diff --git a/pubsub/system-test/subscriptions.test.js b/pubsub/system-test/subscriptions.test.js
index 7f601b2b7c..7f6711221b 100644
--- a/pubsub/system-test/subscriptions.test.js
+++ b/pubsub/system-test/subscriptions.test.js
@@ -39,7 +39,8 @@ describe('pubsub:subscriptions', function () {
         assert.ifError(err);
         assert.equal(subscription.name, name);
         assert(console.log.calledWith('Created subscription %s to topic %s', subscriptionName, topicName));
-        done();
+        // The next test sometimes fails, so, slow this test down
+        setTimeout(done, 2000);
       });
     });
   });
diff --git a/storage/README.md b/storage/README.md
index 5116817041..c957e48a11 100644
--- a/storage/README.md
+++ b/storage/README.md
@@ -33,13 +33,19 @@ View the [documentation][buckets_docs] or the [source code][buckets_code].
 __Usage:__ `node buckets --help`
 
 ```
-Usage: node buckets [COMMAND] [ARGS...]
+Usage: node buckets COMMAND [ARGS...]
 
 Commands:
 
-  create [BUCKET_NAME]
+  create BUCKET_NAME
   list
-  delete [BUCKET_NAME]
+  delete BUCKET_NAME
+
+Examples:
+
+  node buckets create my-bucket
+  node buckets list
+  node buckets delete my-bucket
 ```
 
 [buckets_docs]: https://cloud.google.com/storage/docs
@@ -52,20 +58,60 @@ View the [documentation][files_docs] or the [source code][files_code].
 __Usage:__ `node files --help`
 
 ```
-Usage: node files [COMMAND] [ARGS...]
+Usage: node files COMMAND [ARGS...]
 
 Commands:
 
-  list [BUCKET_NAME]
-  listByPrefix [BUCKET_NAME] [PREFIX] [DELIMITER]
-  upload [BUCKET_NAME] [FILE_NAME]
-  download [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]
-  delete [BUCKET_NAME] [FILE_NAME]
-  getMetadata [BUCKET_NAME] [FILE_NAME]
-  makePublic [BUCKET_NAME] [FILE_NAME]
-  move [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]
-  copy [BUCKET_NAME] [SRC_FILE_NAME] [DEST_BUCKET_NAME] [DEST_FILE_NAME]
+  list BUCKET_NAME
+  listByPrefix BUCKET_NAME PREFIX [DELIMITER]
+  upload BUCKET_NAME FILE_NAME
+  download BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME
+  delete BUCKET_NAME FILE_NAME
+  getMetadata BUCKET_NAME FILE_NAME
+  makePublic BUCKET_NAME FILE_NAME
+  move BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME
+  copy BUCKET_NAME SRC_FILE_NAME DEST_BUCKET_NAME DEST_FILE_NAME
+
+Examples:
+
+  list my-bucket
+  listByPrefix my-bucket /some-folder
+  listByPrefix my-bucket /some-folder -
+  upload my-bucket ./file.txt
+  download my-bucket file.txt ./file.txt
+  delete my-bucket file.txt
+  getMetadata my-bucket file.txt
+  makePublic my-bucket file.txt
+  move my-bucket file.txt file2.txt
+  copy my-bucket file.txt my-other-bucket file.txt
 ```
 
 [files_docs]: https://cloud.google.com/storage/docs
 [files_code]: files.js
+
+### Encryption
+
+View the [documentation][encryption_docs] or the [source code][encryption_code].
+
+__Usage:__ `node encryption --help`
+
+```
+Usage: node encryption COMMAND [ARGS...]
+
+Commands:
+
+  generate-encryption-key
+  upload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY
+  download BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY
+  rotate BUCKET_NAME FILE_NAME OLD_KEY NEW_KEY
+
+Examples:
+
+  node encryption generate-encryption-key
+  node encryption upload my-bucket resources/test.txt file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q=
+  node encryption download my-bucket file_encrypted.txt ./file.txt QxhqaZEqBGVTW55HhQw9Q=
+  node encryption rotate my-bucket file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q= SxafpsdfSDFS89sds9Q=
+```
+
+[encryption_docs]: https://cloud.google.com/storage/docs
+[encryption_code]: encryption.js
diff --git a/storage/buckets.js b/storage/buckets.js
index 4d809e9fae..866e5dfd40 100644
--- a/storage/buckets.js
+++ b/storage/buckets.js
@@ -21,7 +21,7 @@
 // https://googlecloudplatform.github.io/gcloud-node/#/docs/guides/authentication
 var gcloud = require('gcloud');
 
-// Get a reference to the storage component
+// Instantiate a storage client
 var storage = gcloud.storage();
 // [END setup]
 
@@ -93,11 +93,15 @@ function deleteBucket (name, callback) {
 
 // [START usage]
 function printUsage () {
-  console.log('Usage: node buckets [COMMAND] [ARGS...]');
+  console.log('Usage: node buckets COMMAND [ARGS...]');
   console.log('\nCommands:\n');
-  console.log('\tcreate [BUCKET_NAME]');
+  console.log('\tcreate BUCKET_NAME');
   console.log('\tlist');
-  console.log('\tdelete [BUCKET_NAME]');
+  console.log('\tdelete BUCKET_NAME');
+  console.log('\nExamples:\n');
+  console.log('\tnode buckets create my-bucket');
+  console.log('\tnode buckets list');
+  console.log('\tnode buckets delete my-bucket');
 }
 // [END usage]
 
diff --git a/storage/encryption.js b/storage/encryption.js
new file mode 100644
index 0000000000..64ba417fee
--- /dev/null
+++ b/storage/encryption.js
@@ -0,0 +1,193 @@
+// Copyright 2015-2016, Google, Inc.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// [START all]
+// [START setup]
+// By default, gcloud will authenticate using the service account file specified
+// by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use the
+// project specified by the GCLOUD_PROJECT environment variable. See
+// https://googlecloudplatform.github.io/gcloud-node/#/docs/guides/authentication
+var gcloud = require('gcloud');
+
+// Instantiate a storage client
+var storage = gcloud.storage();
+
+var crypto = require('crypto');
+// [END setup]
+
+// [START generate_encryption_key]
+/**
+ * Generates a 256 bit (32 byte) AES encryption key and prints the base64
+ * representation.
+ *
+ * This is included for demonstration purposes. You should generate your own
+ * key. Please remember that encryption keys should be handled with a
+ * comprehensive security policy.
+ *
+ * @returns {string} The encryption key.
+ */
+function generateEncryptionKey () {
+  var buffer = crypto.randomBytes(32);
+  var encodedKey = buffer.toString('base64');
+
+  console.log('Base 64 encoded encryption key: %s', encodedKey);
+
+  return encodedKey;
+}
+// [END generate_encryption_key]
+
+// [START upload_encrypted_file]
+/**
+ * Uploads a file to a Google Cloud Storage bucket using a custom encryption key.
+ *
+ * The file will be encrypted by Google Cloud Storage and only retrievable using
+ * the provided encryption key.
+ *
+ * @param {string} bucketName The bucket where the file will be uploaded.
+ * @param {string} srcFileName The local file to be uploaded.
+ * @param {string} destFileName The name of the destination file.
+ * @param {string} key The encryption key.
+ * @param {function} callback The callback function.
+ */
+function uploadEncryptedFile (bucketName, srcFileName, destFileName, key, callback) {
+  if (!bucketName) {
+    return callback(new Error('"bucketName" is required!'));
+  } else if (!srcFileName) {
+    return callback(new Error('"srcFileName" is required!'));
+  } else if (!destFileName) {
+    return callback(new Error('"destFileName" is required!'));
+  } else if (!key) {
+    return callback(new Error('"key" is required!'));
+  }
+
+  var bucket = storage.bucket(bucketName);
+  var options = {
+    destination: destFileName,
+    encryptionKey: new Buffer(key, 'base64')
+  };
+
+  bucket.upload(srcFileName, options, function (err, file) {
+    if (err) {
+      return callback(err);
+    }
+
+    console.log('Uploaded encrypted file: %s', destFileName);
+    return callback(null, file);
+  });
+}
+// [END upload_encrypted_file]
+
+// [START download_encrypted_file]
+/**
+ * Downloads a previously-encrypted file from Google Cloud Storage.
+ *
+ * The encryption key provided must be the same key provided when uploading the
+ * file.
+ *
+ * @param {string} bucketName The bucket from which the file will be downloaded.
+ * @param {string} srcFileName The name of the file to be downloaded.
+ * @param {string} destFileName The local path to which to save the file.
+ * @param {string} key The encryption key.
+ * @param {function} key The callback function.
+ */
+function downloadEncryptedFile (bucketName, srcFileName, destFileName, key, callback) {
+  if (!bucketName) {
+    return callback(new Error('"bucketName" is required!'));
+  } else if (!srcFileName) {
+    return callback(new Error('"srcFileName" is required!'));
+  } else if (!destFileName) {
+    return callback(new Error('"destFileName" is required!'));
+  } else if (!key) {
+    return callback(new Error('"key" is required!'));
+  }
+
+  var bucket = storage.bucket(bucketName);
+  var file = bucket.file(srcFileName);
+  var options = {
+    destination: destFileName
+  };
+
+  file.setEncryptionKey(new Buffer(key, 'base64'));
+
+  file.download(options, function (err) {
+    if (err) {
+      return callback(err);
+    }
+
+    console.log('Downloaded encrypted file: %s', destFileName);
+    return callback(null);
+  });
+}
+// [END download_encrypted_file]
+
+// [START rotate_encryption_key]
+/**
+ * Performs a key rotation by re-writing an encrypted blob with a new encryption
+ * key.
+ *
+ * @param {function} key The callback function.
+ */
+function rotateEncryptionKey (callback) {
+  callback(new Error('This is currently not available using the Cloud Client Library.'));
+}
+// [END rotate_encryption_key]
+
+// [START usage]
+function printUsage () {
+  console.log('Usage: node encryption COMMAND [ARGS...]');
+  console.log('\nCommands:\n');
+  console.log('\tgenerate-encryption-key');
+  console.log('\tupload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY');
+  console.log('\tdownload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY');
+  console.log('\trotate BUCKET_NAME FILE_NAME OLD_KEY NEW_KEY');
+  console.log('\nExamples:\n');
+  console.log('\tnode encryption generate-encryption-key');
+  console.log('\tnode encryption upload my-bucket resources/test.txt file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q=');
+  console.log('\tnode encryption download my-bucket file_encrypted.txt ./file.txt QxhqaZEqBGVTW55HhQw9Q=');
+  console.log('\tnode encryption rotate my-bucket file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q= SxafpsdfSDFS89sds9Q=');
+}
+// [END usage]
+
+// The command-line program
+var program = {
+  generateEncryptionKey: generateEncryptionKey,
+  uploadEncryptedFile: uploadEncryptedFile,
+  downloadEncryptedFile: downloadEncryptedFile,
+  rotateEncryptionKey: rotateEncryptionKey,
+  printUsage: printUsage,
+
+  // Executed when this program is run from the command-line
+  main: function (args, cb) {
+    var command = args.shift();
+    if (command === 'generate-encryption-key') {
+      this.generateEncryptionKey();
+    } else if (command === 'upload') {
+      this.uploadEncryptedFile(args[0], args[1], args[2], args[3], cb);
+    } else if (command === 'download') {
+      this.downloadEncryptedFile(args[0], args[1], args[2], args[3], cb);
+    } else if (command === 'rotate') {
+      this.rotateEncryptionKey(cb);
+    } else {
+      this.printUsage();
+    }
+  }
+};
+
+if (module === require.main) {
+  program.main(process.argv.slice(2), console.log);
+}
+// [END all]
+
+module.exports = program;
diff --git a/storage/files.js b/storage/files.js
index c248c06eef..7918996222 100644
--- a/storage/files.js
+++ b/storage/files.js
@@ -21,7 +21,7 @@
 // https://googlecloudplatform.github.io/gcloud-node/#/docs/guides/authentication
 var gcloud = require('gcloud');
 
-// Get a reference to the storage component
+// Instantiate a storage client
 var storage = gcloud.storage();
 // [END setup]
 
@@ -324,17 +324,28 @@ function copyFile (name, srcFileName, destBucketName, destFileName, callback) {
 
 // [START usage]
 function printUsage () {
-  console.log('Usage: node files [COMMAND] [ARGS...]');
+  console.log('Usage: node files COMMAND [ARGS...]');
   console.log('\nCommands:\n');
-  console.log('\tlist [BUCKET_NAME]');
-  console.log('\tlistByPrefix [BUCKET_NAME] [PREFIX] [DELIMITER]');
-  console.log('\tupload [BUCKET_NAME] [FILE_NAME]');
-  console.log('\tdownload [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]');
-  console.log('\tdelete [BUCKET_NAME] [FILE_NAME]');
-  console.log('\tgetMetadata [BUCKET_NAME] [FILE_NAME]');
-  console.log('\tmakePublic [BUCKET_NAME] [FILE_NAME]');
-  console.log('\tmove [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]');
-  console.log('\tcopy [BUCKET_NAME] [SRC_FILE_NAME] [DEST_BUCKET_NAME] [DEST_FILE_NAME]');
+  console.log('\tlist BUCKET_NAME');
+  console.log('\tlistByPrefix BUCKET_NAME PREFIX [DELIMITER]');
+  console.log('\tupload BUCKET_NAME FILE_NAME');
+  console.log('\tdownload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME');
+  console.log('\tdelete BUCKET_NAME FILE_NAME');
+  console.log('\tgetMetadata BUCKET_NAME FILE_NAME');
+  console.log('\tmakePublic BUCKET_NAME FILE_NAME');
+  console.log('\tmove BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME');
+  console.log('\tcopy BUCKET_NAME SRC_FILE_NAME DEST_BUCKET_NAME DEST_FILE_NAME');
+  console.log('\nExamples:\n');
+  console.log('\tlist my-bucket');
+  console.log('\tlistByPrefix my-bucket /some-folder');
+  console.log('\tlistByPrefix my-bucket /some-folder -');
+  console.log('\tupload my-bucket ./file.txt');
+  console.log('\tdownload my-bucket file.txt ./file.txt');
+  console.log('\tdelete my-bucket file.txt');
+  console.log('\tgetMetadata my-bucket file.txt');
+  console.log('\tmakePublic my-bucket file.txt');
+  console.log('\tmove my-bucket file.txt file2.txt');
+  console.log('\tcopy my-bucket file.txt my-other-bucket file.txt');
 }
 // [END usage]
 
diff --git a/storage/system-test/encryption.test.js b/storage/system-test/encryption.test.js
new file mode 100644
index 0000000000..33d5dad4b0
--- /dev/null
+++ b/storage/system-test/encryption.test.js
@@ -0,0 +1,79 @@
+// Copyright 2015-2016, Google, Inc.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+var fs = require('fs');
+var path = require('path');
+var gcloud = require('gcloud');
+var uuid = require('node-uuid');
+var storage = gcloud.storage();
+var program = require('../encryption');
+
+var bucketName = 'nodejs-docs-samples-test-' + uuid.v4();
+var fileName = 'test.txt';
+var filePath = path.join(__dirname, '../resources', fileName);
+var downloadFilePath = path.join(__dirname, '../resources/downloaded.txt');
+
+describe('storage:encryption', function () {
+  var key;
+
+  before(function (done) {
+    // Create an encryption key to use throughout the test
+    key = program.generateEncryptionKey();
+    // Create a test bucket
+    storage.createBucket(bucketName, done);
+  });
+
+  after(function (done) {
+    try {
+      // Delete the downloaded file
+      fs.unlinkSync(downloadFilePath);
+    } catch (err) {
+      console.log(err);
+    }
+    // Delete any files that were uploaded
+    storage.bucket(bucketName).deleteFiles({ force: true }, function (err) {
+      if (err) {
+        return done(err);
+      }
+      // Delete the test bucket
+      storage.bucket(bucketName).delete(done);
+    });
+  });
+
+  describe('uploadEncryptedFile', function () {
+    it('should upload a file', function (done) {
+      program.uploadEncryptedFile(bucketName, filePath, fileName, key, function (err, file) {
+        assert.ifError(err);
+        assert(file);
+        assert.equal(file.name, fileName);
+        assert(console.log.calledWith('Uploaded encrypted file: %s', fileName));
+        done();
+      });
+    });
+  });
+
+  describe('downloadEncryptedFile', function () {
+    it('should download a file', function (done) {
+      program.downloadEncryptedFile(bucketName, fileName, downloadFilePath, key, function (err) {
+        assert.ifError(err);
+        assert.doesNotThrow(function () {
+          fs.statSync(downloadFilePath);
+        });
+        assert(console.log.calledWith('Downloaded encrypted file: %s', downloadFilePath));
+        done();
+      });
+    });
+  });
+});
diff --git a/storage/test/buckets.test.js b/storage/test/buckets.test.js
index f80b60fa70..a7116913f1 100644
--- a/storage/test/buckets.test.js
+++ b/storage/test/buckets.test.js
@@ -135,11 +135,15 @@ describe('storage:buckets', function () {
 
       bucketsSample.sample.printUsage();
 
-      assert(console.log.calledWith('Usage: node buckets [COMMAND] [ARGS...]'));
+      assert(console.log.calledWith('Usage: node buckets COMMAND [ARGS...]'));
       assert(console.log.calledWith('\nCommands:\n'));
-      assert(console.log.calledWith('\tcreate [BUCKET_NAME]'));
+      assert(console.log.calledWith('\tcreate BUCKET_NAME'));
       assert(console.log.calledWith('\tlist'));
-      assert(console.log.calledWith('\tdelete [BUCKET_NAME]'));
+      assert(console.log.calledWith('\tdelete BUCKET_NAME'));
+      assert(console.log.calledWith('\nExamples:\n'));
+      assert(console.log.calledWith('\tnode buckets create my-bucket'));
+      assert(console.log.calledWith('\tnode buckets list'));
+      assert(console.log.calledWith('\tnode buckets delete my-bucket'));
     });
   });
   describe('main', function () {
diff --git a/storage/test/encryption.test.js b/storage/test/encryption.test.js
new file mode 100644
index 0000000000..6834082014
--- /dev/null
+++ b/storage/test/encryption.test.js
@@ -0,0 +1,240 @@
+// Copyright 2016, Google, Inc.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+var proxyquire = require('proxyquire').noCallThru();
+var bucketName = 'foo';
+
+function getSample () {
+  var filesMock = [
+    {
+      id: 'foo',
+      name: 'foo'
+    }
+  ];
+  var fileMock = {
+    download: sinon.stub().callsArgWith(1, null),
+    setEncryptionKey: sinon.stub()
+  };
+  var bucketMock = {
+    upload: sinon.stub().callsArgWith(2, null, filesMock[0]),
+    file: sinon.stub().returns(fileMock)
+  };
+  var storageMock = {
+    bucket: sinon.stub().returns(bucketMock)
+  };
+  var gcloudMock = {
+    storage: sinon.stub().returns(storageMock)
+  };
+  return {
+    program: proxyquire('../encryption', {
+      gcloud: gcloudMock
+    }),
+    mocks: {
+      gcloud: gcloudMock,
+      storage: storageMock,
+      files: filesMock,
+      bucket: bucketMock,
+      file: fileMock
+    }
+  };
+}
+
+describe('storage:encryption', function () {
+  describe('generateEncryptionKey', function () {
+    it('should generate an encryption key', function () {
+      var program = getSample().program;
+
+      var key = program.generateEncryptionKey();
+      assert(console.log.calledWith('Base 64 encoded encryption key: %s', key));
+    });
+  });
+
+  describe('uploadEncryptedFile', function () {
+    var fileName = 'test.txt';
+    it('should upload a file', function () {
+      var sample = getSample();
+
+      sample.program.uploadEncryptedFile(bucketName, fileName, fileName, 'key', function (err, file) {
+        assert.ifError(err);
+        assert.strictEqual(file, sample.mocks.files[0]);
+        assert(console.log.calledWith('Uploaded encrypted file: %s', fileName));
+      });
+    });
+    it('should require bucket', function () {
+      var sample = getSample();
+
+      sample.program.uploadEncryptedFile(undefined, undefined, undefined, undefined, function (err, file) {
+        assert(err);
+        assert(err.message = '"bucket" is required!');
+        assert.equal(file, undefined);
+      });
+    });
+    it('should require srcFileName', function () {
+      var sample = getSample();
+
+      sample.program.uploadEncryptedFile(bucketName, undefined, undefined, undefined, function (err, file) {
+        assert(err);
+        assert(err.message = '"srcFileName" is required!');
+        assert.equal(file, undefined);
+      });
+    });
+    it('should require destFileName', function () {
+      var sample = getSample();
+
+      sample.program.uploadEncryptedFile(bucketName, fileName, undefined, undefined, function (err, file) {
+        assert(err);
+        assert(err.message = '"destFileName" is required!');
+        assert.equal(file, undefined);
+      });
+    });
+    it('should require key', function () {
+      var sample = getSample();
+
+      sample.program.uploadEncryptedFile(bucketName, fileName, fileName, undefined, function (err, file) {
+        assert(err);
+        assert(err.message = '"key" is required!');
+        assert.equal(file, undefined);
+      });
+    });
+    it('should handle error', function () {
+      var error = 'error';
+      var sample = getSample();
+      sample.mocks.bucket.upload = sinon.stub().callsArgWith(2, new Error(error));
+
+      sample.program.uploadEncryptedFile(bucketName, fileName, fileName, 'key', function (err, file) {
+        assert(err);
+        assert.equal(err.message, error);
+        assert.equal(file, undefined);
+      });
+    });
+  });
+
+  describe('downloadEncryptedFile', function () {
+    var fileName = 'test.txt';
+    it('should download a file', function () {
+      var sample = getSample();
+
+      sample.program.downloadEncryptedFile(bucketName, fileName, fileName, 'key', function (err) {
+        assert.ifError(err);
+        assert(console.log.calledWith('Downloaded encrypted file: %s', fileName));
+      });
+    });
+    it('should require bucket', function () {
+      var sample = getSample();
+
+      sample.program.downloadEncryptedFile(undefined, undefined, undefined, undefined, function (err, file) {
+        assert(err);
+        assert(err.message = '"bucket" is required!');
+        assert.equal(file, undefined);
+      });
+    });
+    it('should require srcFileName', function () {
+      var sample = getSample();
+
+      sample.program.downloadEncryptedFile(bucketName, undefined, undefined, undefined, function (err, file) {
+        assert(err);
+        assert(err.message = '"srcFileName" is required!');
+        assert.equal(file, undefined);
+      });
+    });
+    it('should require destFileName', function () {
+      var sample = getSample();
+
+      sample.program.downloadEncryptedFile(bucketName, fileName, undefined, undefined, function (err, file) {
+        assert(err);
+        assert(err.message = '"destFileName" is required!');
+        assert.equal(file, undefined);
+      });
+    });
+    it('should require key', function () {
+      var sample = getSample();
+
+      sample.program.downloadEncryptedFile(bucketName, fileName, fileName, undefined, function (err, file) {
+        assert(err);
+        assert(err.message = '"key" is required!');
+        assert.equal(file, undefined);
+      });
+    });
+    it('should handle error', function () {
+      var error = 'error';
+      var sample = getSample();
+      sample.mocks.file.download = sinon.stub().callsArgWith(1, new Error(error));
+
+      sample.program.downloadEncryptedFile(bucketName, fileName, fileName, 'key', function (err, file) {
+        assert(err);
+        assert.equal(err.message, error);
+        assert.equal(file, undefined);
+      });
+    });
+  });
+
+  describe('rotateEncryptionKey', function () {
+    it('should be implemented');
+    it('should rotate an encryption key', function () {
+      var sample = getSample();
+
+      sample.program.rotateEncryptionKey(function (err) {
+        assert(err);
+        assert.equal(err.message, 'This is currently not available using the Cloud Client Library.');
+      });
+    });
+  });
+
+  describe('printUsage', function () {
+    it('should print usage', function () {
+      var program = getSample().program;
+
+      program.printUsage();
+
+      assert(console.log.calledWith('Usage: node encryption COMMAND [ARGS...]'));
+      assert(console.log.calledWith('\nCommands:\n'));
+      assert(console.log.calledWith('\tgenerate-encryption-key'));
+      assert(console.log.calledWith('\tupload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY'));
+      assert(console.log.calledWith('\tdownload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY'));
+      assert(console.log.calledWith('\trotate BUCKET_NAME FILE_NAME OLD_KEY NEW_KEY'));
+      assert(console.log.calledWith('\nExamples:\n'));
+      assert(console.log.calledWith('\tnode encryption generate-encryption-key'));
+      assert(console.log.calledWith('\tnode encryption upload my-bucket resources/test.txt file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q='));
+      assert(console.log.calledWith('\tnode encryption download my-bucket file_encrypted.txt ./file.txt QxhqaZEqBGVTW55HhQw9Q='));
+      assert(console.log.calledWith('\tnode encryption rotate my-bucket file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q= SxafpsdfSDFS89sds9Q='));
+    });
+  });
+
+  describe('main', function () {
+    it('should call the right commands', function () {
+      var program = getSample().program;
+
+      sinon.stub(program, 'generateEncryptionKey');
+      program.main(['generate-encryption-key']);
+      assert(program.generateEncryptionKey.calledOnce);
+
+      sinon.stub(program, 'uploadEncryptedFile');
+      program.main(['upload']);
+      assert(program.uploadEncryptedFile.calledOnce);
+
+      sinon.stub(program, 'downloadEncryptedFile');
+      program.main(['download']);
+      assert(program.downloadEncryptedFile.calledOnce);
+
+      sinon.stub(program, 'rotateEncryptionKey');
+      program.main(['rotate']);
+      assert(program.rotateEncryptionKey.calledOnce);
+
+      sinon.stub(program, 'printUsage');
+      program.main(['--help']);
+      assert(program.printUsage.calledOnce);
+    });
+  });
+});
diff --git a/storage/test/files.test.js b/storage/test/files.test.js
index ba21df7125..8e2b5fcd9c 100644
--- a/storage/test/files.test.js
+++ b/storage/test/files.test.js
@@ -421,17 +421,17 @@ describe('storage:files', function () {
 
       filesSample.sample.printUsage();
 
-      assert(console.log.calledWith('Usage: node files [COMMAND] [ARGS...]'));
+      assert(console.log.calledWith('Usage: node files COMMAND [ARGS...]'));
       assert(console.log.calledWith('\nCommands:\n'));
-      assert(console.log.calledWith('\tlist [BUCKET_NAME]'));
-      assert(console.log.calledWith('\tlistByPrefix [BUCKET_NAME] [PREFIX] [DELIMITER]'));
-      assert(console.log.calledWith('\tupload [BUCKET_NAME] [FILE_NAME]'));
-      assert(console.log.calledWith('\tdownload [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]'));
-      assert(console.log.calledWith('\tdelete [BUCKET_NAME] [FILE_NAME]'));
-      assert(console.log.calledWith('\tgetMetadata [BUCKET_NAME] [FILE_NAME]'));
-      assert(console.log.calledWith('\tmakePublic [BUCKET_NAME] [FILE_NAME]'));
-      assert(console.log.calledWith('\tmove [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]'));
-      assert(console.log.calledWith('\tcopy [BUCKET_NAME] [SRC_FILE_NAME] [DEST_BUCKET_NAME] [DEST_FILE_NAME]'));
+      assert(console.log.calledWith('\tlist BUCKET_NAME'));
+      assert(console.log.calledWith('\tlistByPrefix BUCKET_NAME PREFIX [DELIMITER]'));
+      assert(console.log.calledWith('\tupload BUCKET_NAME FILE_NAME'));
+      assert(console.log.calledWith('\tdownload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME'));
+      assert(console.log.calledWith('\tdelete BUCKET_NAME FILE_NAME'));
+      assert(console.log.calledWith('\tgetMetadata BUCKET_NAME FILE_NAME'));
+      assert(console.log.calledWith('\tmakePublic BUCKET_NAME FILE_NAME'));
+      assert(console.log.calledWith('\tmove BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME'));
+      assert(console.log.calledWith('\tcopy BUCKET_NAME SRC_FILE_NAME DEST_BUCKET_NAME DEST_FILE_NAME'));
     });
   });
   describe('main', function () {