diff --git a/src/cleartext.js b/src/cleartext.js
index 36bf6f6b..a794319a 100644
--- a/src/cleartext.js
+++ b/src/cleartext.js
@@ -155,8 +155,7 @@ export function readArmored(armoredText) {
   packetlist.read(input.data);
   verifyHeaders(input.headers, packetlist);
   const signature = new Signature(packetlist);
-  const newMessage = new CleartextMessage(input.text, signature);
-  return newMessage;
+  return new CleartextMessage(input.text, signature);
 }
 
 /**
diff --git a/src/key.js b/src/key.js
index 4b045d33..a54e61ed 100644
--- a/src/key.js
+++ b/src/key.js
@@ -529,9 +529,10 @@ Key.prototype.getPrimaryUser = function(date=new Date()) {
  * Update key with new components from specified key with same key ID:
  * users, subkeys, certificates are merged into the destination key,
  * duplicates and expired signatures are ignored.
+ *
  * If the specified key is a private key and the destination key is public,
  * the destination key is transformed to a private key.
- * @param  {module:key~Key} key source key to merge
+ * @param  {module:key~Key} key Source key to merge
  */
 Key.prototype.update = async function(key) {
   const that = this;
@@ -903,8 +904,9 @@ User.prototype.verify = async function(primaryKey) {
 
 /**
  * Update user with new components from specified user
- * @param  {module:key~User} user source user to merge
- * @param  {module:packet/signature} primaryKey primary key used for validation
+ * @param  {module:key~User}             user       Source user to merge
+ * @param  {module:packet/secret_key|
+            module:packet/secret_subkey} primaryKey primary key used for validation
  */
 User.prototype.update = async function(user, primaryKey) {
   const dataToVerify = { userid: this.userId || this.userAttribute, key: primaryKey };
@@ -1037,8 +1039,9 @@ SubKey.prototype.getExpirationTime = function() {
 
 /**
  * Update subkey with new components from specified subkey
- * @param  {module:key~SubKey} subKey source subkey to merge
- * @param  {module:packet/signature} primaryKey primary key used for validation
+ * @param  {module:key~SubKey}           subKey     Source subkey to merge
+ * @param  {module:packet/secret_key|
+            module:packet/secret_subkey} primaryKey primary key used for validation
  */
 SubKey.prototype.update = async function(subKey, primaryKey) {
   if (await subKey.verify(primaryKey) === enums.keyStatus.invalid) {
@@ -1226,7 +1229,12 @@ export async function reformat(options) {
     throw new Error('Only RSA Encrypt or Sign supported');
   }
 
-  if (!options.privateKey.decrypt()) {
+  try {
+    const isDecrypted = options.privateKey.getKeyPackets().every(keyPacket => keyPacket.isDecrypted);
+    if (!isDecrypted) {
+      await options.privateKey.decrypt();
+    }
+  } catch (err) {
     throw new Error('Key not decrypted');
   }
 
diff --git a/src/keyring/keyring.js b/src/keyring/keyring.js
index 32d09738..4bf39e4e 100644
--- a/src/keyring/keyring.js
+++ b/src/keyring/keyring.js
@@ -161,7 +161,7 @@ KeyArray.prototype.getForId = function (keyId, deep) {
     if (keyIdCheck(keyId, this.keys[i].primaryKey)) {
       return this.keys[i];
     }
-    if (deep && this.keys[i].subKeys) {
+    if (deep && this.keys[i].subKeys.length) {
       for (let j = 0; j < this.keys[i].subKeys.length; j++) {
         if (keyIdCheck(keyId, this.keys[i].subKeys[j].subKey)) {
           return this.keys[i];
diff --git a/src/message.js b/src/message.js
index af6344b0..6293859f 100644
--- a/src/message.js
+++ b/src/message.js
@@ -138,7 +138,8 @@ Message.prototype.decrypt = async function(privateKeys, passwords, sessionKeys)
  * Decrypt encrypted session keys either with private keys or passwords.
  * @param  {Array<Key>} privateKeys    (optional) private keys with decrypted secret data
  * @param  {Array<String>} passwords   (optional) passwords used to decrypt
- * @returns {Promise{Array<{ data:Uint8Array, algorithm:String }>}} array of object with potential sessionKey, algorithm pairs
+ * @returns {Promise<Array<{ data:      Uint8Array,
+                             algorithm: String }>>} array of object with potential sessionKey, algorithm pairs
  */
 Message.prototype.decryptSessionKeys = async function(privateKeys, passwords) {
   let keyPackets = [];
@@ -162,6 +163,7 @@ Message.prototype.decryptSessionKeys = async function(privateKeys, passwords) {
       throw new Error('No public key encrypted session key packet found.');
     }
     await Promise.all(pkESKeyPacketlist.map(async function(keyPacket) {
+      // TODO improve this
       const privateKeyPackets = privateKeys.reduce(function(acc, privateKey) {
         return acc.concat(privateKey.getKeyPackets(keyPacket.publicKeyId));
       }, new packet.List());
@@ -534,11 +536,12 @@ Message.prototype.verifyDetached = function(signature, keys, date=new Date()) {
 
 /**
  * Create list of objects containing signer's keyid and validity of signature
- * @param {Array<module:packet/signature>} signatureList array of signature packets
- * @param {Array<module:packet/literal>} literalDataList array of literal data packets
- * @param {Array<module:key~Key>} keys array of keys to verify signatures
+ * @param {Array<module:packet/signature>} signatureList   array of signature packets
+ * @param {Array<module:packet/literal>}   literalDataList array of literal data packets
+ * @param {Array<module:key~Key>}          keys            array of keys to verify signatures
  * @param {Date} date Verify the signature against the given date, i.e. check signature creation time < date < expiration time
- * @returns {Promise{Array<({keyid: module:type/keyid, valid: Boolean})>}} list of signer's keyid and validity of signature
+ * @returns {Promise<Array<{keyid: module:type/keyid,
+                            valid: Boolean}>>} list of signer's keyid and validity of signature
  */
 export async function createVerificationObjects(signatureList, literalDataList, keys, date=new Date()) {
   return Promise.all(signatureList.map(async function(signature) {
diff --git a/src/openpgp.js b/src/openpgp.js
index 4f73229a..201b4d64 100644
--- a/src/openpgp.js
+++ b/src/openpgp.js
@@ -371,8 +371,10 @@ export function verify({ message, publicKeys, signature=null, date=new Date() })
 
   return Promise.resolve().then(async function() {
     const result = {};
-    result.data = CleartextMessage.prototype.isPrototypeOf(message) ? message.getText() : message.getLiteralData();
-    result.signatures = signature ? await message.verifyDetached(signature, publicKeys, date) : await message.verify(publicKeys, date);
+    result.data = message instanceof CleartextMessage ? message.getText() : message.getLiteralData();
+    result.signatures = signature ?
+      await message.verifyDetached(signature, publicKeys, date) :
+      await message.verify(publicKeys, date);
     return result;
   }).catch(onError.bind(null, 'Error verifying cleartext signed message'));
 }
@@ -462,12 +464,12 @@ function checkData(data, name) {
   }
 }
 function checkMessage(message) {
-  if (!messageLib.Message.prototype.isPrototypeOf(message)) {
+  if (!(message instanceof messageLib.Message)) {
     throw new Error('Parameter [message] needs to be of type Message');
   }
 }
 function checkCleartextOrMessage(message) {
-  if (!CleartextMessage.prototype.isPrototypeOf(message) && !messageLib.Message.prototype.isPrototypeOf(message)) {
+  if (!(message instanceof CleartextMessage) && !(message instanceof messageLib.Message)) {
     throw new Error('Parameter [message] needs to be of type Message or CleartextMessage');
   }
 }
diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js
index 13fd624d..f23343fe 100644
--- a/src/packet/secret_key.js
+++ b/src/packet/secret_key.js
@@ -216,7 +216,7 @@ function produceEncryptionKey(s2k, passphrase, algorithm) {
  */
 SecretKey.prototype.decrypt = async function (passphrase) {
   if (this.isDecrypted) {
-    return true;
+    throw new Error('Key packet is already decrypted.');
   }
 
   let i = 0;
diff --git a/src/packet/sym_encrypted_session_key.js b/src/packet/sym_encrypted_session_key.js
index 3884f072..6433b0ab 100644
--- a/src/packet/sym_encrypted_session_key.js
+++ b/src/packet/sym_encrypted_session_key.js
@@ -104,7 +104,7 @@ SymEncryptedSessionKey.prototype.write = function() {
 /**
  * Decrypts the session key
  * @param {String} passphrase The passphrase in string form
- * @return {Promise<Boolean}
+ * @return {Promise<Boolean>}
  */
 SymEncryptedSessionKey.prototype.decrypt = async function(passphrase) {
   const algo = this.sessionKeyEncryptionAlgorithm !== null ?
@@ -128,7 +128,7 @@ SymEncryptedSessionKey.prototype.decrypt = async function(passphrase) {
 /**
  * Encrypts the session key
  * @param {String} passphrase The passphrase in string form
- * @return {Promise<Boolean}
+ * @return {Promise<Boolean>}
  */
 SymEncryptedSessionKey.prototype.encrypt = async function(passphrase) {
   const algo = this.sessionKeyEncryptionAlgorithm !== null ?
diff --git a/src/type/keyid.js b/src/type/keyid.js
index c741bd51..16fd3324 100644
--- a/src/type/keyid.js
+++ b/src/type/keyid.js
@@ -53,6 +53,7 @@ Keyid.prototype.toHex = function() {
 };
 
 Keyid.prototype.equals = function(keyid) {
+  // Note: checks if keyid is a wildcard, but doesn't check "this".
   return keyid.isWildcard() || this.bytes === keyid.bytes;
 };
 
diff --git a/test/general/ecc_nist.js b/test/general/ecc_nist.js
index f88708d8..264e07cd 100644
--- a/test/general/ecc_nist.js
+++ b/test/general/ecc_nist.js
@@ -202,7 +202,6 @@ describe('Elliptic Curve Cryptography', function () {
   it('Encrypt and sign message', async function () {
     const romeoPrivate = await load_priv_key('romeo');
     const julietPublic = load_pub_key('juliet');
-    expect(await romeoPrivate.decrypt(data.romeo.pass)).to.be.true;
     const encrypted = await openpgp.encrypt({publicKeys: [julietPublic], privateKeys: [romeoPrivate], data: data.romeo.message + "\n"});
 
     const message = openpgp.message.readArmored(encrypted.data);
diff --git a/test/general/key.js b/test/general/key.js
index a241e64f..dff1d7ed 100644
--- a/test/general/key.js
+++ b/test/general/key.js
@@ -769,7 +769,7 @@ describe('Key', function() {
 
     const pubKey = pubKeys.keys[0];
     // remove subkeys
-    pubKey.subKeys = null;
+    pubKey.subKeys = [];
     // primary key has only key flags for signing
     const keyPacket = pubKey.getEncryptionKeyPacket();
     expect(keyPacket).to.not.exist;
@@ -798,13 +798,13 @@ describe('Key', function() {
     )()).to.be.rejectedWith('Key update method: fingerprints of keys not equal').notify(done);
   });
 
-  it('update() - merge revocation signature', function(done) {
+  it('update() - merge revocation signatures', function(done) {
     const source = openpgp.key.readArmored(pub_revoked).keys[0];
     const dest = openpgp.key.readArmored(pub_revoked).keys[0];
-    expect(source.revocationSignature).to.exist;
-    dest.revocationSignature = null;
+    expect(source.revocationSignatures).to.exist;
+    dest.revocationSignatures = [];
     dest.update(source).then(() => {
-      expect(dest.revocationSignature).to.exist.and.be.an.instanceof(openpgp.packet.Signature);
+      expect(dest.revocationSignatures[0]).to.exist.and.be.an.instanceof(openpgp.packet.Signature);
       done();
     });
   });
@@ -821,18 +821,18 @@ describe('Key', function() {
     });
   });
 
-  it('update() - merge user - other and revocation certification', function(done) {
+  it('update() - merge user - other and certification revocation signatures', function(done) {
     const source = openpgp.key.readArmored(pub_sig_test).keys[0];
     const dest = openpgp.key.readArmored(pub_sig_test).keys[0];
     expect(source.users[1].otherCertifications).to.exist;
-    expect(source.users[1].revocationCertifications).to.exist;
-    dest.users[1].otherCertifications = null;
-    dest.users[1].revocationCertifications.pop();
+    expect(source.users[1].revocationSignatures).to.exist;
+    dest.users[1].otherCertifications = [];
+    dest.users[1].revocationSignatures.pop();
     dest.update(source).then(() => {
       expect(dest.users[1].otherCertifications).to.exist.and.to.have.length(1);
       expect(dest.users[1].otherCertifications[0].signature).to.equal(source.users[1].otherCertifications[0].signature);
-      expect(dest.users[1].revocationCertifications).to.exist.and.to.have.length(2);
-      expect(dest.users[1].revocationCertifications[1].signature).to.equal(source.users[1].revocationCertifications[1].signature);
+      expect(dest.users[1].revocationSignatures).to.exist.and.to.have.length(2);
+      expect(dest.users[1].revocationSignatures[1].signature).to.equal(source.users[1].revocationSignatures[1].signature);
       done();
     });
   });
@@ -851,15 +851,14 @@ describe('Key', function() {
     });
   });
 
-  it('update() - merge subkey - revocation signature', function(done) {
+  it('update() - merge subkey - revocation signature', function() {
     const source = openpgp.key.readArmored(pub_sig_test).keys[0];
     const dest = openpgp.key.readArmored(pub_sig_test).keys[0];
-    expect(source.subKeys[0].revocationSignature).to.exist;
-    dest.subKeys[0].revocationSignature = null;
-    dest.update(source).then(() => {
-      expect(dest.subKeys[0].revocationSignature).to.exist;
-      expect(dest.subKeys[0].revocationSignature.signature).to.equal(dest.subKeys[0].revocationSignature.signature);
-      done();
+    expect(source.subKeys[0].revocationSignatures).to.exist;
+    dest.subKeys[0].revocationSignatures = [];
+    return dest.update(source).then(() => {
+      expect(dest.subKeys[0].revocationSignatures).to.exist;
+      expect(dest.subKeys[0].revocationSignatures[0].signature).to.equal(dest.subKeys[0].revocationSignatures[0].signature);
     });
   });
 
@@ -886,8 +885,8 @@ describe('Key', function() {
   it('update() - merge private key into public key - no subkeys', function() {
     const source = openpgp.key.readArmored(priv_key_rsa).keys[0];
     const dest = openpgp.key.readArmored(twoKeys).keys[0];
-    source.subKeys = null;
-    dest.subKeys = null;
+    source.subKeys = [];
+    dest.subKeys = [];
     expect(dest.isPublic()).to.be.true;
     return dest.update(source).then(() => {
       expect(dest.isPrivate()).to.be.true;
@@ -905,7 +904,7 @@ describe('Key', function() {
   it('update() - merge private key into public key - mismatch throws error', function(done) {
     const source = openpgp.key.readArmored(priv_key_rsa).keys[0];
     const dest = openpgp.key.readArmored(twoKeys).keys[0];
-    source.subKeys = null;
+    source.subKeys = [];
     expect(dest.subKeys).to.exist;
     expect(dest.isPublic()).to.be.true;
     expect(dest.update.bind(dest, source)())
diff --git a/test/general/packet.js b/test/general/packet.js
index c5fe98d4..1c07bd76 100644
--- a/test/general/packet.js
+++ b/test/general/packet.js
@@ -141,7 +141,7 @@ describe("Packet", function() {
     });
   });
 
-  it('Sym encrypted session key with a compressed packet', function(done) {
+  it('Sym encrypted session key with a compressed packet', async function() {
     const msg =
         '-----BEGIN PGP MESSAGE-----\n' +
         'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
@@ -156,16 +156,16 @@ describe("Packet", function() {
     const parsed = new openpgp.packet.List();
     parsed.read(msgbytes);
 
-    parsed[0].decrypt('test');
+    return parsed[0].decrypt('test').then(() => {
+      const key = parsed[0].sessionKey;
+      return parsed[1].decrypt(parsed[0].sessionKeyAlgorithm, key).then(() => {
+        const compressed = parsed[1].packets[0];
 
-    const key = parsed[0].sessionKey;
-    parsed[1].decrypt(parsed[0].sessionKeyAlgorithm, key);
-    const compressed = parsed[1].packets[0];
+        const result = stringify(compressed.packets[0].data);
 
-    const result = stringify(compressed.packets[0].data);
-
-    expect(result).to.equal('Hello world!\n');
-    done();
+        expect(result).to.equal('Hello world!\n');
+      });
+    });
   });
 
   it('Public key encrypted symmetric key packet', function() {
@@ -187,13 +187,13 @@ describe("Packet", function() {
       enc.publicKeyAlgorithm = 'rsa_encrypt';
       enc.sessionKeyAlgorithm = 'aes256';
       enc.publicKeyId.bytes = '12345678';
-      enc.encrypt({ params: mpi }).then(() => {
+      return enc.encrypt({ params: mpi }).then(() => {
 
         msg.push(enc);
 
         msg2.read(msg.write());
 
-        msg2[0].decrypt({ params: mpi }).then(() => {
+        return msg2[0].decrypt({ params: mpi }).then(() => {
 
           expect(stringify(msg2[0].sessionKey)).to.equal(stringify(enc.sessionKey));
           expect(msg2[0].sessionKeyAlgorithm).to.equal(enc.sessionKeyAlgorithm);
@@ -299,8 +299,8 @@ describe("Packet", function() {
     const msg = new openpgp.packet.List();
     msg.read(openpgp.armor.decode(armored_msg).data);
 
-    return msg[0].decrypt(key).then(() => {
-      return msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
+    return msg[0].decrypt(key).then(async () => {
+      await msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
 
       const text = stringify(msg[1].packets[0].packets[0].data);
 
@@ -339,7 +339,7 @@ describe("Packet", function() {
     expect(stringify(msg2[1].packets[0].data)).to.equal(stringify(literal.data));
   });
 
-  it('Secret key encryption/decryption test', function() {
+  it('Secret key encryption/decryption test', async function() {
     const armored_msg =
         '-----BEGIN PGP MESSAGE-----\n' +
         'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
@@ -355,13 +355,13 @@ describe("Packet", function() {
     let key = new openpgp.packet.List();
     key.read(openpgp.armor.decode(armored_key).data);
     key = key[3];
-    key.decrypt('test');
+    await key.decrypt('test');
 
     const msg = new openpgp.packet.List();
     msg.read(openpgp.armor.decode(armored_msg).data);
 
-    return msg[0].decrypt(key).then(() => {
-      return msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
+    return msg[0].decrypt(key).then(async () => {
+      await msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
 
       const text = stringify(msg[1].packets[0].packets[0].data);
 
@@ -386,7 +386,7 @@ describe("Packet", function() {
     ]);
   });
 
-  it('Reading a signed, encrypted message.', function(done) {
+  it('Reading a signed, encrypted message.', async function() {
     const armored_msg =
         '-----BEGIN PGP MESSAGE-----\n' +
         'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
@@ -405,19 +405,19 @@ describe("Packet", function() {
 
     const key = new openpgp.packet.List();
     key.read(openpgp.armor.decode(armored_key).data);
-    key[3].decrypt('test');
+    await key[3].decrypt('test');
 
     const msg = new openpgp.packet.List();
     msg.read(openpgp.armor.decode(armored_msg).data);
 
-    msg[0].decrypt(key[3]).then(() => {
-      msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
+    return msg[0].decrypt(key[3]).then(async () => {
+      await msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
 
       const payload = msg[1].packets[0].packets;
 
       expect(payload[2].verify(
         key[0], payload[1]
-      )).to.eventually.be.true.notify(done);
+      )).to.eventually.be.true;
     });
   });
 
@@ -428,7 +428,7 @@ describe("Packet", function() {
     const rsa = openpgp.crypto.publicKey.rsa;
     const keySize = openpgp.util.getWebCryptoAll() ? 2048 : 512; // webkit webcrypto accepts minimum 2048 bit keys
 
-    return rsa.generate(keySize, "10001").then(function(mpiGen) {
+    return rsa.generate(keySize, "10001").then(async function(mpiGen) {
       let mpi = [mpiGen.n, mpiGen.e, mpiGen.d, mpiGen.p, mpiGen.q, mpiGen.u];
       mpi = mpi.map(function(k) {
         return new openpgp.MPI(k);
@@ -436,13 +436,13 @@ describe("Packet", function() {
 
       key[0].params = mpi;
       key[0].algorithm = "rsa_sign";
-      key[0].encrypt('hello');
+      await key[0].encrypt('hello');
 
       const raw = key.write();
 
       const key2 = new openpgp.packet.List();
       key2.read(raw);
-      key2[0].decrypt('hello');
+      await key2[0].decrypt('hello');
 
       expect(key[0].params.toString()).to.equal(key2[0].params.toString());
     });
diff --git a/test/general/signature.js b/test/general/signature.js
index 166cae47..0728e126 100644
--- a/test/general/signature.js
+++ b/test/general/signature.js
@@ -688,16 +688,18 @@ describe("Signature", function() {
 
   });
 
-  it('Verify primary key revocation signature', function(done) {
+  // TODO add test with multiple revocation signatures
+  it('Verify primary key revocation signatures', function(done) {
     const pubKey = openpgp.key.readArmored(pub_revoked).keys[0];
-    expect(pubKey.revocationSignature.verify(
+    expect(pubKey.revocationSignatures[0].verify(
       pubKey.primaryKey, {key: pubKey.primaryKey}
     )).to.eventually.be.true.notify(done);
   });
 
-  it('Verify subkey revocation signature', function(done) {
+  // TODO add test with multiple revocation signatures
+  it('Verify subkey revocation signatures', function(done) {
     const pubKey = openpgp.key.readArmored(pub_revoked).keys[0];
-    expect(pubKey.subKeys[0].revocationSignature.verify(
+    expect(pubKey.subKeys[0].revocationSignatures[0].verify(
       pubKey.primaryKey, {key: pubKey.primaryKey, bind: pubKey.subKeys[0].subKey}
     )).to.eventually.be.true.notify(done);
   });
diff --git a/test/general/x25519.js b/test/general/x25519.js
index b7849304..1f1e62ae 100644
--- a/test/general/x25519.js
+++ b/test/general/x25519.js
@@ -184,7 +184,6 @@ describe('X25519 Cryptography', function () {
   it('Decrypt and verify message', async function () {
     const light = load_pub_key('light');
     const night = await load_priv_key('night');
-    expect(await night.decrypt(data.night.pass)).to.be.true;
     const msg = openpgp.message.readArmored(data.night.message_encrypted);
     const result = await openpgp.decrypt({ privateKeys: night, publicKeys: [light], message: msg });
 
@@ -198,7 +197,6 @@ describe('X25519 Cryptography', function () {
   it('Encrypt and sign message', async function () {
     const nightPublic = load_pub_key('night');
     const lightPrivate = await load_priv_key('light');
-    expect(await lightPrivate.decrypt(data.light.pass)).to.be.true;
     const encrypted = await openpgp.encrypt({ publicKeys: [nightPublic], privateKeys: [lightPrivate], data: data.light.message + "\n" });
 
     const message = openpgp.message.readArmored(encrypted.data);