diff --git a/.mocharc.yml b/.mocharc.yml
index 83fda38..1b4a955 100644
--- a/.mocharc.yml
+++ b/.mocharc.yml
@@ -1,6 +1,6 @@
 recursive: true
 reporter: "spec"
-retries: 1
+retries: 0
 slow: 20
 timeout: 2000
 ui: "bdd"
diff --git a/lib/grant-types/abstract-grant-type.js b/lib/grant-types/abstract-grant-type.js
index 4f73e55..c6daedf 100644
--- a/lib/grant-types/abstract-grant-type.js
+++ b/lib/grant-types/abstract-grant-type.js
@@ -1,20 +1,12 @@
 'use strict';
 
-/**
- * Module dependencies.
- */
-
 const InvalidArgumentError = require('../errors/invalid-argument-error');
-const InvalidScopeError = require('../errors/invalid-scope-error');
-const Promise = require('bluebird');
-const promisify = require('promisify-any').use(Promise);
 const is = require('../validator/is');
 const tokenUtil = require('../utils/token-util');
 
 /**
  * Constructor.
  */
-
 function AbstractGrantType(options) {
   options = options || {};
 
@@ -35,37 +27,56 @@ function AbstractGrantType(options) {
 /**
  * Generate access token.
  */
+AbstractGrantType.prototype.generateAccessToken = async function(client, user, scope) {
+
+  let accessToken;
+
+  if (
+    this.model &&
+    this.model.generateAccessToken &&
+    typeof this.model.generateAccessToken === 'function'
+  ) {
+
+    try {
+      accessToken = await this.model.generateAccessToken
+        .call(this.model, client, user, scope);
+    } catch (err) {
+      return Promise.reject(err);
+    }
 
-AbstractGrantType.prototype.generateAccessToken = function(client, user, scope) {
-  if (this.model.generateAccessToken) {
-    return promisify(this.model.generateAccessToken, 3).call(this.model, client, user, scope)
-      .then(function(accessToken) {
-        return accessToken || tokenUtil.generateRandomToken();
-      });
   }
 
-  return tokenUtil.generateRandomToken();
+  return Promise.resolve( accessToken || tokenUtil.generateRandomToken() );
 };
 
 /**
  * Generate refresh token.
  */
+AbstractGrantType.prototype.generateRefreshToken = async function(client, user, scope) {
+
+  let refreshToken;
+
+  if (
+    this.model &&
+    this.model.generateRefreshToken &&
+    typeof this.model.generateRefreshToken === 'function'
+  ) {
+
+    try {
+      refreshToken = await this.model.generateRefreshToken
+        .call(this.model, client, user, scope); 
+    } catch (err) {
+      return Promise.reject(err);
+    }
 
-AbstractGrantType.prototype.generateRefreshToken = function(client, user, scope) {
-  if (this.model.generateRefreshToken) {
-    return promisify(this.model.generateRefreshToken, 3).call(this.model, client, user, scope)
-      .then(function(refreshToken) {
-        return refreshToken || tokenUtil.generateRandomToken();
-      });
   }
 
-  return tokenUtil.generateRandomToken();
+  return Promise.resolve( refreshToken || tokenUtil.generateRandomToken() );
 };
 
 /**
  * Get access token expiration date.
  */
-
 AbstractGrantType.prototype.getAccessTokenExpiresAt = function() {
   return new Date(Date.now() + this.accessTokenLifetime * 1000);
 };
@@ -73,7 +84,6 @@ AbstractGrantType.prototype.getAccessTokenExpiresAt = function() {
 /**
  * Get refresh token expiration date.
  */
-
 AbstractGrantType.prototype.getRefreshTokenExpiresAt = function() {
   return new Date(Date.now() + this.refreshTokenLifetime * 1000);
 };
@@ -81,9 +91,9 @@ AbstractGrantType.prototype.getRefreshTokenExpiresAt = function() {
 /**
  * Get scope from the request body.
  */
-
 AbstractGrantType.prototype.getScope = function(request) {
-  if (!is.nqschar(request.body.scope)) {
+
+  if (!request || !request.body || !is.nqschar(request.body.scope)) {
     throw new InvalidArgumentError('Invalid parameter: `scope`');
   }
 
@@ -93,23 +103,35 @@ AbstractGrantType.prototype.getScope = function(request) {
 /**
  * Validate requested scope.
  */
-AbstractGrantType.prototype.validateScope = function(user, client, scope) {
-  if (this.model.validateScope) {
-    return promisify(this.model.validateScope, 3).call(this.model, user, client, scope)
-      .then(function (scope) {
-        if (!scope) {
-          throw new InvalidScopeError('Invalid scope: Requested scope is invalid');
-        }
-
-        return scope;
-      });
-  } else {
-    return scope;
+AbstractGrantType.prototype.validateScope = async function(user, client, scope) {
+
+  // scope is valid by default
+  let isValidScope = true;
+
+  if (
+    this.model &&
+    this.model.validateScope &&
+    typeof this.model.validateScope === 'function'
+  ) {
+
+    try {
+      isValidScope = await this.model.validateScope
+        .call(this.model, user, client, scope);
+    } catch (err) {
+      return Promise.reject(err);
+    }
+    
   }
-};
 
-/**
- * Export constructor.
- */
+  // This should never return an error, only true or false.
+  // if (!isValidScope) {
+  //   Promise.reject( 
+  //     new InvalidScopeError('Invalid scope: Requested scope is invalid')
+  //   );
+  // }
+
+  return Promise.resolve(isValidScope);
+
+};
 
 module.exports = AbstractGrantType;
diff --git a/lib/grant-types/authorization-code-grant-type.js b/lib/grant-types/authorization-code-grant-type.js
index 8f21aef..9f9471c 100644
--- a/lib/grant-types/authorization-code-grant-type.js
+++ b/lib/grant-types/authorization-code-grant-type.js
@@ -8,11 +8,9 @@ const AbstractGrantType = require('./abstract-grant-type');
 const InvalidArgumentError = require('../errors/invalid-argument-error');
 const InvalidGrantError = require('../errors/invalid-grant-error');
 const InvalidRequestError = require('../errors/invalid-request-error');
-const Promise = require('bluebird');
-const promisify = require('promisify-any').use(Promise);
 const ServerError = require('../errors/server-error');
 const is = require('../validator/is');
-const util = require('util');
+const {inherits} = require('util');
 
 /**
  * Constructor.
@@ -44,43 +42,58 @@ function AuthorizationCodeGrantType(options) {
  * Inherit prototype.
  */
 
-util.inherits(AuthorizationCodeGrantType, AbstractGrantType);
+inherits(AuthorizationCodeGrantType, AbstractGrantType);
 
 /**
  * Handle authorization code grant.
  *
  * @see https://tools.ietf.org/html/rfc6749#section-4.1.3
  */
-
-AuthorizationCodeGrantType.prototype.handle = function(request, client) {
+AuthorizationCodeGrantType.prototype.handle = async function(request, client) {
+  
   if (!request) {
-    throw new InvalidArgumentError('Missing parameter: `request`');
+    return Promise.reject(
+      new InvalidArgumentError('Missing parameter: `request`')
+    );
   }
 
   if (!client) {
-    throw new InvalidArgumentError('Missing parameter: `client`');
-  }
-
-  return Promise.bind(this)
-    .then(function() {
-      return this.getAuthorizationCode(request, client);
-    })
-    .tap(function(code) {
-      return this.validateRedirectUri(request, code);
-    })
-    .tap(function(code) {
-      return this.revokeAuthorizationCode(code);
-    })
-    .then(function(code) {
-      return this.saveToken(code.user, client, code.authorizationCode, code.scope);
-    });
+    return Promise.reject(
+      new InvalidArgumentError('Missing parameter: `client`')
+    );
+  }
+
+  let code;
+
+  try {
+    code = await this.getAuthorizationCode(request, client);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  try {
+    await this.validateRedirectUri(request, code);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  try {
+    await this.revokeAuthorizationCode(code);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+
+  return this.saveToken(code.user, client, code.authorizationCode, code.scope);
+
 };
 
 /**
  * Get the authorization code.
  */
 
-AuthorizationCodeGrantType.prototype.getAuthorizationCode = function(request, client) {
+AuthorizationCodeGrantType.prototype.getAuthorizationCode = async function(request, client) {
+
   if (!request.body.code) {
     throw new InvalidRequestError('Missing parameter: `code`');
   }
@@ -88,38 +101,61 @@ AuthorizationCodeGrantType.prototype.getAuthorizationCode = function(request, cl
   if (!is.vschar(request.body.code)) {
     throw new InvalidRequestError('Invalid parameter: `code`');
   }
-  return promisify(this.model.getAuthorizationCode, 1).call(this.model, request.body.code)
-    .then(function(code) {
-      if (!code) {
-        throw new InvalidGrantError('Invalid grant: authorization code is invalid');
-      }
+  let code;
 
-      if (!code.client) {
-        throw new ServerError('Server error: `getAuthorizationCode()` did not return a `client` object');
-      }
+  try {
+    code = await this.model.getAuthorizationCode.call(this.model, request.body.code);
+  } catch (err) {
+    return Promise.reject(err);
+  }
 
-      if (!code.user) {
-        throw new ServerError('Server error: `getAuthorizationCode()` did not return a `user` object');
-      }
+  // console.log(code);
 
-      if (code.client.id !== client.id) {
-        throw new InvalidGrantError('Invalid grant: authorization code is invalid');
-      }
+  
+  if (!code) {
+    return Promise.reject(
+      new InvalidGrantError('Invalid grant: authorization code is invalid') 
+    );
+  }
 
-      if (!(code.expiresAt instanceof Date)) {
-        throw new ServerError('Server error: `expiresAt` must be a Date instance');
-      }
+  if (!code.client) {
+    return Promise.reject(
+      new ServerError('Server error: `getAuthorizationCode()` did not return a `client` object') 
+    );
+  }
 
-      if (code.expiresAt < new Date()) {
-        throw new InvalidGrantError('Invalid grant: authorization code has expired');
-      }
+  if (!code.user) {
+    return Promise.reject(
+      new ServerError('Server error: `getAuthorizationCode()` did not return a `user` object') 
+    );
+  }
 
-      if (code.redirectUri && !is.uri(code.redirectUri)) {
-        throw new InvalidGrantError('Invalid grant: `redirect_uri` is not a valid URI');
-      }
+  if (code.client.id !== client.id) {
+    return Promise.reject(
+      new InvalidGrantError('Invalid grant: authorization code is invalid') 
+    );
+  }
+
+  if (!(code.expiresAt instanceof Date)) {
+    return Promise.reject(
+      new ServerError('Server error: `expiresAt` must be a Date instance') 
+    );
+  }
+
+  if (code.expiresAt < new Date()) {
+    return Promise.reject(
+      new InvalidGrantError('Invalid grant: authorization code has expired') 
+    );
+  }
+
+  if (code.redirectUri && !is.uri(code.redirectUri)) {
+    return Promise.reject(
+      new InvalidGrantError('Invalid grant: `redirect_uri` is not a valid URI') 
+    );
+  }
+
+  return Promise.resolve(code);
 
-      return code;
-    });
 };
 
 /**
@@ -134,6 +170,7 @@ AuthorizationCodeGrantType.prototype.getAuthorizationCode = function(request, cl
  */
 
 AuthorizationCodeGrantType.prototype.validateRedirectUri = function(request, code) {
+
   if (!code.redirectUri) {
     return;
   }
@@ -147,6 +184,7 @@ AuthorizationCodeGrantType.prototype.validateRedirectUri = function(request, cod
   if (redirectUri !== code.redirectUri) {
     throw new InvalidRequestError('Invalid request: `redirect_uri` is invalid');
   }
+
 };
 
 /**
@@ -159,15 +197,24 @@ AuthorizationCodeGrantType.prototype.validateRedirectUri = function(request, cod
  * @see https://tools.ietf.org/html/rfc6749#section-4.1.2
  */
 
-AuthorizationCodeGrantType.prototype.revokeAuthorizationCode = function(code) {
-  return promisify(this.model.revokeAuthorizationCode, 1).call(this.model, code)
-    .then(function(status) {
-      if (!status) {
-        throw new InvalidGrantError('Invalid grant: authorization code is invalid');
-      }
+AuthorizationCodeGrantType.prototype.revokeAuthorizationCode = async function(code) {
+
+  let status;
+
+  try {
+    status = await this.model.revokeAuthorizationCode.call(this.model, code);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  if (!status) {
+    return Promise.reject(
+      new InvalidGrantError('Invalid grant: authorization code is invalid')
+    );
+  }
+
+  return Promise.resolve(code);
 
-      return code;
-    });
 };
 
 /**
@@ -175,6 +222,7 @@ AuthorizationCodeGrantType.prototype.revokeAuthorizationCode = function(code) {
  */
 
 AuthorizationCodeGrantType.prototype.saveToken = function(user, client, authorizationCode, scope) {
+
   const fns = [
     this.validateScope(user, client, scope),
     this.generateAccessToken(client, user, scope),
@@ -184,18 +232,24 @@ AuthorizationCodeGrantType.prototype.saveToken = function(user, client, authoriz
   ];
 
   return Promise.all(fns)
-    .bind(this)
-    .spread(function(scope, accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt) {
+    .then( (result) => {
+
+      if (!result || result.length < 5) {
+        return Promise.reject(
+          new Error('Unexpected problem saving Authorization Code Grant Type token')
+        );
+      }
+
       const token = {
-        accessToken: accessToken,
+        accessToken: result[1],
         authorizationCode: authorizationCode,
-        accessTokenExpiresAt: accessTokenExpiresAt,
-        refreshToken: refreshToken,
-        refreshTokenExpiresAt: refreshTokenExpiresAt,
-        scope: scope
+        accessTokenExpiresAt: result[3],
+        refreshToken: result[2],
+        refreshTokenExpiresAt: result[4],
+        scope: result[0],
       };
 
-      return promisify(this.model.saveToken, 3).call(this.model, token, client, user);
+      return this.model.saveToken.call(this.model, token, client, user);
     });
 };
 
diff --git a/lib/grant-types/client-credentials-grant-type.js b/lib/grant-types/client-credentials-grant-type.js
index d0af0fe..34efd56 100644
--- a/lib/grant-types/client-credentials-grant-type.js
+++ b/lib/grant-types/client-credentials-grant-type.js
@@ -7,8 +7,7 @@
 const AbstractGrantType = require('./abstract-grant-type');
 const InvalidArgumentError = require('../errors/invalid-argument-error');
 const InvalidGrantError = require('../errors/invalid-grant-error');
-const Promise = require('bluebird');
-const promisify = require('promisify-any').use(Promise);
+const ServerError = require('../errors/server-error');
 const util = require('util');
 
 /**
@@ -45,7 +44,8 @@ util.inherits(ClientCredentialsGrantType, AbstractGrantType);
  * @see https://tools.ietf.org/html/rfc6749#section-4.4.2
  */
 
-ClientCredentialsGrantType.prototype.handle = function(request, client) {
+ClientCredentialsGrantType.prototype.handle = async function(request, client) {
+
   if (!request) {
     throw new InvalidArgumentError('Missing parameter: `request`');
   }
@@ -56,52 +56,76 @@ ClientCredentialsGrantType.prototype.handle = function(request, client) {
 
   const scope = this.getScope(request);
 
-  return Promise.bind(this)
-    .then(function() {
-      return this.getUserFromClient(client);
-    })
-    .then(function(user) {
-      return this.saveToken(user, client, scope);
-    });
+  let user;
+  try {
+    user = await this.getUserFromClient.call(this, client);   
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  return this.saveToken.call(this, user, client, scope);
+
 };
 
 /**
  * Retrieve the user using client credentials.
  */
 
-ClientCredentialsGrantType.prototype.getUserFromClient = function(client) {
-  return promisify(this.model.getUserFromClient, 1).call(this.model, client)
-    .then(function(user) {
-      if (!user) {
-        throw new InvalidGrantError('Invalid grant: user credentials are invalid');
-      }
+ClientCredentialsGrantType.prototype.getUserFromClient = async function(client) {
+
+  let user;
+
+  try {
+    user = await this.model.getUserFromClient.call(this.model, client);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  if (!user) {
+    return Promise.reject( 
+      new InvalidGrantError('Invalid grant: user credentials are invalid')
+    );
+  }
+
+  return user;
 
-      return user;
-    });
 };
 
 /**
  * Save token.
  */
 
-ClientCredentialsGrantType.prototype.saveToken = function(user, client, scope) {
+ClientCredentialsGrantType.prototype.saveToken = async function(user, client, scope) {
+
   const fns = [
-    this.validateScope(user, client, scope),
-    this.generateAccessToken(client, user, scope),
-    this.getAccessTokenExpiresAt(client, user, scope)
+    this.validateScope.call( this, user, client, scope),
+    this.generateAccessToken.call( this, client, user, scope),
+    this.getAccessTokenExpiresAt.call( this, client, user, scope)
   ];
 
-  return Promise.all(fns)
-    .bind(this)
-    .spread(function(scope, accessToken, accessTokenExpiresAt) {
-      const token = {
-        accessToken: accessToken,
-        accessTokenExpiresAt: accessTokenExpiresAt,
-        scope: scope
-      };
-
-      return promisify(this.model.saveToken, 3).call(this.model, token, client, user);
-    });
+  let res;
+
+  try {
+    res = await Promise.all(fns);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  if (!res || res.length !== 3) {
+    // REVIEW: confirm this is the correct error
+    return Promise.reject( 
+      new ServerError('Server error: failed to save token')
+    );
+  }
+
+  const token = {
+    scope: res[0],
+    accessToken: res[1],
+    accessTokenExpiresAt: res[2],
+  };
+
+  return this.model.saveToken.call(this.model, token, client, user);
+
 };
 
 /**
diff --git a/lib/grant-types/password-grant-type.js b/lib/grant-types/password-grant-type.js
index 70a7c1b..0b3d0f7 100644
--- a/lib/grant-types/password-grant-type.js
+++ b/lib/grant-types/password-grant-type.js
@@ -8,8 +8,7 @@ const AbstractGrantType = require('./abstract-grant-type');
 const InvalidArgumentError = require('../errors/invalid-argument-error');
 const InvalidGrantError = require('../errors/invalid-grant-error');
 const InvalidRequestError = require('../errors/invalid-request-error');
-const Promise = require('bluebird');
-const promisify = require('promisify-any').use(Promise);
+const ServerError = require('../errors/server-error');
 const is = require('../validator/is');
 const util = require('util');
 
@@ -47,7 +46,8 @@ util.inherits(PasswordGrantType, AbstractGrantType);
  * @see https://tools.ietf.org/html/rfc6749#section-4.3.2
  */
 
-PasswordGrantType.prototype.handle = function(request, client) {
+PasswordGrantType.prototype.handle = async function(request, client) {
+
   if (!request) {
     throw new InvalidArgumentError('Missing parameter: `request`');
   }
@@ -58,72 +58,111 @@ PasswordGrantType.prototype.handle = function(request, client) {
 
   const scope = this.getScope(request);
 
-  return Promise.bind(this)
-    .then(function() {
-      return this.getUser(request);
-    })
-    .then(function(user) {
-      return this.saveToken(user, client, scope);
-    });
+  let user;
+
+  try {
+    user = await this.getUser.call(this, request);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  return this.saveToken.call(this, user, client, scope);
+
+//   return Promise.bind(this)
+//     .then(function() {
+//       return this.getUser(request);
+//     })
+//     .then(function(user) {
+//       return this.saveToken(user, client, scope);
+//     });
 };
 
 /**
  * Get user using a username/password combination.
  */
 
-PasswordGrantType.prototype.getUser = function(request) {
+PasswordGrantType.prototype.getUser = async function(request) {
   if (!request.body.username) {
-    throw new InvalidRequestError('Missing parameter: `username`');
+    return Promise.reject(
+      new InvalidRequestError('Missing parameter: `username`')
+    );
   }
 
   if (!request.body.password) {
-    throw new InvalidRequestError('Missing parameter: `password`');
+    return Promise.reject(
+      new InvalidRequestError('Missing parameter: `password`')
+    );
   }
 
   if (!is.uchar(request.body.username)) {
-    throw new InvalidRequestError('Invalid parameter: `username`');
+    return Promise.reject(
+      new InvalidRequestError('Invalid parameter: `username`')
+    );
   }
 
   if (!is.uchar(request.body.password)) {
-    throw new InvalidRequestError('Invalid parameter: `password`');
+    return Promise.reject(
+      new InvalidRequestError('Invalid parameter: `password`')
+    );
   }
 
-  return promisify(this.model.getUser, 2).call(this.model, request.body.username, request.body.password)
-    .then(function(user) {
-      if (!user) {
-        throw new InvalidGrantError('Invalid grant: user credentials are invalid');
-      }
+  let user;
+
+  try {
+    user = await this.model.getUser
+      .call(this.model, request.body.username, request.body.password);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  if (!user) {
+    return Promise.reject(
+      new InvalidGrantError('Invalid grant: user credentials are invalid')
+    );
+  }
 
-      return user;
-    });
+  return Promise.resolve(user);
 };
 
 /**
  * Save token.
  */
 
-PasswordGrantType.prototype.saveToken = function(user, client, scope) {
+PasswordGrantType.prototype.saveToken = async function(user, client, scope) {
+
   const fns = [
-    this.validateScope(user, client, scope),
-    this.generateAccessToken(client, user, scope),
-    this.generateRefreshToken(client, user, scope),
-    this.getAccessTokenExpiresAt(),
-    this.getRefreshTokenExpiresAt()
+    this.validateScope.call(this, user, client, scope),
+    this.generateAccessToken.call(this, client, user, scope),
+    this.generateRefreshToken.call(this, client, user, scope),
+    this.getAccessTokenExpiresAt.call(this),
+    this.getRefreshTokenExpiresAt.call(this)
   ];
 
-  return Promise.all(fns)
-    .bind(this)
-    .spread(function(scope, accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt) {
-      const token = {
-        accessToken: accessToken,
-        accessTokenExpiresAt: accessTokenExpiresAt,
-        refreshToken: refreshToken,
-        refreshTokenExpiresAt: refreshTokenExpiresAt,
-        scope: scope
-      };
-
-      return promisify(this.model.saveToken, 3).call(this.model, token, client, user);
-    });
+  let res;
+
+  try {
+    res = await Promise.all(fns);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  if (!res || res.length !== 5) {
+    // REVIEW: confirm this is the correct error
+    return Promise.reject( 
+      new ServerError('Server error: faild to save token')
+    );
+  }
+
+  const token = {
+    scope: res[0],
+    accessToken: res[1],
+    refreshToken: res[2],
+    accessTokenExpiresAt: res[3],
+    refreshTokenExpiresAt: res[4],
+  };
+
+  return this.model.saveToken.call(this.model, token, client, user);
+
 };
 
 /**
diff --git a/lib/grant-types/refresh-token-grant-type.js b/lib/grant-types/refresh-token-grant-type.js
index 3eac92b..2c54005 100644
--- a/lib/grant-types/refresh-token-grant-type.js
+++ b/lib/grant-types/refresh-token-grant-type.js
@@ -8,8 +8,7 @@ const AbstractGrantType = require('./abstract-grant-type');
 const InvalidArgumentError = require('../errors/invalid-argument-error');
 const InvalidGrantError = require('../errors/invalid-grant-error');
 const InvalidRequestError = require('../errors/invalid-request-error');
-const Promise = require('bluebird');
-const promisify = require('promisify-any').use(Promise);
+const InvalidClientError = require('../errors/invalid-client-error');
 const ServerError = require('../errors/server-error');
 const is = require('../validator/is');
 const util = require('util');
@@ -52,68 +51,91 @@ util.inherits(RefreshTokenGrantType, AbstractGrantType);
  * @see https://tools.ietf.org/html/rfc6749#section-6
  */
 
-RefreshTokenGrantType.prototype.handle = function(request, client) {
+RefreshTokenGrantType.prototype.handle = async function(request, client) {
+
   if (!request) {
-    throw new InvalidArgumentError('Missing parameter: `request`');
+    return Promise.reject( 
+      new InvalidArgumentError('Missing parameter: `request`') 
+    );
   }
 
   if (!client) {
-    throw new InvalidArgumentError('Missing parameter: `client`');
-  }
-
-  return Promise.bind(this)
-    .then(function() {
-      return this.getRefreshToken(request, client);
-    })
-    .tap(function(token) {
-      return this.revokeToken(token);
-    })
-    .then(function(token) {
-      return this.saveToken(token.user, client, token.scope);
-    });
+    return Promise.reject( 
+      new InvalidArgumentError('Missing parameter: `client`') 
+    );
+  }
+
+  let token;
+
+  try {
+    token = await this.getRefreshToken.call(this, request, client);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  try {
+    await this.revokeToken.call(this, token);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  return this.saveToken.call(this, token.user, client, token.scope);
+
 };
 
 /**
  * Get refresh token.
  */
 
-RefreshTokenGrantType.prototype.getRefreshToken = function(request, client) {
+RefreshTokenGrantType.prototype.getRefreshToken = async function(request, client) {
+
   if (!request.body.refresh_token) {
-    throw new InvalidRequestError('Missing parameter: `refresh_token`');
+    return Promise.reject(
+      new InvalidRequestError('Missing parameter: `refresh_token`')
+    );
   }
 
   if (!is.vschar(request.body.refresh_token)) {
-    throw new InvalidRequestError('Invalid parameter: `refresh_token`');
+    return Promise.reject(
+      new InvalidRequestError('Invalid parameter: `refresh_token`')
+    );
   }
 
-  return promisify(this.model.getRefreshToken, 1).call(this.model, request.body.refresh_token)
-    .then(function(token) {
-      if (!token) {
-        throw new InvalidGrantError('Invalid grant: refresh token is invalid');
-      }
+  let token;
+
+  try {
+    token = await this.model.getRefreshToken
+      .call(this.model, request.body.refresh_token);
+  } catch (err) {
+    return Promise.reject(err);
+  }
 
-      if (!token.client) {
-        throw new ServerError('Server error: `getRefreshToken()` did not return a `client` object');
-      }
+  if (!token) {
+    throw new InvalidGrantError('Invalid grant: refresh token is invalid');
+  }
 
-      if (!token.user) {
-        throw new ServerError('Server error: `getRefreshToken()` did not return a `user` object');
-      }
+  if (!token.client) {
+    throw new ServerError('Server error: `getRefreshToken()` did not return a `client` object');
+  }
 
-      if (token.client.id !== client.id) {
-        throw new InvalidGrantError('Invalid grant: refresh token is invalid');
-      }
+  if (!token.user) {
+    throw new ServerError('Server error: `getRefreshToken()` did not return a `user` object');
+  }
 
-      if (token.refreshTokenExpiresAt && !(token.refreshTokenExpiresAt instanceof Date)) {
-        throw new ServerError('Server error: `refreshTokenExpiresAt` must be a Date instance');
-      }
+  if (token.client.id !== client.id) {
+    throw new InvalidGrantError('Invalid grant: refresh token is invalid');
+  }
 
-      if (token.refreshTokenExpiresAt && token.refreshTokenExpiresAt < new Date()) {
-        throw new InvalidGrantError('Invalid grant: refresh token has expired');
-      }
+  if (token.refreshTokenExpiresAt && !(token.refreshTokenExpiresAt instanceof Date)) {
+    throw new ServerError('Server error: `refreshTokenExpiresAt` must be a Date instance');
+  }
+
+  if (token.refreshTokenExpiresAt && token.refreshTokenExpiresAt < new Date()) {
+    throw new InvalidGrantError('Invalid grant: refresh token has expired');
+  }
+  
+  return Promise.resolve(token);
 
-      return token;
-    });
 };
 
 /**
@@ -121,56 +143,69 @@ RefreshTokenGrantType.prototype.getRefreshToken = function(request, client) {
  *
  * @see https://tools.ietf.org/html/rfc6749#section-6
  */
+RefreshTokenGrantType.prototype.revokeToken = async function(token) {
 
-RefreshTokenGrantType.prototype.revokeToken = function(token) {
   if (this.alwaysIssueNewRefreshToken === false) {
     return Promise.resolve(token);
   }
 
-  return promisify(this.model.revokeToken, 1).call(this.model, token)
-    .then(function(status) {
-      if (!status) {
-        throw new InvalidGrantError('Invalid grant: refresh token is invalid');
-      }
+  let status;
+
+  try {
+    status = this.model.revokeToken.call(this.model, token);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  if (!status) {
+    return Promise.reject(
+      new InvalidGrantError('Invalid grant: refresh token is invalid')
+    );
+  }
+
+  return token;
 
-      return token;
-    });
 };
 
 /**
  * Save token.
  */
+RefreshTokenGrantType.prototype.saveToken = async function(user, client, scope) {
 
-RefreshTokenGrantType.prototype.saveToken = function(user, client, scope) {
   const fns = [
-    this.generateAccessToken(client, user, scope),
-    this.generateRefreshToken(client, user, scope),
-    this.getAccessTokenExpiresAt(),
-    this.getRefreshTokenExpiresAt()
+    this.generateAccessToken.call(this,client, user, scope),
+    this.generateRefreshToken.call(this,client, user, scope),
+    this.getAccessTokenExpiresAt.call(this),
+    this.getRefreshTokenExpiresAt.call(this),
   ];
 
-  return Promise.all(fns)
-    .bind(this)
-    .spread(function(accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt) {
-      const token = {
-        accessToken: accessToken,
-        accessTokenExpiresAt: accessTokenExpiresAt,
-        scope: scope
-      };
-
-      if (this.alwaysIssueNewRefreshToken !== false) {
-        token.refreshToken = refreshToken;
-        token.refreshTokenExpiresAt = refreshTokenExpiresAt;
-      }
-
-      return token;
-    })
-    .then(function(token) {
-      return promisify(this.model.saveToken, 3).call(this.model, token, client, user)
-        .then(function(savedToken) {
-          return savedToken;
-        });
-    });
+  let res;
+
+  try {
+    res = await Promise.all(fns);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  if (!res || res.length !== 4) {
+    return Promise.reject( 
+      new InvalidClientError('Invalid client: client credentials are invalid')
+    );
+  }
+
+  const token = {
+    accessToken: res[0],
+    accessTokenExpiresAt: res[2],
+    scope: scope
+  };
+
+  if (this.alwaysIssueNewRefreshToken !== false) {
+    token.refreshToken = res[1];
+    token.refreshTokenExpiresAt = res[3];
+  }
+
+  return this.model.saveToken.call(this.model, token, client, user);
+
 };
 
 /**
diff --git a/lib/handlers/authenticate-handler.js b/lib/handlers/authenticate-handler.js
index b02b123..04a95ef 100644
--- a/lib/handlers/authenticate-handler.js
+++ b/lib/handlers/authenticate-handler.js
@@ -9,8 +9,6 @@ const InvalidRequestError = require('../errors/invalid-request-error');
 const InsufficientScopeError = require('../errors/insufficient-scope-error');
 const InvalidTokenError = require('../errors/invalid-token-error');
 const OAuthError = require('../errors/oauth-error');
-const Promise = require('bluebird');
-const promisify = require('promisify-any').use(Promise);
 const Request = require('../request');
 const Response = require('../response');
 const ServerError = require('../errors/server-error');
@@ -53,8 +51,8 @@ function AuthenticateHandler(options) {
 /**
  * Authenticate Handler.
  */
+AuthenticateHandler.prototype.handle = async function(request, response) {
 
-AuthenticateHandler.prototype.handle = function(request, response) {
   if (!(request instanceof Request)) {
     throw new InvalidArgumentError('Invalid argument: `request` must be an instance of Request');
   }
@@ -63,41 +61,60 @@ AuthenticateHandler.prototype.handle = function(request, response) {
     throw new InvalidArgumentError('Invalid argument: `response` must be an instance of Response');
   }
 
-  return Promise.bind(this)
-    .then(function() {
-      return this.getTokenFromRequest(request);
-    })
-    .then(function(token) {
-      return this.getAccessToken(token);
-    })
-    .tap(function(token) {
-      return this.validateAccessToken(token);
-    })
-    .tap(function(token) {
-      if (!this.scope) {
-        return;
-      }
-
-      return this.verifyScope(token);
-    })
-    .tap(function(token) {
-      return this.updateResponse(response, token);
-    })
-    .catch(function(e) {
-      // Include the "WWW-Authenticate" response header field if the client
-      // lacks any authentication information.
-      //
-      // @see https://tools.ietf.org/html/rfc6750#section-3.1
-      if (e instanceof UnauthorizedRequestError) {
-        response.set('WWW-Authenticate', 'Bearer realm="Service"');
-      }
-
-      if (!(e instanceof OAuthError)) {
-        throw new ServerError(e);
-      }
-
-      throw e;
-    });
+  function errorHandler (err) {
+    // Include the "WWW-Authenticate" response header field if the client
+    // lacks any authentication information.
+    //
+    // @see https://tools.ietf.org/html/rfc6750#section-3.1
+    if (err instanceof UnauthorizedRequestError) {
+      response.set('WWW-Authenticate', 'Bearer realm="Service"');
+    }
+
+    if (!(err instanceof OAuthError)) {
+      return Promise.reject( new ServerError(err) );
+    }
+
+    return Promise.reject( err );
+
+  }
+
+  let requestToken,
+    accessToken;
+
+  try {
+    requestToken = await this.getTokenFromRequest.call(this, request);
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  try {
+    accessToken = await this.getAccessToken.call(this, requestToken);
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  try {
+    await this.validateAccessToken.call(this, accessToken);
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  if (this.scope) {
+    try {
+      await this.verifyScope.call(this, accessToken);
+    } catch (err) {
+      return errorHandler(err);
+    }
+  }
+
+  try {
+    await this.updateResponse.call(this, response, accessToken);
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  return Promise.resolve(accessToken);
+
 };
 
 /**
@@ -107,14 +124,16 @@ AuthenticateHandler.prototype.handle = function(request, response) {
  *
  * @see https://tools.ietf.org/html/rfc6750#section-2
  */
-
 AuthenticateHandler.prototype.getTokenFromRequest = function(request) {
+  
   const headerToken = request.get('Authorization');
   const queryToken = request.query.access_token;
   const bodyToken = request.body.access_token;
 
   if (!!headerToken + !!queryToken + !!bodyToken > 1) {
-    throw new InvalidRequestError('Invalid request: only one authentication method is allowed');
+    return Promise.reject(
+      new InvalidRequestError('Invalid request: only one authentication method is allowed')
+    );
   }
 
   if (headerToken) {
@@ -129,7 +148,10 @@ AuthenticateHandler.prototype.getTokenFromRequest = function(request) {
     return this.getTokenFromRequestBody(request);
   }
 
-  throw new UnauthorizedRequestError('Unauthorized request: no authentication given');
+  return Promise.reject(
+    new UnauthorizedRequestError('Unauthorized request: no authentication given')
+  );
+
 };
 
 /**
@@ -196,19 +218,26 @@ AuthenticateHandler.prototype.getTokenFromRequestBody = function(request) {
  * Get the access token from the model.
  */
 
-AuthenticateHandler.prototype.getAccessToken = function(token) {
-  return promisify(this.model.getAccessToken, 1).call(this.model, token)
-    .then(function(accessToken) {
-      if (!accessToken) {
-        throw new InvalidTokenError('Invalid token: access token is invalid');
-      }
+AuthenticateHandler.prototype.getAccessToken = async function(token) {
+
+  let accessToken;
 
-      if (!accessToken.user) {
-        throw new ServerError('Server error: `getAccessToken()` did not return a `user` object');
-      }
+  try {
+    accessToken = await this.model.getAccessToken.call(this.model, token);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  if (!accessToken) {
+    throw new InvalidTokenError('Invalid token: access token is invalid');
+  }
+
+  if (!accessToken.user) {
+    throw new ServerError('Server error: `getAccessToken()` did not return a `user` object');
+  }
+
+  return accessToken;
 
-      return accessToken;
-    });
 };
 
 /**
@@ -216,6 +245,7 @@ AuthenticateHandler.prototype.getAccessToken = function(token) {
  */
 
 AuthenticateHandler.prototype.validateAccessToken = function(accessToken) {
+
   if (!(accessToken.accessTokenExpiresAt instanceof Date)) {
     throw new ServerError('Server error: `accessTokenExpiresAt` must be a Date instance');
   }
@@ -225,21 +255,31 @@ AuthenticateHandler.prototype.validateAccessToken = function(accessToken) {
   }
 
   return accessToken;
+
 };
 
 /**
  * Verify scope.
  */
 
-AuthenticateHandler.prototype.verifyScope = function(accessToken) {
-  return promisify(this.model.verifyScope, 2).call(this.model, accessToken, this.scope)
-    .then(function(scope) {
-      if (!scope) {
-        throw new InsufficientScopeError('Insufficient scope: authorized scope is insufficient');
-      }
+AuthenticateHandler.prototype.verifyScope = async function(accessToken) {
+
+  let scope;
+
+  try {
+    scope = await this.model.verifyScope.call(this.model, accessToken, this.scope);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  if (!scope) {
+    return Promise.reject(
+      new InsufficientScopeError('Insufficient scope: authorized scope is insufficient')
+    );
+  }
+
+  return Promise.resolve(scope);
 
-      return scope;
-    });
 };
 
 /**
diff --git a/lib/handlers/authorize-handler.js b/lib/handlers/authorize-handler.js
index 5e06ded..c2f1a23 100644
--- a/lib/handlers/authorize-handler.js
+++ b/lib/handlers/authorize-handler.js
@@ -12,8 +12,6 @@ const InvalidRequestError = require('../errors/invalid-request-error');
 const InvalidScopeError = require('../errors/invalid-scope-error');
 const UnsupportedResponseTypeError = require('../errors/unsupported-response-type-error');
 const OAuthError = require('../errors/oauth-error');
-const Promise = require('bluebird');
-const promisify = require('promisify-any').use(Promise);
 const Request = require('../request');
 const Response = require('../response');
 const ServerError = require('../errors/server-error');
@@ -68,17 +66,24 @@ function AuthorizeHandler(options) {
  * Authorize Handler.
  */
 
-AuthorizeHandler.prototype.handle = function(request, response) {
+AuthorizeHandler.prototype.handle = async function(request, response) {
+
   if (!(request instanceof Request)) {
-    throw new InvalidArgumentError('Invalid argument: `request` must be an instance of Request');
+    return Promise.reject(
+      new InvalidArgumentError('Invalid argument: `request` must be an instance of Request')
+    );
   }
 
   if (!(response instanceof Response)) {
-    throw new InvalidArgumentError('Invalid argument: `response` must be an instance of Response');
+    return Promise.reject(
+      new InvalidArgumentError('Invalid argument: `response` must be an instance of Response')
+    );
   }
 
   if ('false' === request.query.allowed) {
-    return Promise.reject(new AccessDeniedError('Access denied: user denied access to application'));
+    return Promise.reject(
+      new AccessDeniedError('Access denied: user denied access to application')
+    );
   }
 
   const fns = [
@@ -87,55 +92,103 @@ AuthorizeHandler.prototype.handle = function(request, response) {
     this.getUser(request, response)
   ];
 
-  return Promise.all(fns)
-    .bind(this)
-    .spread(function(expiresAt, client, user) {
-      const uri = this.getRedirectUri(request, client);
-      let scope;
-      let state;
-      let ResponseType;
-
-      return Promise.bind(this)
-        .then(function() {
-          state = this.getState(request);
-          if(request.query.allowed === 'false') {
-            throw new AccessDeniedError('Access denied: user denied access to application');
-          }
-        })
-        .then(function() {
-          const requestedScope = this.getScope(request);
-
-          return this.validateScope(user, client, requestedScope);
-        })
-        .then(function(validScope) {
-          scope = validScope;
-
-          return this.generateAuthorizationCode(client, user, scope);
-        })
-        .then(function(authorizationCode) {
-          ResponseType = this.getResponseType(request);
-
-          return this.saveAuthorizationCode(authorizationCode, expiresAt, scope, client, uri, user);
-        })
-        .then(function(code) {
-          const responseType = new ResponseType(code.authorizationCode);
-          const redirectUri = this.buildSuccessRedirectUri(uri, responseType);
-
-          this.updateResponse(response, redirectUri, state);
-
-          return code;
-        })
-        .catch(function(e) {
-          if (!(e instanceof OAuthError)) {
-            e = new ServerError(e);
-          }
-          const redirectUri = this.buildErrorRedirectUri(uri, e);
-
-          this.updateResponse(response, redirectUri, state);
-
-          throw e;
-        });
-    });
+  let res;
+
+  try {
+    res = await Promise.all(fns);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  if (!res || !res.length === 3) {
+    return Promise.reject( new ServerError() );
+  }
+
+  const expiresAt = res[0];
+  const client = res[1];
+  const user = res[2];
+  const errorHandler = (err) => {
+
+    if (!(err instanceof OAuthError)) {
+      err = new ServerError();
+    }
+    const redirectUri = this.buildErrorRedirectUri(uri, err);
+
+    this.updateResponse(response, redirectUri, state);
+
+    return Promise.reject(err);
+
+  };
+
+  let uri,
+    scope,
+    scopeIsValid,
+    authorizationCode,
+    state,
+    ResponseType,
+    code;
+
+  try {
+    uri = this.getRedirectUri(request, client);
+  } catch (err) {
+    return errorHandler(err);
+  } 
+
+  try {
+    state = this.getState(request);
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  try {
+    scope = this.getScope(request);
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  try {
+    ResponseType = this.getResponseType(request);
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  if(request.query.allowed === 'false') {
+    return Promise.reject(
+      new AccessDeniedError('Access denied: user denied access to application')
+    );
+  }
+
+  try {
+    scopeIsValid = await this.validateScope(
+      user,
+      client,
+      scope,
+    );
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  try {
+    authorizationCode = await this.generateAuthorizationCode(
+      client, user, scopeIsValid );
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  try {
+    code = await this.saveAuthorizationCode(
+      authorizationCode, expiresAt, scope, client, uri, user);    
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  const responseType = new ResponseType(code.authorizationCode);
+  const redirectUri = this.buildSuccessRedirectUri(uri, responseType);
+
+  this.updateResponse(response, redirectUri, state);
+
+  return Promise.resolve(code);
+
 };
 
 /**
@@ -143,10 +196,13 @@ AuthorizeHandler.prototype.handle = function(request, response) {
  */
 
 AuthorizeHandler.prototype.generateAuthorizationCode = function(client, user, scope) {
+ 
   if (this.model.generateAuthorizationCode) {
-    return promisify(this.model.generateAuthorizationCode, 3).call(this.model, client, user, scope);
+    return this.model.generateAuthorizationCode.call(this.model, client, user, scope);
   }
+
   return tokenUtil.generateRandomToken();
+
 };
 
 /**
@@ -154,73 +210,117 @@ AuthorizeHandler.prototype.generateAuthorizationCode = function(client, user, sc
  */
 
 AuthorizeHandler.prototype.getAuthorizationCodeLifetime = function() {
+
   const expires = new Date();
 
   expires.setSeconds(expires.getSeconds() + this.authorizationCodeLifetime);
+
   return expires;
+
 };
 
 /**
  * Get the client from the model.
  */
 
-AuthorizeHandler.prototype.getClient = function(request) {
+AuthorizeHandler.prototype.getClient = async function(request) {
+
   const clientId = request.body.client_id || request.query.client_id;
 
   if (!clientId) {
-    throw new InvalidRequestError('Missing parameter: `client_id`');
+    return Promise.reject(
+      new InvalidRequestError('Missing parameter: `client_id`')
+    );
   }
 
   if (!is.vschar(clientId)) {
-    throw new InvalidRequestError('Invalid parameter: `client_id`');
+    return Promise.reject(
+      new InvalidRequestError('Invalid parameter: `client_id`')
+    );
   }
 
   const redirectUri = request.body.redirect_uri || request.query.redirect_uri;
 
   if (redirectUri && !is.uri(redirectUri)) {
-    throw new InvalidRequestError('Invalid request: `redirect_uri` is not a valid URI');
-  }
-  return promisify(this.model.getClient, 2).call(this.model, clientId, null)
-    .then(function(client) {
-      if (!client) {
-        throw new InvalidClientError('Invalid client: client credentials are invalid');
-      }
-
-      if (!client.grants) {
-        throw new InvalidClientError('Invalid client: missing client `grants`');
-      }
-
-      if (!Array.isArray(client.grants) || !client.grants.includes('authorization_code')) {
-        throw new UnauthorizedClientError('Unauthorized client: `grant_type` is invalid');
-      }
-
-      if (!client.redirectUris || 0 === client.redirectUris.length) {
-        throw new InvalidClientError('Invalid client: missing client `redirectUri`');
-      }
-
-      if (redirectUri && !client.redirectUris.includes(redirectUri)) {
-        throw new InvalidClientError('Invalid client: `redirect_uri` does not match client value');
-      }
-      return client;
-    });
+    return Promise.reject(
+      new InvalidRequestError('Invalid request: `redirect_uri` is not a valid URI')
+    );
+  }
+
+  let client;
+
+  try {
+    client = await this.model.getClient.call(this.model, clientId, null);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  if (!client) {
+    return Promise.reject(
+      new InvalidClientError('Invalid client: client credentials are invalid')
+    );
+  }
+
+  if (!client.grants) {
+    return Promise.reject(
+      new InvalidClientError('Invalid client: missing client `grants`')
+    );
+  }
+
+  if (!Array.isArray(client.grants) || !client.grants.includes('authorization_code')) {
+    return Promise.reject(
+      new UnauthorizedClientError('Unauthorized client: `grant_type` is invalid')
+    );
+  }
+
+  if (!client.redirectUris || 0 === client.redirectUris.length) {
+    return Promise.reject(
+      new InvalidClientError('Invalid client: missing client `redirectUri`')
+    );
+  }
+
+  if (redirectUri && !client.redirectUris.includes(redirectUri)) {
+    return Promise.reject(
+      new InvalidClientError('Invalid client: `redirect_uri` does not match client value')
+    );
+  }
+
+  return Promise.resolve(client);
+
 };
 
 /**
  * Validate requested scope.
  */
-AuthorizeHandler.prototype.validateScope = function(user, client, scope) {
+
+AuthorizeHandler.prototype.validateScope = async function(user, client, scope) {
+
   if (this.model.validateScope) {
-    return promisify(this.model.validateScope, 3).call(this.model, user, client, scope)
-      .then(function (scope) {
-        if (!scope) {
-          throw new InvalidScopeError('Invalid scope: Requested scope is invalid');
-        }
 
-        return scope;
-      });
-  } else {
-    return Promise.resolve(scope);
+    let isValid;
+
+    try {
+      isValid = await this.model.validateScope
+        .call(this.model, user, client, scope);
+    } catch (err) {
+      return Promise.reject(err);
+    }
+
+    // TODO: fix documentation: "Returns true if the access token passes, false otherwise."
+    // should say "returns true if the access token is valid, Error otherwise."
+    // https://oauth2-server.readthedocs.io/en/latest/model/spec.html#validatescope-user-client-scope-callback
+    if (!isValid) {
+      return Promise.reject( new InvalidScopeError('Invalid scope: Requested scope is invalid') );
+    }
+
+    return isValid;
+
   }
+
+  // REVIEW: This should always be true
+  // from docs: "If not implemented, any scope is accepted."
+  return Promise.resolve(true);
+
 };
 
 /**
@@ -228,6 +328,7 @@ AuthorizeHandler.prototype.validateScope = function(user, client, scope) {
  */
 
 AuthorizeHandler.prototype.getScope = function(request) {
+
   const scope = request.body.scope || request.query.scope;
 
   if (!is.nqschar(scope)) {
@@ -235,6 +336,7 @@ AuthorizeHandler.prototype.getScope = function(request) {
   }
 
   return scope;
+
 };
 
 /**
@@ -242,8 +344,11 @@ AuthorizeHandler.prototype.getScope = function(request) {
  */
 
 AuthorizeHandler.prototype.getState = function(request) {
+
   const state = request.body.state || request.query.state;
+
   const stateExists = state && state.length > 0;
+
   const stateIsValid = stateExists
     ? is.vschar(state)
     : this.allowEmptyState;
@@ -254,23 +359,51 @@ AuthorizeHandler.prototype.getState = function(request) {
   }
 
   return state;
+
 };
 
 /**
  * Get user by calling the authenticate middleware.
  */
 
-AuthorizeHandler.prototype.getUser = function(request, response) {
+AuthorizeHandler.prototype.getUser = async function(request, response) {
+
+  let user;
+
   if (this.authenticateHandler instanceof AuthenticateHandler) {
-    return this.authenticateHandler.handle(request, response).get('user');
-  }
-  return promisify(this.authenticateHandler.handle, 2)(request, response).then(function(user) {
-    if (!user) {
-      throw new ServerError('Server error: `handle()` did not return a `user` object');
+
+    let res;
+
+    try {
+      res = await this.authenticateHandler.handle(request, response);
+    } catch (err) {
+      return Promise.reject(err);
     }
 
-    return user;
-  });
+    if ( !res || !res.user ) {
+      return Promise.reject( 
+        new ServerError('Server error: `handle()` did not return a `user` object')
+      );
+    }
+
+    return Promise.resolve(res.user);
+
+  } 
+
+  try {
+    user = await this.authenticateHandler.handle(request, response);
+  } catch (err) {
+    return Promise.reject(err);
+  }
+
+  if (!user) {
+    return Promise.reject( 
+      new ServerError('Server error: `handle()` did not return a `user` object')
+    );
+  }
+
+  return Promise.resolve(user);
+
 };
 
 /**
@@ -278,39 +411,49 @@ AuthorizeHandler.prototype.getUser = function(request, response) {
  */
 
 AuthorizeHandler.prototype.getRedirectUri = function(request, client) {
-  return request.body.redirect_uri || request.query.redirect_uri || client.redirectUris[0];
+
+  return request.body.redirect_uri || 
+    request.query.redirect_uri ||
+    client.redirectUris[0];
+
 };
 
 /**
  * Save authorization code.
  */
 
-AuthorizeHandler.prototype.saveAuthorizationCode = function(authorizationCode, expiresAt, scope, client, redirectUri, user) {
-  const code = {
-    authorizationCode: authorizationCode,
-    expiresAt: expiresAt,
-    redirectUri: redirectUri,
-    scope: scope
+AuthorizeHandler.prototype.saveAuthorizationCode = 
+  function(authorizationCode, expiresAt, scope, client, redirectUri, user) {
+
+    const code = {
+      authorizationCode: authorizationCode,
+      expiresAt: expiresAt,
+      redirectUri: redirectUri,
+      scope: scope
+    };
+
+    return this.model.saveAuthorizationCode.call(this.model, code, client, user);
+
   };
-  return promisify(this.model.saveAuthorizationCode, 3).call(this.model, code, client, user);
-};
 
 /**
  * Get response type.
  */
 
 AuthorizeHandler.prototype.getResponseType = function(request) {
+  
   const responseType = request.body.response_type || request.query.response_type;
 
   if (!responseType) {
     throw new InvalidRequestError('Missing parameter: `response_type`');
   }
 
-  if (!Object.prototype.hasOwnProperty.call(responseTypes, responseType)) {
+  if ( !Object.prototype.hasOwnProperty.call(responseTypes, responseType) ) {
     throw new UnsupportedResponseTypeError('Unsupported response type: `response_type` is not supported');
   }
 
   return responseTypes[responseType];
+
 };
 
 /**
@@ -344,6 +487,7 @@ AuthorizeHandler.prototype.buildErrorRedirectUri = function(redirectUri, error)
  */
 
 AuthorizeHandler.prototype.updateResponse = function(response, redirectUri, state) {
+  
   redirectUri.query = redirectUri.query || {};
 
   if (state) {
@@ -351,6 +495,7 @@ AuthorizeHandler.prototype.updateResponse = function(response, redirectUri, stat
   }
 
   response.redirect(url.format(redirectUri));
+
 };
 
 /**
diff --git a/lib/handlers/token-handler.js b/lib/handlers/token-handler.js
index 8195969..9eaa864 100644
--- a/lib/handlers/token-handler.js
+++ b/lib/handlers/token-handler.js
@@ -9,8 +9,6 @@ const InvalidArgumentError = require('../errors/invalid-argument-error');
 const InvalidClientError = require('../errors/invalid-client-error');
 const InvalidRequestError = require('../errors/invalid-request-error');
 const OAuthError = require('../errors/oauth-error');
-const Promise = require('bluebird');
-const promisify = require('promisify-any').use(Promise);
 const Request = require('../request');
 const Response = require('../response');
 const ServerError = require('../errors/server-error');
@@ -67,99 +65,169 @@ function TokenHandler(options) {
  * Token Handler.
  */
 
-TokenHandler.prototype.handle = function(request, response) {
+TokenHandler.prototype.handle = async function(request, response) {
+
   if (!(request instanceof Request)) {
-    throw new InvalidArgumentError('Invalid argument: `request` must be an instance of Request');
+    return Promise.reject(
+      new InvalidArgumentError('Invalid argument: `request` must be an instance of Request')
+    );
   }
 
   if (!(response instanceof Response)) {
-    throw new InvalidArgumentError('Invalid argument: `response` must be an instance of Response');
+    return Promise.reject(
+      new InvalidArgumentError('Invalid argument: `response` must be an instance of Response')
+    );
   }
 
   if (request.method !== 'POST') {
-    return Promise.reject(new InvalidRequestError('Invalid request: method must be POST'));
+    return Promise.reject(
+      new InvalidRequestError('Invalid request: method must be POST')
+    );
   }
 
   if (!request.is('application/x-www-form-urlencoded')) {
-    return Promise.reject(new InvalidRequestError('Invalid request: content must be application/x-www-form-urlencoded'));
-  }
-
-  return Promise.bind(this)
-    .then(function() {
-      return this.getClient(request, response);
-    })
-    .then(function(client) {
-      return this.handleGrantType(request, client);
-    })
-    .tap(function(data) {
-      const model = new TokenModel(data, {allowExtendedTokenAttributes: this.allowExtendedTokenAttributes});
-      const tokenType = this.getTokenType(model);
-
-      this.updateSuccessResponse(response, tokenType);
-    }).catch(function(e) {
-      if (!(e instanceof OAuthError)) {
-        e = new ServerError(e);
-      }
-
-      this.updateErrorResponse(response, e);
-
-      throw e;
-    });
+    return Promise.reject(
+      new InvalidRequestError('Invalid request: content must be application/x-www-form-urlencoded')
+    );
+  }
+
+  const errorHandler = (err) => {
+
+    if (!(err instanceof OAuthError)) {
+      err = new ServerError(err);
+    }
+
+    this.updateErrorResponse(response, err);
+
+    return Promise.reject(err);
+  };
+
+  let client,
+    data,
+    tokenType;
+
+  try {
+    client = await this.getClient(request, response);
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  if (!client) {
+    return errorHandler();
+  }
+
+  try {
+    data = await this.handleGrantType(request, client);
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  if (!data) {
+    return errorHandler();
+  }
+
+  const model = new TokenModel(data, {
+    allowExtendedTokenAttributes:
+    this.allowExtendedTokenAttributes
+  });
+
+  try {
+    tokenType = this.getTokenType(model);
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  if (!tokenType) {
+    return errorHandler();
+  }
+
+  try {
+    this.updateSuccessResponse(response, tokenType);
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  return Promise.resolve(data);
+
 };
 
 /**
  * Get the client from the model.
  */
 
-TokenHandler.prototype.getClient = function(request, response) {
+TokenHandler.prototype.getClient = async function(request, response) {
+
   const credentials = this.getClientCredentials(request);
+
   const grantType = request.body.grant_type;
 
   if (!credentials.clientId) {
-    throw new InvalidRequestError('Missing parameter: `client_id`');
+    return Promise.reject(
+      new InvalidRequestError('Missing parameter: `client_id`')
+    );
   }
 
   if (this.isClientAuthenticationRequired(grantType) && !credentials.clientSecret) {
-    throw new InvalidRequestError('Missing parameter: `client_secret`');
+    return Promise.reject(
+      new InvalidRequestError('Missing parameter: `client_secret`')
+    );
   }
 
   if (!is.vschar(credentials.clientId)) {
-    throw new InvalidRequestError('Invalid parameter: `client_id`');
+    return Promise.reject(
+      new InvalidRequestError('Invalid parameter: `client_id`')
+    );
   }
 
   if (credentials.clientSecret && !is.vschar(credentials.clientSecret)) {
-    throw new InvalidRequestError('Invalid parameter: `client_secret`');
-  }
-
-  return promisify(this.model.getClient, 2).call(this.model, credentials.clientId, credentials.clientSecret)
-    .then(function(client) {
-      if (!client) {
-        throw new InvalidClientError('Invalid client: client is invalid');
-      }
-
-      if (!client.grants) {
-        throw new ServerError('Server error: missing client `grants`');
-      }
-
-      if (!(client.grants instanceof Array)) {
-        throw new ServerError('Server error: `grants` must be an array');
-      }
-
-      return client;
-    })
-    .catch(function(e) {
-      // Include the "WWW-Authenticate" response header field if the client
-      // attempted to authenticate via the "Authorization" request header.
-      //
-      // @see https://tools.ietf.org/html/rfc6749#section-5.2.
-      if ((e instanceof InvalidClientError) && request.get('authorization')) {
-        response.set('WWW-Authenticate', 'Basic realm="Service"');
-
-        throw new InvalidClientError(e, { code: 401 });
-      }
-
-      throw e;
-    });
+    return Promise.reject(
+      new InvalidRequestError('Invalid parameter: `client_secret`')
+    );
+  }
+
+  function errorHandler(err) {
+    // Include the "WWW-Authenticate" response header field if the client
+    // attempted to authenticate via the "Authorization" request header.
+    //
+    // @see https://tools.ietf.org/html/rfc6749#section-5.2.
+    if ((err instanceof InvalidClientError) && request.get('authorization')) {
+      response.set('WWW-Authenticate', 'Basic realm="Service"');
+
+      return Promise.reject( new InvalidClientError(err, { code: 401 }) );
+    }
+
+    return Promise.reject(err);
+  }
+
+  let client;
+
+  try {
+    client = await this.model.getClient.call(
+      this.model, credentials.clientId, credentials.clientSecret );
+  } catch (err) {
+    return errorHandler(err);
+  }
+
+  if (!client) {
+    return errorHandler(
+      new InvalidClientError('Invalid client: client is invalid')
+    );
+  }
+
+  if (!client.grants) {
+    return errorHandler(
+      new ServerError('Server error: missing client `grants`')
+    );
+  }
+
+  if (!(client.grants instanceof Array)) {
+    return errorHandler(
+      new ServerError('Server error: `grants` must be an array')
+    );
+  }
+
+  return Promise.resolve(client);
+
 };
 
 /**
@@ -172,7 +240,9 @@ TokenHandler.prototype.getClient = function(request, response) {
  */
 
 TokenHandler.prototype.getClientCredentials = function(request) {
+
   const credentials = auth(request);
+
   const grantType = request.body.grant_type;
 
   if (credentials) {
@@ -197,6 +267,7 @@ TokenHandler.prototype.getClientCredentials = function(request) {
  */
 
 TokenHandler.prototype.handleGrantType = function(request, client) {
+  
   const grantType = request.body.grant_type;
 
   if (!grantType) {
@@ -251,7 +322,15 @@ TokenHandler.prototype.getRefreshTokenLifetime = function(client) {
  */
 
 TokenHandler.prototype.getTokenType = function(model) {
-  return new BearerTokenType(model.accessToken, model.accessTokenLifetime, model.refreshToken, model.scope, model.customAttributes);
+
+  return new BearerTokenType(
+    model.accessToken,
+    model.accessTokenLifetime,
+    model.refreshToken,
+    model.scope,
+    model.customAttributes
+  );
+
 };
 
 /**
@@ -259,10 +338,13 @@ TokenHandler.prototype.getTokenType = function(model) {
  */
 
 TokenHandler.prototype.updateSuccessResponse = function(response, tokenType) {
+
   response.body = tokenType.valueOf();
 
   response.set('Cache-Control', 'no-store');
+
   response.set('Pragma', 'no-cache');
+
 };
 
 /**
@@ -270,6 +352,7 @@ TokenHandler.prototype.updateSuccessResponse = function(response, tokenType) {
  */
 
 TokenHandler.prototype.updateErrorResponse = function(response, error) {
+  
   response.body = {
     error: error.name,
     error_description: error.message
@@ -282,11 +365,18 @@ TokenHandler.prototype.updateErrorResponse = function(response, error) {
  * Given a grant type, check if client authentication is required
  */
 TokenHandler.prototype.isClientAuthenticationRequired = function(grantType) {
+
   if (Object.keys(this.requireClientAuthentication).length > 0) {
-    return (typeof this.requireClientAuthentication[grantType] !== 'undefined') ? this.requireClientAuthentication[grantType] : true;
+
+    return (typeof this.requireClientAuthentication[grantType] !== 'undefined') 
+      ? this.requireClientAuthentication[grantType] : true;
+
   } else {
+
     return true;
+
   }
+
 };
 
 /**
diff --git a/lib/server.js b/lib/server.js
index 53bbd2a..58f85e1 100644
--- a/lib/server.js
+++ b/lib/server.js
@@ -12,7 +12,6 @@ const TokenHandler = require('./handlers/token-handler');
 /**
  * Constructor.
  */
-
 function OAuth2Server(options) {
   options = options || {};
 
@@ -21,13 +20,19 @@ function OAuth2Server(options) {
   }
 
   this.options = options;
+
+  // REVIEW: This allows you to access the handlers from an instance of OAuth2Server.
+  this.authenticateHandler;
+  this.authorizeHandler;
+  this.tokenHandler;
+
 }
 
 /**
  * Authenticate a token.
  */
+OAuth2Server.prototype.authenticate = function(request, response, options) {
 
-OAuth2Server.prototype.authenticate = function(request, response, options, callback) {
   if (typeof options === 'string') {
     options = {scope: options};
   }
@@ -38,41 +43,44 @@ OAuth2Server.prototype.authenticate = function(request, response, options, callb
     allowBearerTokensInQueryString: false
   }, this.options, options);
 
-  return new AuthenticateHandler(options)
-    .handle(request, response)
-    .nodeify(callback);
+  this.authenticateHandler = new AuthenticateHandler(options);
+  
+  return this.authenticateHandler.handle(request, response);
+
 };
 
 /**
  * Authorize a request.
  */
+OAuth2Server.prototype.authorize = function(request, response, options) {
 
-OAuth2Server.prototype.authorize = function(request, response, options, callback) {
   options = Object.assign({
     allowEmptyState: false,
-    authorizationCodeLifetime: 5 * 60   // 5 minutes.
+    authorizationCodeLifetime: 300 // 5 * 60 = 5 minutes.
   }, this.options, options);
 
-  return new AuthorizeHandler(options)
-    .handle(request, response)
-    .nodeify(callback);
+  this.authorizeHandler = new AuthorizeHandler(options);
+
+  return this.authorizeHandler.handle(request, response);
+
 };
 
 /**
  * Create a token.
  */
+OAuth2Server.prototype.token = function(request, response, options) {
 
-OAuth2Server.prototype.token = function(request, response, options, callback) {
   options = Object.assign({
-    accessTokenLifetime: 60 * 60,             // 1 hour.
-    refreshTokenLifetime: 60 * 60 * 24 * 14,  // 2 weeks.
+    accessTokenLifetime: 3600, // 60 * 60 = 1 hour.
+    refreshTokenLifetime: 1209600,  // 60 * 60 * 24 * 14 = 2 weeks.
     allowExtendedTokenAttributes: false,
-    requireClientAuthentication: {}           // defaults to true for all grant types
+    requireClientAuthentication: {}  // defaults to true for all grant types
   }, this.options, options);
 
-  return new TokenHandler(options)
-    .handle(request, response)
-    .nodeify(callback);
+  this.tokenHandler = new TokenHandler(options);
+
+  return this.tokenHandler.handle(request, response);
+
 };
 
 /**
diff --git a/lib/utils/token-util.js b/lib/utils/token-util.js
index a66e252..2e8ba5c 100644
--- a/lib/utils/token-util.js
+++ b/lib/utils/token-util.js
@@ -3,9 +3,8 @@
 /**
  * Module dependencies.
  */
-
 const crypto = require('crypto');
-const randomBytes = require('bluebird').promisify(require('crypto').randomBytes);
+const {promisify} = require('util');
 
 /**
  * Export `TokenUtil`.
@@ -16,14 +15,21 @@ module.exports = {
   /**
    * Generate random token.
    */
+  generateRandomToken: async function() {
+
+    let buffer;
+
+    try {
+      buffer = await promisify(crypto.randomBytes)(256);
+    } catch (err) {
+      return Promise.reject(err);
+    }
+
+    return crypto
+      .createHash('sha256')
+      .update(buffer)
+      .digest('hex');
 
-  generateRandomToken: function() {
-    return randomBytes(256).then(function(buffer) {
-      return crypto
-        .createHash('sha256')
-        .update(buffer)
-        .digest('hex');
-    });
   }
 
 };
diff --git a/test/integration/grant-types/abstract-grant-type_test.js b/test/integration/grant-types/abstract-grant-type_test.js
index a6c4d2b..e8119e8 100644
--- a/test/integration/grant-types/abstract-grant-type_test.js
+++ b/test/integration/grant-types/abstract-grant-type_test.js
@@ -6,7 +6,6 @@
 
 const AbstractGrantType = require('../../../lib/grant-types/abstract-grant-type');
 const InvalidArgumentError = require('../../../lib/errors/invalid-argument-error');
-const Promise = require('bluebird');
 const Request = require('../../../lib/request');
 const should = require('chai').should();
 
@@ -78,6 +77,7 @@ describe('AbstractGrantType integration', function() {
       const handler = new AbstractGrantType({ accessTokenLifetime: 123, model: model, refreshTokenLifetime: 456 });
 
       handler.generateAccessToken().should.be.an.instanceOf(Promise);
+
     });
 
     it('should support non-promises', function() {
diff --git a/test/integration/grant-types/authorization-code-grant-type_test.js b/test/integration/grant-types/authorization-code-grant-type_test.js
index 6cddd53..8b55ee6 100644
--- a/test/integration/grant-types/authorization-code-grant-type_test.js
+++ b/test/integration/grant-types/authorization-code-grant-type_test.js
@@ -8,7 +8,6 @@ const AuthorizationCodeGrantType = require('../../../lib/grant-types/authorizati
 const InvalidArgumentError = require('../../../lib/errors/invalid-argument-error');
 const InvalidGrantError = require('../../../lib/errors/invalid-grant-error');
 const InvalidRequestError = require('../../../lib/errors/invalid-request-error');
-const Promise = require('bluebird');
 const Request = require('../../../lib/request');
 const ServerError = require('../../../lib/errors/server-error');
 const should = require('chai').should();
@@ -18,7 +17,38 @@ const should = require('chai').should();
  */
 
 describe('AuthorizationCodeGrantType integration', function() {
+
+  const defaultModel = {
+    getAuthorizationCode: function() { 
+      return Promise.resolve({
+        authorizationCode: 12345,
+        expiresAt: new Date(new Date() * 2),
+        user: {},
+        client: { id: 'foobar' },
+      }); 
+    },
+    revokeAuthorizationCode: function() {
+      return Promise.resolve(true);
+    },
+    saveToken: function() {
+      return Promise.resolve({});
+    },
+    validateScope: function() { return 'read'; }
+  };
+
+  const defaultRequest = new Request(
+    {
+      body: { 
+        code: 12345
+      },
+      headers: {},
+      method: {},
+      query: {}
+    }
+  );
+
   describe('constructor()', function() {
+
     it('should throw an error if `model` is missing', function() {
       try {
         new AuthorizationCodeGrantType();
@@ -74,172 +104,247 @@ describe('AuthorizationCodeGrantType integration', function() {
   });
 
   describe('handle()', function() {
-    it('should throw an error if `request` is missing', function() {
-      const model = {
-        getAuthorizationCode: function() {},
-        revokeAuthorizationCode: function() {},
-        saveToken: function() {}
-      };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
 
-      try {
-        grantType.handle();
+    it('should throw an error if `request` is missing', async function() {
 
-        should.fail();
-      } catch (e) {
-        e.should.be.an.instanceOf(InvalidArgumentError);
-        e.message.should.equal('Missing parameter: `request`');
+      const model = {...defaultModel};
+      model.getAuthorizationCode = function() {};
+      model.revokeAuthorizationCode = function() {};
+      model.saveToken = function() {};
+
+      const grantType = new AuthorizationCodeGrantType(
+        {
+          accessTokenLifetime: 123,
+          model: model
+        }
+      );
+
+      let result;
+      try {
+        result = await grantType.handle();
+      } catch (err) {
+        should.exist(err);
+        err.should.be.an.instanceOf(InvalidArgumentError);
+        err.message.should.equal('Missing parameter: `request`');
       }
+
+      should.not.exist(result);
+
     });
-    
-    it('should throw an error if `client` is invalid', function() {
+
+
+    it('should throw an error if `client` is invalid', async function() {
+
       const client = {};
-      const model = {
-        getAuthorizationCode: function() { return { authorizationCode: 12345, expiresAt: new Date(new Date() * 2), user: {} }; },
-        revokeAuthorizationCode: function() {},
-        saveToken: function() {}
+      const model = {...defaultModel};
+      model.getAuthorizationCode = function() { 
+        return Promise.resolve({
+          authorizationCode: 12345,
+          expiresAt: new Date(new Date() * 2),
+          user: {},
+          // client: { id: 'foobar' },
+        }); 
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
-      return grantType.handle(request, client)
-        .then(should.fail)
-        .catch(function(e) {
-          e.should.be.an.instanceOf(ServerError);
-          e.message.should.equal('Server error: `getAuthorizationCode()` did not return a `client` object');
-        });
+      const grantType = new AuthorizationCodeGrantType(
+        {
+          accessTokenLifetime: 123,
+          model: model
+        }
+      );
+
+      let result;
+
+      try {
+        result = await grantType.handle(defaultRequest, client);
+      } catch (err) {
+        should.exist(err);
+        err.should.be.an.instanceOf(ServerError);
+        err.message.should.equal('Server error: `getAuthorizationCode()` did not return a `client` object');
+      }
+
+      should.not.exist(result);
+
     });
 
-    it('should throw an error if `client` is missing', function() {
+    it('should throw an error if `client` is missing', async function() {
       
-      const model = {
-        getAuthorizationCode: function() { return { authorizationCode: 12345, expiresAt: new Date(new Date() * 2), user: {} }; },
-        revokeAuthorizationCode: function() {},
-        saveToken: function() {}
+      const client = null;
+      const model = {...defaultModel};
+      model.getAuthorizationCode = function() { 
+        return Promise.resolve({
+          authorizationCode: 12345,
+          expiresAt: new Date(new Date() * 2),
+          user: {},
+        }); 
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
+
+      const grantType = new AuthorizationCodeGrantType(
+        {
+          accessTokenLifetime: 123,
+          model: model
+        }
+      );
+
+      let result;
 
       try {
-        grantType.handle(request, null);
-      }
-      catch (e) {
-        e.should.be.an.instanceOf(InvalidArgumentError);
-        e.message.should.equal('Missing parameter: `client`');
+        result = await grantType.handle(defaultRequest, client);
+      } catch (err) {
+        should.exist(err);
+        err.should.be.an.instanceOf(InvalidArgumentError);
+        err.message.should.equal('Missing parameter: `client`');
       }
+
+      should.not.exist(result);
+
     });
 
-    it('should return a token', function() {
+    it('should return a token', async function() {
+
       const client = { id: 'foobar' };
-      const token = {};
-      const model = {
-        getAuthorizationCode: function() { return { authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; },
-        revokeAuthorizationCode: function() { return true; },
-        saveToken: function() { return token; },
-        validateScope: function() { return 'foo'; }
-      };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
+      const grantType = new AuthorizationCodeGrantType(
+        {
+          accessTokenLifetime: 123,
+          model: defaultModel
+        }
+      );
+
+      let result;
+
+      try {
+        result = await grantType.handle(defaultRequest, client);
+      } catch (err) {
+        should.not.exist(err, err.stack);
+      }
+      should.exist(result);
+      result.should.eql({}, 'data should equal ');
 
-      return grantType.handle(request, client)
-        .then(function(data) {
-          data.should.equal(token);
-        })
-        .catch(should.fail);
     });
 
+
     it('should support promises', function() {
+
       const client = { id: 'foobar' };
-      const model = {
-        getAuthorizationCode: function() { return Promise.resolve({ authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }); },
-        revokeAuthorizationCode: function() { return true; },
-        saveToken: function() {}
-      };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
+      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: defaultModel });
 
-      grantType.handle(request, client).should.be.an.instanceOf(Promise);
+      grantType.handle(defaultRequest, client).should.be.an.instanceOf(Promise);
     });
 
     it('should support non-promises', function() {
       const client = { id: 'foobar' };
-      const model = {
-        getAuthorizationCode: function() { return { authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }; },
-        revokeAuthorizationCode: function() { return true; },
-        saveToken: function() {}
-      };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
-      grantType.handle(request, client).should.be.an.instanceOf(Promise);
+      const model = {...defaultModel};
+      model.getAuthorizationCode = function() { 
+        return {
+          authorizationCode: 12345,
+          client: { id: 'foobar' },
+          expiresAt: new Date(new Date() * 2),
+          user: {} 
+        }; 
+      },
+      model.revokeAuthorizationCode = function() { return true; },
+      model.saveToken = function() {};
+
+      const grantType = new AuthorizationCodeGrantType(
+        {
+          accessTokenLifetime: 123,
+          model: model
+        }
+      );
+
+      grantType.handle(defaultRequest, client).should.be.an.instanceOf(Promise);
     });
 
-    it('should support callbacks', function() {
+    it.skip('should not support callbacks', function() {
+
       const client = { id: 'foobar' };
-      const model = {
-        getAuthorizationCode: function(code, callback) { callback(null, { authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} }); },
-        revokeAuthorizationCode: function(code, callback) { callback(null, { authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() / 2), user: {} }); },
-        saveToken: function(tokenToSave, client, user, callback) { callback(null, tokenToSave); }
+      const model = {...defaultModel};
+      
+      model.getAuthorizationCode =  function(code, callback) {
+        callback( null, 
+          {
+            authorizationCode: 12345,
+            client: { id: 'foobar' },
+            expiresAt: new Date(new Date() * 2),
+            user: {}
+          }
+        ); 
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
-      grantType.handle(request, client).should.be.an.instanceOf(Promise);
+      model.revokeAuthorizationCode =  function(code, callback) {
+        callback( null, 
+          {
+            authorizationCode: 12345,
+            client: { id: 'foobar' },
+            expiresAt: new Date(new Date() / 2),
+            user: {} 
+          }
+        ); 
+      };
+
+      model.saveToken =  function(tokenToSave, client, user, callback) {
+        callback( null, tokenToSave);
+      };
+
+      const grantType = new AuthorizationCodeGrantType(
+        {
+          accessTokenLifetime: 123,
+          model: model
+        }
+      );
+
+      grantType.handle(defaultRequest, client);
+
     });
   });
 
   describe('getAuthorizationCode()', function() {
-    it('should throw an error if the request body does not contain `code`', function() {
-      const client = {};
-      const model = {
-        getAuthorizationCode: function() {},
-        revokeAuthorizationCode: function() {},
-        saveToken: function() {}
-      };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
 
-      try {
-        grantType.getAuthorizationCode(request, client);
+    it('should throw an error if the request body does not contain `code`', async function() {
 
-        should.fail();
-      } catch (e) {
-        e.should.be.an.instanceOf(InvalidRequestError);
-        e.message.should.equal('Missing parameter: `code`');
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: defaultModel 
+      }); 
+      const request = {...defaultRequest};
+      request.body = {};
+
+      try {
+        await grantType.getAuthorizationCode(request, {});
+      } catch (err) {
+        err.should.be.an.instanceOf(InvalidRequestError);
+        err.message.should.equal('Missing parameter: `code`');
       }
     });
 
-    it('should throw an error if `code` is invalid', function() {
-      const client = {};
-      const model = {
-        getAuthorizationCode: function() {},
-        revokeAuthorizationCode: function() {},
-        saveToken: function() {}
-      };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { code: 'øå€£‰' }, headers: {}, method: {}, query: {} });
+    it('should throw an error if `code` is invalid', async function() {
 
-      try {
-        grantType.getAuthorizationCode(request, client);
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: defaultModel 
+      });
+      const request = {...defaultRequest};
+      request.body = {code: 'øå€£‰'};
 
-        should.fail();
-      } catch (e) {
-        e.should.be.an.instanceOf(InvalidRequestError);
-        e.message.should.equal('Invalid parameter: `code`');
+      try {
+        await grantType.getAuthorizationCode(request, {});
+      } catch (err) {
+        err.should.be.an.instanceOf(InvalidRequestError);
+        err.message.should.equal('Invalid parameter: `code`');
       }
     });
 
     it('should throw an error if `authorizationCode` is missing', function() {
-      const client = {};
-      const model = {
-        getAuthorizationCode: function() {},
-        revokeAuthorizationCode: function() {},
-        saveToken: function() {}
-      };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
-      return grantType.getAuthorizationCode(request, client)
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: defaultModel 
+      });
+      const request = {...defaultRequest};
+      request.body = {code: 12345};
+
+      return grantType.getAuthorizationCode(request, {})
         .then(should.fail)
         .catch(function(e) {
           e.should.be.an.instanceOf(InvalidGrantError);
@@ -248,16 +353,18 @@ describe('AuthorizationCodeGrantType integration', function() {
     });
 
     it('should throw an error if `authorizationCode.client` is missing', function() {
-      const client = {};
-      const model = {
-        getAuthorizationCode: function() { return { authorizationCode: 12345 }; },
-        revokeAuthorizationCode: function() {},
-        saveToken: function() {}
+
+      const model = {...defaultModel};
+      model.getAuthorizationCode = function() { 
+        return { authorizationCode: 12345 }; 
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
+      
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
 
-      return grantType.getAuthorizationCode(request, client)
+      return grantType.getAuthorizationCode(defaultRequest, {})
         .then(should.fail)
         .catch(function(e) {
           e.should.be.an.instanceOf(ServerError);
@@ -266,16 +373,19 @@ describe('AuthorizationCodeGrantType integration', function() {
     });
 
     it('should throw an error if `authorizationCode.expiresAt` is missing', function() {
-      const client = {};
-      const model = {
-        getAuthorizationCode: function() { return { authorizationCode: 12345, client: {}, user: {} }; },
-        revokeAuthorizationCode: function() {},
-        saveToken: function() {}
+
+      const model = {...defaultModel};
+      
+      model.getAuthorizationCode = function() { 
+        return { authorizationCode: 12345, client: {}, user: {} }; 
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
-      return grantType.getAuthorizationCode(request, client)
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
+
+      return grantType.getAuthorizationCode(defaultRequest, {})
         .then(should.fail)
         .catch(function(e) {
           e.should.be.an.instanceOf(ServerError);
@@ -290,7 +400,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() {},
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
       const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
       return grantType.getAuthorizationCode(request, client)
@@ -310,7 +423,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() {},
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
       const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
       return grantType.getAuthorizationCode(request, client)
@@ -331,7 +447,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() {},
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
       const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
       return grantType.getAuthorizationCode(request, client)
@@ -350,7 +469,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() {},
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
       const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
       return grantType.getAuthorizationCode(request, client)
@@ -369,7 +491,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() {},
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
       const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
       return grantType.getAuthorizationCode(request, client)
@@ -387,7 +512,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() {},
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
       const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
       grantType.getAuthorizationCode(request, client).should.be.an.instanceOf(Promise);
@@ -401,13 +529,16 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() {},
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
       const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
       grantType.getAuthorizationCode(request, client).should.be.an.instanceOf(Promise);
     });
 
-    it('should support callbacks', function() {
+    it.skip('should support callbacks', function() {
       const authorizationCode = { authorizationCode: 12345, client: { id: 'foobar' }, expiresAt: new Date(new Date() * 2), user: {} };
       const client = { id: 'foobar' };
       const model = {
@@ -415,7 +546,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() {},
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
       const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
       grantType.getAuthorizationCode(request, client).should.be.an.instanceOf(Promise);
@@ -430,7 +564,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() { return authorizationCode; },
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
       const request = new Request({ body: { code: 12345 }, headers: {}, method: {}, query: {} });
 
       try {
@@ -450,7 +587,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() { return true; },
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
       const request = new Request({ body: { code: 12345, redirect_uri: 'http://bar.foo' }, headers: {}, method: {}, query: {} });
 
       try {
@@ -472,7 +612,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() { return true; },
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
 
       return grantType.revokeAuthorizationCode(authorizationCode)
         .then(function(data) {
@@ -488,7 +631,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() { return false; },
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
 
       return grantType.revokeAuthorizationCode(authorizationCode)
         .then(function(data) {
@@ -507,7 +653,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() { return Promise.resolve(true); },
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
 
       grantType.revokeAuthorizationCode(authorizationCode).should.be.an.instanceOf(Promise);
     });
@@ -519,19 +668,25 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() { return authorizationCode; },
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
 
       grantType.revokeAuthorizationCode(authorizationCode).should.be.an.instanceOf(Promise);
     });
 
-    it('should support callbacks', function() {
+    it.skip('should support callbacks', function() {
       const authorizationCode = { authorizationCode: 12345, client: {}, expiresAt: new Date(new Date() / 2), user: {} };
       const model = {
         getAuthorizationCode: function() {},
         revokeAuthorizationCode: function(code, callback) { callback(null, authorizationCode); },
         saveToken: function() {}
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
 
       grantType.revokeAuthorizationCode(authorizationCode).should.be.an.instanceOf(Promise);
     });
@@ -546,7 +701,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         saveToken: function() { return token; },
         validateScope: function() { return 'foo'; }
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
 
       return grantType.saveToken(token)
         .then(function(data) {
@@ -562,7 +720,10 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() {},
         saveToken: function() { return Promise.resolve(token); }
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
 
       grantType.saveToken(token).should.be.an.instanceOf(Promise);
     });
@@ -574,19 +735,25 @@ describe('AuthorizationCodeGrantType integration', function() {
         revokeAuthorizationCode: function() {},
         saveToken: function() { return token; }
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
 
       grantType.saveToken(token).should.be.an.instanceOf(Promise);
     });
 
-    it('should support callbacks', function() {
+    it.skip('should support callbacks', function() {
       const token = {};
       const model = {
         getAuthorizationCode: function() {},
         revokeAuthorizationCode: function() {},
         saveToken: function(tokenToSave, client, user, callback) { callback(null, token); }
       };
-      const grantType = new AuthorizationCodeGrantType({ accessTokenLifetime: 123, model: model });
+      const grantType = new AuthorizationCodeGrantType({ 
+        accessTokenLifetime: 123,
+        model: model 
+      });
 
       grantType.saveToken(token).should.be.an.instanceOf(Promise);
     });
diff --git a/test/integration/grant-types/client-credentials-grant-type_test.js b/test/integration/grant-types/client-credentials-grant-type_test.js
index b13df08..089a213 100644
--- a/test/integration/grant-types/client-credentials-grant-type_test.js
+++ b/test/integration/grant-types/client-credentials-grant-type_test.js
@@ -7,9 +7,9 @@
 const ClientCredentialsGrantType = require('../../../lib/grant-types/client-credentials-grant-type');
 const InvalidArgumentError = require('../../../lib/errors/invalid-argument-error');
 const InvalidGrantError = require('../../../lib/errors/invalid-grant-error');
-const Promise = require('bluebird');
 const Request = require('../../../lib/request');
 const should = require('chai').should();
+const sinon = require('sinon');
 
 /**
  * Test `ClientCredentialsGrantType` integration.
@@ -20,7 +20,6 @@ describe('ClientCredentialsGrantType integration', function() {
     it('should throw an error if `model` is missing', function() {
       try {
         new ClientCredentialsGrantType();
-
         should.fail();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
@@ -56,24 +55,31 @@ describe('ClientCredentialsGrantType integration', function() {
   });
 
   describe('handle()', function() {
-    it('should throw an error if `request` is missing', function() {
+
+    it('should throw an error if `request` is missing', async function() {
+
       const model = {
         getUserFromClient: function() {},
         saveToken: function() {}
       };
+
       const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 120, model: model });
 
-      try {
-        grantType.handle();
+      let res;
 
-        should.fail();
+      try {
+        res = await grantType.handle();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `request`');
       }
+
+      should.not.exist(res);
+
     });
 
-    it('should throw an error if `client` is missing', function() {
+    it('should throw an error if `client` is missing', async function() {
+
       const model = {
         getUserFromClient: function() {},
         saveToken: function() {}
@@ -81,56 +87,41 @@ describe('ClientCredentialsGrantType integration', function() {
       const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 120, model: model });
       const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
 
-      try {
-        grantType.handle(request);
+      let res;
 
-        should.fail();
+      try {
+        res = await grantType.handle(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `client`');
       }
-    });
 
-    it('should return a token', function() {
-      const token = {};
-      const model = {
-        getUserFromClient: function() { return {}; },
-        saveToken: function() { return token; },
-        validateScope: function() { return 'foo'; }
-      };
-      const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 120, model: model });
-      const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
+      should.not.exist(res);
 
-      return grantType.handle(request, {})
-        .then(function(data) {
-          data.should.equal(token);
-        })
-        .catch(should.fail);
     });
 
-    it('should support promises', function() {
+    it('should return a token', async function() {
       const token = {};
       const model = {
-        getUserFromClient: function() { return {}; },
-        saveToken: function() { return token; }
+        getUserFromClient: sinon.stub().returns({}),
+        saveToken: sinon.stub().returns(token),
+        validateScope: sinon.stub().returns('foo'),
       };
       const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 120, model: model });
       const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
 
-      grantType.handle(request, {}).should.be.an.instanceOf(Promise);
-    });
+      let res;
 
-    it('should support non-promises', function() {
-      const token = {};
-      const model = {
-        getUserFromClient: function() { return {}; },
-        saveToken: function() { return token; }
-      };
-      const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 120, model: model });
-      const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
+      try {
+        res = await grantType.handle(request, {});
+      } catch (e) { 
+        should.not.exist(e, e.stack);
+      }
+      res.should.eql(token);
 
-      grantType.handle(request, {}).should.be.an.instanceOf(Promise);
     });
+
+
   });
 
   describe('getUserFromClient()', function() {
@@ -153,8 +144,8 @@ describe('ClientCredentialsGrantType integration', function() {
     it('should return a user', function() {
       const user = { email: 'foo@bar.com' };
       const model = {
-        getUserFromClient: function() { return user; },
-        saveToken: function() {}
+        getUserFromClient: sinon.stub().returns(user),
+        saveToken: sinon.stub().returns({})
       };
       const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 120, model: model });
       const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
@@ -169,19 +160,7 @@ describe('ClientCredentialsGrantType integration', function() {
     it('should support promises', function() {
       const user = { email: 'foo@bar.com' };
       const model = {
-        getUserFromClient: function() { return Promise.resolve(user); },
-        saveToken: function() {}
-      };
-      const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 120, model: model });
-      const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
-
-      grantType.getUserFromClient(request, {}).should.be.an.instanceOf(Promise);
-    });
-
-    it('should support non-promises', function() {
-      const user = { email: 'foo@bar.com' };
-      const model = {
-        getUserFromClient: function() {return user; },
+        getUserFromClient: sinon.stub().returns(user),
         saveToken: function() {}
       };
       const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 120, model: model });
@@ -190,67 +169,40 @@ describe('ClientCredentialsGrantType integration', function() {
       grantType.getUserFromClient(request, {}).should.be.an.instanceOf(Promise);
     });
 
-    it('should support callbacks', function() {
-      const user = { email: 'foo@bar.com' };
-      const model = {
-        getUserFromClient: function(userId, callback) { callback(null, user); },
-        saveToken: function() {}
-      };
-      const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 120, model: model });
-      const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
-
-      grantType.getUserFromClient(request, {}).should.be.an.instanceOf(Promise);
-    });
   });
 
   describe('saveToken()', function() {
-    it('should save the token', function() {
-      const token = {};
-      const model = {
-        getUserFromClient: function() {},
-        saveToken: function() { return token; },
-        validateScope: function() { return 'foo'; }
-      };
-      const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 123, model: model });
 
-      return grantType.saveToken(token)
-        .then(function(data) {
-          data.should.equal(token);
-        })
-        .catch(should.fail);
-    });
+    it('should save the token', async function() {
 
-    it('should support promises', function() {
       const token = {};
+
       const model = {
-        getUserFromClient: function() {},
-        saveToken: function() { return Promise.resolve(token); }
+        getUserFromClient: sinon.stub().returns({}),
+        saveToken: sinon.stub().returns(token),
+        validateScope: sinon.stub().returns('foo')
       };
-      const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 123, model: model });
 
-      grantType.saveToken(token).should.be.an.instanceOf(Promise);
-    });
+      const grantType = new ClientCredentialsGrantType({
+        accessTokenLifetime: 123,
+        model: model
+      });
 
-    it('should support non-promises', function() {
-      const token = {};
-      const model = {
-        getUserFromClient: function() {},
-        saveToken: function() { return token; }
-      };
-      const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 123, model: model });
+      let res;
 
-      grantType.saveToken(token).should.be.an.instanceOf(Promise);
-    });
+      try {
+        res = await grantType.saveToken(token);
+      } catch (err) {
+        should.fail(err);
+      }
 
-    it('should support callbacks', function() {
-      const token = {};
-      const model = {
-        getUserFromClient: function() {},
-        saveToken: function(tokenToSave, client, user, callback) { callback(null, token); }
-      };
-      const grantType = new ClientCredentialsGrantType({ accessTokenLifetime: 123, model: model });
+      model.validateScope.callCount.should.equal(1);
+      model.saveToken.callCount.should.equal(1);
+      model.saveToken.firstCall.args.should.have.length(3);
+      res.should.equal(token);
 
-      grantType.saveToken(token).should.be.an.instanceOf(Promise);
     });
+
+
   });
 });
diff --git a/test/integration/grant-types/password-grant-type_test.js b/test/integration/grant-types/password-grant-type_test.js
index a8c4cda..3ea76e9 100644
--- a/test/integration/grant-types/password-grant-type_test.js
+++ b/test/integration/grant-types/password-grant-type_test.js
@@ -8,25 +8,31 @@ const InvalidArgumentError = require('../../../lib/errors/invalid-argument-error
 const InvalidGrantError = require('../../../lib/errors/invalid-grant-error');
 const InvalidRequestError = require('../../../lib/errors/invalid-request-error');
 const PasswordGrantType = require('../../../lib/grant-types/password-grant-type');
-const Promise = require('bluebird');
 const Request = require('../../../lib/request');
 const should = require('chai').should();
-
+const sinon = require('sinon');
 /**
  * Test `PasswordGrantType` integration.
  */
 
 describe('PasswordGrantType integration', function() {
+
   describe('constructor()', function() {
-    it('should throw an error if `model` is missing', function() {
-      try {
-        new PasswordGrantType();
 
+    it('should throw an error if `model` is missing', async function() {
+
+      let passwordGrantType;
+
+      try {
+        passwordGrantType = new PasswordGrantType();
         should.fail();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `model`');
       }
+
+      should.not.exist(passwordGrantType);
+
     });
 
     it('should throw an error if the model does not implement `getUser()`', function() {
@@ -57,47 +63,57 @@ describe('PasswordGrantType integration', function() {
   });
 
   describe('handle()', function() {
-    it('should throw an error if `request` is missing', function() {
+    it('should throw an error if `request` is missing', async function() {
+
       const model = {
         getUser: function() {},
         saveToken: function() {}
       };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
 
-      try {
-        grantType.handle();
+      const grantType = new PasswordGrantType({
+        accessTokenLifetime: 123,
+        model: model
+      });
 
-        should.fail();
+      let res;
+
+      try {
+        res = await grantType.handle();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `request`');
       }
+
+      should.not.exist(res);
+
     });
 
-    it('should throw an error if `client` is missing', function() {
+    it('should throw an error if `client` is missing', async function() {
       const model = {
         getUser: function() {},
         saveToken: function() {}
       };
       const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
 
-      try {
-        grantType.handle({});
+      let res;
 
-        should.fail();
+      try {
+        res = await grantType.handle({});
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `client`');
       }
+
+      should.not.exist(res);
     });
 
     it('should return a token', function() {
       const client = { id: 'foobar' };
       const token = {};
       const model = {
-        getUser: function() { return {}; },
-        saveToken: function() { return token; },
-        validateScope: function() { return 'baz'; }
+        getUser: sinon.stub().resolves({}),
+        saveToken: sinon.stub().resolves(token),
+        validateScope: sinon.stub().resolves('baz'),
       };
       const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
       const request = new Request({ body: { username: 'foo', password: 'bar', scope: 'baz' }, headers: {}, method: {}, query: {} });
@@ -109,117 +125,129 @@ describe('PasswordGrantType integration', function() {
         .catch(should.fail);
     });
 
-    it('should support promises', function() {
-      const client = { id: 'foobar' };
-      const token = {};
-      const model = {
-        getUser: function() { return {}; },
-        saveToken: function() { return Promise.resolve(token); }
-      };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { username: 'foo', password: 'bar' }, headers: {}, method: {}, query: {} });
-
-      grantType.handle(request, client).should.be.an.instanceOf(Promise);
-    });
 
-    it('should support non-promises', function() {
-      const client = { id: 'foobar' };
-      const token = {};
-      const model = {
-        getUser: function() { return {}; },
-        saveToken: function() { return token; }
-      };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { username: 'foo', password: 'bar' }, headers: {}, method: {}, query: {} });
+  });
 
-      grantType.handle(request, client).should.be.an.instanceOf(Promise);
-    });
+  describe('getUser()', function() {
+    it('should throw an error if the request body does not contain `username`', async function() {
 
-    it('should support callbacks', function() {
-      const client = { id: 'foobar' };
-      const token = {};
       const model = {
-        getUser: function(username, password, callback) { callback(null, {}); },
-        saveToken: function(tokenToSave, client, user, callback) { callback(null, token); }
+        getUser: sinon.stub().resolves({}),
+        saveToken: sinon.stub().resolves({}),
       };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { username: 'foo', password: 'bar' }, headers: {}, method: {}, query: {} });
 
-      grantType.handle(request, client).should.be.an.instanceOf(Promise);
-    });
-  });
+      const grantType = new PasswordGrantType({
+        accessTokenLifetime: 123,
+        model: model 
+      });
 
-  describe('getUser()', function() {
-    it('should throw an error if the request body does not contain `username`', function() {
-      const model = {
-        getUser: function() {},
-        saveToken: function() {}
-      };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
+      const request = new Request({
+        body: {},
+        headers: {},
+        method: {},
+        query: {}
+      });
 
-      try {
-        grantType.getUser(request);
+      let user;
 
-        should.fail();
+      try {
+        user = await grantType.getUser(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Missing parameter: `username`');
       }
+
+      should.not.exist(user);
+
     });
 
-    it('should throw an error if the request body does not contain `password`', function() {
+    it('should throw an error if the request body does not contain `password`', async function() {
+
       const model = {
-        getUser: function() {},
-        saveToken: function() {}
+        getUser: sinon.stub().resolves({}),
+        saveToken: sinon.stub().resolves({}),
       };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { username: 'foo' }, headers: {}, method: {}, query: {} });
-
+      const grantType = new PasswordGrantType({
+        accessTokenLifetime: 123,
+        model: model
+      });
+      const request = new Request({
+        body: { username: 'foo' },
+        headers: {},
+        method: {},
+        query: {}
+      });
+
+      let user;
       try {
-        grantType.getUser(request);
-
-        should.fail();
+        user = await grantType.getUser(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Missing parameter: `password`');
       }
+
+      should.not.exist(user);
     });
 
-    it('should throw an error if `username` is invalid', function() {
+    it('should throw an error if `username` is invalid', async function() {
+
       const model = {
-        getUser: function() {},
-        saveToken: function() {}
+        getUser: sinon.stub().resolves({}),
+        saveToken: sinon.stub().resolves({}),
       };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { username: '\r\n', password: 'foobar' }, headers: {}, method: {}, query: {} });
-
+      const grantType = new PasswordGrantType({
+        accessTokenLifetime: 123,
+        model: model
+      });
+      const request = new Request({
+        body: { 
+          password: 'foobar',
+          username: '\r\n', 
+        },
+        headers: {},
+        method: {},
+        query: {}
+      });
+
+      let user;
       try {
-        grantType.getUser(request);
-
-        should.fail();
+        user = await grantType.getUser(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Invalid parameter: `username`');
       }
+      should.not.exist(user);
     });
 
-    it('should throw an error if `password` is invalid', function() {
+    it('should throw an error if `password` is invalid', async function() {
       const model = {
-        getUser: function() {},
-        saveToken: function() {}
+        getUser: sinon.stub().resolves({}),
+        saveToken: sinon.stub().resolves({}),
       };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { username: 'foobar', password: '\r\n' }, headers: {}, method: {}, query: {} });
+      const grantType = new PasswordGrantType({
+        accessTokenLifetime: 123,
+        model: model
+      });
+      const request = new Request({
+        body: {
+          username: 'foobar',
+          password: '\r\n'
+        },
+        headers: {},
+        method: {},
+        query: {}
+      });
+
+      let user;
 
       try {
-        grantType.getUser(request);
-
-        should.fail();
+        user = await grantType.getUser(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Invalid parameter: `password`');
       }
+      should.not.exist(user);
+
     });
 
     it('should throw an error if `user` is missing', function() {
@@ -254,91 +282,38 @@ describe('PasswordGrantType integration', function() {
         .catch(should.fail);
     });
 
-    it('should support promises', function() {
-      const user = { email: 'foo@bar.com' };
-      const model = {
-        getUser: function() { return Promise.resolve(user); },
-        saveToken: function() {}
-      };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { username: 'foo', password: 'bar' }, headers: {}, method: {}, query: {} });
-
-      grantType.getUser(request).should.be.an.instanceOf(Promise);
-    });
-
-    it('should support non-promises', function() {
-      const user = { email: 'foo@bar.com' };
-      const model = {
-        getUser: function() { return user; },
-        saveToken: function() {}
-      };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { username: 'foo', password: 'bar' }, headers: {}, method: {}, query: {} });
-
-      grantType.getUser(request).should.be.an.instanceOf(Promise);
-    });
-
-    it('should support callbacks', function() {
-      const user = { email: 'foo@bar.com' };
-      const model = {
-        getUser: function(username, password, callback) { callback(null, user); },
-        saveToken: function() {}
-      };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { username: 'foo', password: 'bar' }, headers: {}, method: {}, query: {} });
 
-      grantType.getUser(request).should.be.an.instanceOf(Promise);
-    });
   });
 
   describe('saveToken()', function() {
-    it('should save the token', function() {
-      const token = {};
-      const model = {
-        getUser: function() {},
-        saveToken: function() { return token; },
-        validateScope: function() { return 'foo'; }
-      };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
 
-      return grantType.saveToken(token)
-        .then(function(data) {
-          data.should.equal(token);
-        })
-        .catch(should.fail);
-    });
+    it('should save the token', async function() {
 
-    it('should support promises', function() {
       const token = {};
+
       const model = {
-        getUser: function() {},
-        saveToken: function() { return Promise.resolve(token); }
+        getUser: sinon.stub().resolves({}),
+        saveToken: sinon.stub().resolves(token),
+        validateScope: sinon.stub().resolves('foo'),
       };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
 
-      grantType.saveToken(token).should.be.an.instanceOf(Promise);
-    });
+      const grantType = new PasswordGrantType({ 
+        accessTokenLifetime: 123,
+        model: model
+      });
 
-    it('should support non-promises', function() {
-      const token = {};
-      const model = {
-        getUser: function() {},
-        saveToken: function() { return token; }
-      };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
+      let res;
+
+      try {
+        res = await grantType.saveToken(token);
+      } catch (err) {
+        should.fail(err);
+      }
+      should.exist(res);
+      res.should.equal(token);
 
-      grantType.saveToken(token).should.be.an.instanceOf(Promise);
     });
 
-    it('should support callbacks', function() {
-      const token = {};
-      const model = {
-        getUser: function() {},
-        saveToken: function(tokenToSave, client, user, callback) { callback(null, token); }
-      };
-      const grantType = new PasswordGrantType({ accessTokenLifetime: 123, model: model });
 
-      grantType.saveToken(token).should.be.an.instanceOf(Promise);
-    });
   });
 });
diff --git a/test/integration/grant-types/refresh-token-grant-type_test.js b/test/integration/grant-types/refresh-token-grant-type_test.js
index 945d51c..8a05ba3 100644
--- a/test/integration/grant-types/refresh-token-grant-type_test.js
+++ b/test/integration/grant-types/refresh-token-grant-type_test.js
@@ -7,92 +7,113 @@
 const InvalidArgumentError = require('../../../lib/errors/invalid-argument-error');
 const InvalidGrantError = require('../../../lib/errors/invalid-grant-error');
 const InvalidRequestError = require('../../../lib/errors/invalid-request-error');
-const Promise = require('bluebird');
 const RefreshTokenGrantType = require('../../../lib/grant-types/refresh-token-grant-type');
 const Request = require('../../../lib/request');
 const ServerError = require('../../../lib/errors/server-error');
 const should = require('chai').should();
-
+const sinon = require('sinon');
 /**
  * Test `RefreshTokenGrantType` integration.
  */
 
 describe('RefreshTokenGrantType integration', function() {
+
   describe('constructor()', function() {
+
     it('should throw an error if `model` is missing', function() {
-      try {
-        new RefreshTokenGrantType();
 
-        should.fail();
+      let refreshTokenGrantType;
+
+      try {
+        refreshTokenGrantType = new RefreshTokenGrantType();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `model`');
       }
+
+      should.not.exist(refreshTokenGrantType);
+
     });
 
     it('should throw an error if the model does not implement `getRefreshToken()`', function() {
-      try {
-        new RefreshTokenGrantType({ model: {} });
 
-        should.fail();
+      let refreshTokenGrantType;
+
+      try {
+        refreshTokenGrantType = new RefreshTokenGrantType({ model: {} });
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: model does not implement `getRefreshToken()`');
       }
+      should.not.exist(refreshTokenGrantType);
+
     });
 
     it('should throw an error if the model does not implement `revokeToken()`', function() {
-      try {
-        const model = {
-          getRefreshToken: function() {}
-        };
-
-        new RefreshTokenGrantType({ model: model });
+      
+      let refreshTokenGrantType;
 
-        should.fail();
+      try {
+        refreshTokenGrantType = new RefreshTokenGrantType({
+          model: {
+            getRefreshToken: function() {}
+          } 
+        });
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: model does not implement `revokeToken()`');
       }
+      should.not.exist(refreshTokenGrantType);
     });
 
     it('should throw an error if the model does not implement `saveToken()`', function() {
-      try {
-        const model = {
-          getRefreshToken: function() {},
-          revokeToken: function() {}
-        };
 
-        new RefreshTokenGrantType({ model: model });
+      let refreshTokenGrantType;
 
-        should.fail();
+      try {
+        refreshTokenGrantType = new RefreshTokenGrantType({ 
+          model: {
+            getRefreshToken: function() {},
+            revokeToken: function() {}
+          }
+        });
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: model does not implement `saveToken()`');
       }
+
+      should.not.exist(refreshTokenGrantType);
+
     });
   });
 
   describe('handle()', function() {
-    it('should throw an error if `request` is missing', function() {
+
+    it('should throw an error if `request` is missing', async function() {
+
       const model = {
         getRefreshToken: function() {},
         revokeToken: function() {},
         saveToken: function() {}
       };
+
       const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model: model });
 
-      try {
-        grantType.handle();
+      let res;
 
-        should.fail();
+      try {
+        res = await grantType.handle();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `request`');
       }
+
+      should.not.exist(res);
+
     });
 
-    it('should throw an error if `client` is missing', function() {
+    it('should throw an error if `client` is missing', async function() {
+
       const model = {
         getRefreshToken: function() {},
         revokeToken: function() {},
@@ -100,18 +121,21 @@ describe('RefreshTokenGrantType integration', function() {
       };
       const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model: model });
       const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
+      let res;
 
       try {
-        grantType.handle(request);
-
-        should.fail();
+        res = await grantType.handle(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `client`');
       }
+
+      should.not.exist(res);
+
     });
 
     it('should return a token', function() {
+
       const client = { id: 123 };
       const token = { accessToken: 'foo', client: { id: 123 }, user: {} };
       const model = {
@@ -129,83 +153,65 @@ describe('RefreshTokenGrantType integration', function() {
         .catch(should.fail);
     });
 
-    it('should support promises', function() {
-      const client = { id: 123 };
-      const model = {
-        getRefreshToken: function() { return Promise.resolve({ accessToken: 'foo', client: { id: 123 }, user: {} }); },
-        revokeToken: function() { return Promise.resolve({ accessToken: 'foo', client: {}, refreshTokenExpiresAt: new Date(new Date() / 2), user: {} }); },
-        saveToken: function() { return Promise.resolve({ accessToken: 'foo', client: {}, user: {} }); }
-      };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { refresh_token: 'foobar' }, headers: {}, method: {}, query: {} });
-
-      grantType.handle(request, client).should.be.an.instanceOf(Promise);
-    });
-
-    it('should support non-promises', function() {
-      const client = { id: 123 };
-      const model = {
-        getRefreshToken: function() { return { accessToken: 'foo', client: { id: 123 }, user: {} }; },
-        revokeToken: function() { return { accessToken: 'foo', client: {}, refreshTokenExpiresAt: new Date(new Date() / 2), user: {} }; },
-        saveToken: function() { return { accessToken: 'foo', client: {}, user: {} }; }
-      };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { refresh_token: 'foobar' }, headers: {}, method: {}, query: {} });
-
-      grantType.handle(request, client).should.be.an.instanceOf(Promise);
-    });
-
-    it('should support callbacks', function() {
-      const client = { id: 123 };
-      const model = {
-        getRefreshToken: function(refreshToken, callback) { callback(null, { accessToken: 'foo', client: { id: 123 }, user: {} }); },
-        revokeToken: function(refreshToken, callback) { callback(null, { accessToken: 'foo', client: {}, refreshTokenExpiresAt: new Date(new Date() / 2), user: {} }); },
-        saveToken: function(tokenToSave, client, user, callback) { callback(null,{ accessToken: 'foo', client: {}, user: {} }); }
-      };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { refresh_token: 'foobar' }, headers: {}, method: {}, query: {} });
-
-      grantType.handle(request, client).should.be.an.instanceOf(Promise);
-    });
   });
 
   describe('getRefreshToken()', function() {
-    it('should throw an error if the `refreshToken` parameter is missing from the request body', function() {
+
+    it('should throw an error if the `refreshToken` parameter is missing from the request body', async function() {
+
       const client = {};
       const model = {
-        getRefreshToken: function() {},
-        revokeToken: function() {},
-        saveToken: function() {}
+        getRefreshToken: sinon.stub().resolves({}),
+        revokeToken: sinon.stub().resolves({}),
+        saveToken: sinon.stub().resolves({})
       };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model: model });
-      const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
+      const grantType = new RefreshTokenGrantType({
+        accessTokenLifetime: 120,
+        model: model
+      });
+      
+      const request = new Request({
+        body: {},
+        headers: {},
+        method: {},
+        query: {}
+      });
+
+      let res;
 
       try {
-        grantType.getRefreshToken(request, client);
-
-        should.fail();
-      } catch (e) {
-        e.should.be.an.instanceOf(InvalidRequestError);
-        e.message.should.equal('Missing parameter: `refresh_token`');
+        res = await grantType.getRefreshToken(request, client);
+      } catch (err) {
+        err.should.be.an.instanceOf(InvalidRequestError);
+        err.message.should.equal('Missing parameter: `refresh_token`');
       }
+
+      should.not.exist(res);
+
     });
 
-    it('should throw an error if `refreshToken` is not found', function() {
+    it('should throw an error if `refreshToken` is not found', async function() {
+
       const client = { id: 123 };
       const model = {
-        getRefreshToken: function() { return; },
-        revokeToken: function() {},
-        saveToken: function() {}
+        getRefreshToken: sinon.stub().resolves(null),
+        revokeToken: sinon.stub().resolves({}),
+        saveToken: sinon.stub().resolves({})
       };
       const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model: model });
       const request = new Request({ body: { refresh_token: '12345' }, headers: {}, method: {}, query: {} });
 
-      return grantType.getRefreshToken(request, client)
-        .then(should.fail)
-        .catch(function(e) {
-          e.should.be.an.instanceOf(InvalidGrantError);
-          e.message.should.equal('Invalid grant: refresh token is invalid');
-        });
+      let res;
+
+      try {
+        res = await grantType.getRefreshToken(request, client);
+      } catch (err) {
+        err.should.be.an.instanceOf(InvalidGrantError);
+        err.message.should.equal('Invalid grant: refresh token is invalid');
+      }
+
+      should.not.exist(res);
+
     });
 
     it('should throw an error if `refreshToken.client` is missing', function() {
@@ -266,7 +272,7 @@ describe('RefreshTokenGrantType integration', function() {
         });
     });
 
-    it('should throw an error if `refresh_token` contains invalid characters', function() {
+    it('should throw an error if `refresh_token` contains invalid characters', async function() {
       const client = {};
       const model = {
         getRefreshToken: function() {
@@ -278,14 +284,17 @@ describe('RefreshTokenGrantType integration', function() {
       const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model: model });
       const request = new Request({ body: { refresh_token: 'øå€£‰' }, headers: {}, method: {}, query: {} });
 
-      try {
-        grantType.getRefreshToken(request, client);
+      let token;
 
-        should.fail();
+      try {
+        token  = await grantType.getRefreshToken(request, client);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Invalid parameter: `refresh_token`');
       }
+
+      should.not.exist(token);
+
     });
 
     it('should throw an error if `refresh_token` is missing', function() {
@@ -367,95 +376,33 @@ describe('RefreshTokenGrantType integration', function() {
         .catch(should.fail);
     });
 
-    it('should support promises', function() {
-      const client = { id: 123 };
-      const token = { accessToken: 'foo', client: { id: 123 }, user: {} };
-      const model = {
-        getRefreshToken: function() { return Promise.resolve(token); },
-        revokeToken: function() {},
-        saveToken: function() {}
-      };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { refresh_token: 'foobar' }, headers: {}, method: {}, query: {} });
-
-      grantType.getRefreshToken(request, client).should.be.an.instanceOf(Promise);
-    });
-
-    it('should support non-promises', function() {
-      const client = { id: 123 };
-      const token = { accessToken: 'foo', client: { id: 123 }, user: {} };
-      const model = {
-        getRefreshToken: function() { return token; },
-        revokeToken: function() {},
-        saveToken: function() {}
-      };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { refresh_token: 'foobar' }, headers: {}, method: {}, query: {} });
-
-      grantType.getRefreshToken(request, client).should.be.an.instanceOf(Promise);
-    });
-
-    it('should support callbacks', function() {
-      const client = { id: 123 };
-      const token = { accessToken: 'foo', client: { id: 123 }, user: {} };
-      const model = {
-        getRefreshToken: function(refreshToken, callback) { callback(null, token); },
-        revokeToken: function() {},
-        saveToken: function() {}
-      };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
-      const request = new Request({ body: { refresh_token: 'foobar' }, headers: {}, method: {}, query: {} });
-
-      grantType.getRefreshToken(request, client).should.be.an.instanceOf(Promise);
-    });
   });
 
   describe('revokeToken()', function() {
-    it('should throw an error if the `token` is invalid', function() {
+
+    it('should throw an error if the `token` is invalid', async function() {
       const model = {
         getRefreshToken: function() {},
         revokeToken: function() {},
         saveToken: function() {}
       };
       const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 120, model: model });
+      
+      let res;
 
-      grantType.revokeToken({})
-        .then(should.fail)
-        .catch(function (e) {
-          e.should.be.an.instanceOf(InvalidGrantError);
-          e.message.should.equal('Invalid grant: refresh token is invalid');
-        });
-    });
+      try {
+        res = await grantType.revokeToken({});
+      } catch (err) {
+        err.should.be.an.instanceOf(InvalidGrantError);
+        err.message.should.equal('Invalid grant: refresh token is invalid');
+      }
 
-    it('should revoke the token', function() {
-      const token = { accessToken: 'foo', client: {}, refreshTokenExpiresAt: new Date(new Date() / 2), user: {} };
-      const model = {
-        getRefreshToken: function() {},
-        revokeToken: function() { return token; },
-        saveToken: function() {}
-      };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
+      should.not.exist(res);
+      
 
-      return grantType.revokeToken(token)
-        .then(function(data) {
-          data.should.equal(token);
-        })
-        .catch(should.fail);
     });
 
-    it('should support promises', function() {
-      const token = { accessToken: 'foo', client: {}, refreshTokenExpiresAt: new Date(new Date() / 2), user: {} };
-      const model = {
-        getRefreshToken: function() {},
-        revokeToken: function() { return Promise.resolve(token); },
-        saveToken: function() {}
-      };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
-
-      grantType.revokeToken(token).should.be.an.instanceOf(Promise);
-    });
-
-    it('should support non-promises', function() {
+    it('should revoke the token', async function() {
       const token = { accessToken: 'foo', client: {}, refreshTokenExpiresAt: new Date(new Date() / 2), user: {} };
       const model = {
         getRefreshToken: function() {},
@@ -463,53 +410,24 @@ describe('RefreshTokenGrantType integration', function() {
         saveToken: function() {}
       };
       const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
+      
+      let res;
 
-      grantType.revokeToken(token).should.be.an.instanceOf(Promise);
-    });
-
-    it('should support callbacks', function() {
-      const token = { accessToken: 'foo', client: {}, refreshTokenExpiresAt: new Date(new Date() / 2), user: {} };
-      const model = {
-        getRefreshToken: function() {},
-        revokeToken: function(refreshToken, callback) { callback(null, token); },
-        saveToken: function() {}
-      };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
+      try {
+        res = await grantType.revokeToken(token);
+      } catch (err) {
+        should.fail(err);
+      }
+      
+      res.should.equal(token);
 
-      grantType.revokeToken(token).should.be.an.instanceOf(Promise);
     });
+
   });
 
   describe('saveToken()', function() {
-    it('should save the token', function() {
-      const token = {};
-      const model = {
-        getRefreshToken: function() {},
-        revokeToken: function() {},
-        saveToken: function() { return token; }
-      };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
 
-      return grantType.saveToken(token)
-        .then(function(data) {
-          data.should.equal(token);
-        })
-        .catch(should.fail);
-    });
-
-    it('should support promises', function() {
-      const token = {};
-      const model = {
-        getRefreshToken: function() {},
-        revokeToken: function() {},
-        saveToken: function() { return Promise.resolve(token); }
-      };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
-
-      grantType.saveToken(token).should.be.an.instanceOf(Promise);
-    });
-
-    it('should support non-promises', function() {
+    it('should save the token', async function() {
       const token = {};
       const model = {
         getRefreshToken: function() {},
@@ -517,20 +435,19 @@ describe('RefreshTokenGrantType integration', function() {
         saveToken: function() { return token; }
       };
       const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
+      
+      let res;
 
-      grantType.saveToken(token).should.be.an.instanceOf(Promise);
-    });
+      try {
+        res = await grantType.saveToken(token);
+      } catch (err) {
+        should.fail(err);
+      }
 
-    it('should support callbacks', function() {
-      const token = {};
-      const model = {
-        getRefreshToken: function() {},
-        revokeToken: function() {},
-        saveToken: function(tokenToSave, client, user, callback) { callback(null, token); }
-      };
-      const grantType = new RefreshTokenGrantType({ accessTokenLifetime: 123, model: model });
+      res.should.equal(token);
 
-      grantType.saveToken(token).should.be.an.instanceOf(Promise);
     });
+
   });
+
 });
diff --git a/test/integration/handlers/authenticate-handler_test.js b/test/integration/handlers/authenticate-handler_test.js
index 3e0eefd..777dbe9 100644
--- a/test/integration/handlers/authenticate-handler_test.js
+++ b/test/integration/handlers/authenticate-handler_test.js
@@ -10,86 +10,125 @@ const InvalidArgumentError = require('../../../lib/errors/invalid-argument-error
 const InvalidRequestError = require('../../../lib/errors/invalid-request-error');
 const InsufficientScopeError = require('../../../lib/errors/insufficient-scope-error');
 const InvalidTokenError = require('../../../lib/errors/invalid-token-error');
-const Promise = require('bluebird');
+// const Promise = require('bluebird');
 const Request = require('../../../lib/request');
 const Response = require('../../../lib/response');
 const ServerError = require('../../../lib/errors/server-error');
 const UnauthorizedRequestError = require('../../../lib/errors/unauthorized-request-error');
 const should = require('chai').should();
+const sinon = require('sinon');
 
 /**
  * Test `AuthenticateHandler` integration.
  */
 
 describe('AuthenticateHandler integration', function() {
+
   describe('constructor()', function() {
+
     it('should throw an error if `options.model` is missing', function() {
-      try {
-        new AuthenticateHandler();
 
-        should.fail();
+      let authenticateHandler;
+
+      try {
+        authenticateHandler = new AuthenticateHandler();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `model`');
       }
+
+      should.not.exist(authenticateHandler);
+
     });
 
     it('should throw an error if the model does not implement `getAccessToken()`', function() {
-      try {
-        new AuthenticateHandler({ model: {} });
 
-        should.fail();
+      let authenticateHandler;
+
+      try {
+        authenticateHandler = new AuthenticateHandler({ model: {} });
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: model does not implement `getAccessToken()`');
       }
+
+      should.not.exist(authenticateHandler);
+
     });
 
     it('should throw an error if `scope` was given and `addAcceptedScopesHeader()` is missing', function() {
-      try {
-        new AuthenticateHandler({ model: { getAccessToken: function() {} }, scope: 'foobar' });
 
-        should.fail();
+      let authenticateHandler;
+
+      try {
+        authenticateHandler = new AuthenticateHandler({
+          model: { getAccessToken: function() {} },
+          scope: 'foobar'
+        });
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `addAcceptedScopesHeader`');
       }
+
+      should.not.exist(authenticateHandler);
+
     });
 
     it('should throw an error if `scope` was given and `addAuthorizedScopesHeader()` is missing', function() {
+      let authenticateHandler;
+      
       try {
-        new AuthenticateHandler({ addAcceptedScopesHeader: true, model: { getAccessToken: function() {} }, scope: 'foobar' });
-
-        should.fail();
+        authenticateHandler = new AuthenticateHandler({
+          addAcceptedScopesHeader: true,
+          model: { getAccessToken: function() {} },
+          scope: 'foobar'
+        });
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `addAuthorizedScopesHeader`');
       }
+
+      should.not.exist(authenticateHandler);
+
     });
 
     it('should throw an error if `scope` was given and the model does not implement `verifyScope()`', function() {
-      try {
-        new AuthenticateHandler({ addAcceptedScopesHeader: true, addAuthorizedScopesHeader: true, model: { getAccessToken: function() {} }, scope: 'foobar' });
 
-        should.fail();
+      let authenticateHandler;
+
+      try {
+        authenticateHandler = new AuthenticateHandler({
+          addAcceptedScopesHeader: true,
+          addAuthorizedScopesHeader: true,
+          model: {
+            getAccessToken: function() {}
+          },
+          scope: 'foobar' 
+        });
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: model does not implement `verifyScope()`');
       }
+
+      should.not.exist(authenticateHandler);
+
     });
 
     it('should set the `model`', function() {
+
       const model = { getAccessToken: function() {} };
       const grantType = new AuthenticateHandler({ model: model });
-
       grantType.model.should.equal(model);
+
     });
 
     it('should set the `scope`', function() {
+
       const model = {
         getAccessToken: function() {},
         verifyScope: function() {}
       };
+
       const grantType = new AuthenticateHandler({
         addAcceptedScopesHeader: true,
         addAuthorizedScopesHeader: true,
@@ -98,24 +137,34 @@ describe('AuthenticateHandler integration', function() {
       });
 
       grantType.scope.should.equal('foobar');
+
     });
+
   });
 
   describe('handle()', function() {
-    it('should throw an error if `request` is missing', function() {
-      const handler = new AuthenticateHandler({ model: { getAccessToken: function() {} } });
 
-      try {
-        handler.handle();
+    it('should throw an error if `request` is missing', async function() {
+
+      const handler = new AuthenticateHandler({
+        model: { getAccessToken: function() {} } 
+      });
+
+      let res;
 
-        should.fail();
+      try {
+        res = await handler.handle();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: `request` must be an instance of Request');
       }
+
+      should.not.exist(res);
+
     });
 
     it('should set the `WWW-Authenticate` header if an unauthorized request error is thrown', function() {
+
       const model = {
         getAccessToken: function() {
           throw new UnauthorizedRequestError();
@@ -130,32 +179,38 @@ describe('AuthenticateHandler integration', function() {
         .catch(function() {
           response.get('WWW-Authenticate').should.equal('Bearer realm="Service"');
         });
+
     });
 
     it('should throw the error if an oauth error is thrown', function() {
+
       const model = {
         getAccessToken: function() {
           throw new AccessDeniedError('Cannot request this access token');
         }
       };
+
       const handler = new AuthenticateHandler({ model: model });
       const request = new Request({ body: {}, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: {} });
       const response = new Response({ body: {}, headers: {} });
 
       return handler.handle(request, response)
         .then(should.fail)
-        .catch(function(e) {
+        .catch( function(e) {
           e.should.be.an.instanceOf(AccessDeniedError);
           e.message.should.equal('Cannot request this access token');
         });
+
     });
 
     it('should throw a server error if a non-oauth error is thrown', function() {
+
       const model = {
         getAccessToken: function() {
           throw new Error('Unhandled exception');
         }
       };
+
       const handler = new AuthenticateHandler({ model: model });
       const request = new Request({ body: {}, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: {} });
       const response = new Response({ body: {}, headers: {} });
@@ -166,41 +221,60 @@ describe('AuthenticateHandler integration', function() {
           e.should.be.an.instanceOf(ServerError);
           e.message.should.equal('Unhandled exception');
         });
+
     });
 
-    it('should return an access token', function() {
+    it('should return an access token', async function() {
+
       const accessToken = {
-        user: {},
+        user: {id: 123},
         accessTokenExpiresAt: new Date(new Date().getTime() + 10000)
       };
-      const model = {
-        getAccessToken: function() {
-          return accessToken;
+
+      const authenticateHandler = new AuthenticateHandler({
+        addAcceptedScopesHeader: true,
+        addAuthorizedScopesHeader: true,
+        model: {
+          getAccessToken: sinon.stub().resolves(accessToken),
+          verifyScope: sinon.stub().resolves(true)
         },
-        verifyScope: function() {
-          return true;
-        }
-      };
-      const handler = new AuthenticateHandler({ addAcceptedScopesHeader: true, addAuthorizedScopesHeader: true, model: model, scope: 'foo' });
+        scope: 'foo'
+      });
+
       const request = new Request({
         body: {},
         headers: { 'Authorization': 'Bearer foo' },
         method: {},
         query: {}
       });
-      const response = new Response({ body: {}, headers: {} });
 
-      return handler.handle(request, response)
-        .then(function(data) {
-          data.should.equal(accessToken);
-        })
-        .catch(should.fail);
+      const response = new Response({
+        body: {},
+        headers: {}
+      });
+
+      let res;
+
+      try {
+        res = await authenticateHandler.handle(request, response);
+      } catch (err) {
+        should.fail(err.stack);
+      }
+      should.exist(res);
+      res.should.equal(accessToken);
+
     });
+
   });
 
   describe('getTokenFromRequest()', function() {
-    it('should throw an error if more than one authentication method is used', function() {
-      const handler = new AuthenticateHandler({ model: { getAccessToken: function() {} } });
+
+    it('should throw an error if more than one authentication method is used', async function() {
+
+      const handler = new AuthenticateHandler({
+        model: { getAccessToken: function() {} }
+      });
+
       const request = new Request({
         body: {},
         headers: { 'Authorization': 'Bearer foo' },
@@ -208,94 +282,175 @@ describe('AuthenticateHandler integration', function() {
         query: { access_token: 'foo' }
       });
 
-      try {
-        handler.getTokenFromRequest(request);
+      let token;
 
-        should.fail();
+      try {
+        token = await handler.getTokenFromRequest(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Invalid request: only one authentication method is allowed');
       }
+
+      should.not.exist(token);
+
     });
 
-    it('should throw an error if `accessToken` is missing', function() {
-      const handler = new AuthenticateHandler({ model: { getAccessToken: function() {} } });
-      const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
+    it('should throw an error if `accessToken` is missing', async function() {
 
-      try {
-        handler.getTokenFromRequest(request);
+      const handler = new AuthenticateHandler({
+        model: {
+          getAccessToken: function() {}
+        }
+      });
+      
+      const request = new Request({
+        body: {},
+        headers: {},
+        method: {},
+        query: {}
+      });
+
+      let token;
 
-        should.fail();
+      try {
+        token = await handler.getTokenFromRequest(request);
       } catch (e) {
         e.should.be.an.instanceOf(UnauthorizedRequestError);
         e.message.should.equal('Unauthorized request: no authentication given');
       }
+
+      should.not.exist(token);
     });
   });
 
   describe('getTokenFromRequestHeader()', function() {
-    it('should throw an error if the token is malformed', function() {
-      const handler = new AuthenticateHandler({ model: { getAccessToken: function() {} } });
+
+    it('should throw an error if the token is malformed', async function() {
+
+
+      const handler = new AuthenticateHandler({
+        model: {
+          getAccessToken: function() {}
+        }
+      }); 
+
+      const authHeaderValue = 'foobar';
+
       const request = new Request({
         body: {},
         headers: {
-          'Authorization': 'foobar'
+          'Authorization': authHeaderValue
         },
         method: {},
         query: {}
       });
 
-      try {
-        handler.getTokenFromRequestHeader(request);
+      let token;
 
-        should.fail();
+      try {
+        token = await handler.getTokenFromRequestHeader(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Invalid request: malformed authorization header');
       }
+
+      should.not.exist(token);
+
     });
 
-    it('should return the bearer token', function() {
-      const handler = new AuthenticateHandler({ model: { getAccessToken: function() {} } });
+    it('should return the bearer token', async function() {
+
+      const token = 'foo';
+
+      const handler = new AuthenticateHandler({
+        model: {
+          getAccessToken: function() {}
+        }
+      });
+
       const request = new Request({
         body: {},
         headers: {
-          'Authorization': 'Bearer foo'
+          'Authorization': `Bearer ${token}`
         },
         method: {},
         query: {}
       });
 
-      const bearerToken = handler.getTokenFromRequestHeader(request);
+      let bearerToken;
+
+      try {
+        bearerToken = await handler.getTokenFromRequestHeader(request);
+      } catch (err) {
+        should.fail(err.stack);
+      }
+
+      should.exist(bearerToken);
+      bearerToken.should.equal(token);
 
-      bearerToken.should.equal('foo');
     });
+
   });
 
   describe('getTokenFromRequestQuery()', function() {
-    it('should throw an error if the query contains a token', function() {
-      const handler = new AuthenticateHandler({ model: { getAccessToken: function() {} } });
 
-      try {
-        handler.getTokenFromRequestQuery();
+    it('should throw an error if the query contains a token', async function() {
+
+      const handler = new AuthenticateHandler({
+        model: {
+          getAccessToken: function() {}
+        }
+      });
 
-        should.fail();
+      let token;
+
+      try {
+        token = await handler.getTokenFromRequestQuery();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Invalid request: do not send bearer tokens in query URLs');
       }
+
+      should.not.exist(token);
+
     });
 
-    it('should return the bearer token if `allowBearerTokensInQueryString` is true', function() {
-      const handler = new AuthenticateHandler({ allowBearerTokensInQueryString: true, model: { getAccessToken: function() {} } });
+    it('should return the bearer token if `allowBearerTokensInQueryString` is true', async function() {
+
+      const query = {
+        access_token: 'foo'
+      };
 
-      handler.getTokenFromRequestQuery({ query: { access_token: 'foo' } }).should.equal('foo');
+      const handler = new AuthenticateHandler({
+        allowBearerTokensInQueryString: true,
+        model: {
+          getAccessToken: function() {}
+        }
+      });
+
+      let token;
+
+      try {
+        token = await handler.getTokenFromRequestQuery({query: query});
+      } catch (err) {
+        should.fail(err.stack);
+      }
+
+      should.exist(token);
+      token.should.equal(query.access_token);
     });
   });
 
   describe('getTokenFromRequestBody()', function() {
-    it('should throw an error if the method is `GET`', function() {
-      const handler = new AuthenticateHandler({ model: { getAccessToken: function() {} } });
+
+    it('should throw an error if the method is `GET`', async function() {
+
+      const handler = new AuthenticateHandler({
+        model: {
+          getAccessToken: function() {}
+        }
+      });
+
       const request = new Request({
         body: { access_token: 'foo' },
         headers: {},
@@ -303,18 +458,27 @@ describe('AuthenticateHandler integration', function() {
         query: {}
       });
 
-      try {
-        handler.getTokenFromRequestBody(request);
+      let token;
 
-        should.fail();
+      try {
+        token = await handler.getTokenFromRequestBody(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Invalid request: token may not be passed in the body when using the GET verb');
       }
+
+      should.not.exist(token);
+
     });
 
-    it('should throw an error if the media type is not `application/x-www-form-urlencoded`', function() {
-      const handler = new AuthenticateHandler({ model: { getAccessToken: function() {} } });
+    it('should throw an error if the media type is not `application/x-www-form-urlencoded`', async function() {
+
+      const handler = new AuthenticateHandler({
+        model: {
+          getAccessToken: function() {}
+        }
+      });
+
       const request = new Request({
         body: { access_token: 'foo' },
         headers: {},
@@ -322,31 +486,59 @@ describe('AuthenticateHandler integration', function() {
         query: {}
       });
 
-      try {
-        handler.getTokenFromRequestBody(request);
+      let token;
 
-        should.fail();
+      try {
+        token = await handler.getTokenFromRequestBody(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Invalid request: content must be application/x-www-form-urlencoded');
       }
+
+      should.not.exist(token);
+
     });
 
-    it('should return the bearer token', function() {
-      const handler = new AuthenticateHandler({ model: { getAccessToken: function() {} } });
+    it('should return the bearer token', async function() {
+
+      const body = {
+        access_token: 'foo'
+      };
+
+      const handler = new AuthenticateHandler({
+        model: {
+          getAccessToken: function() {}
+        }
+      });
+
       const request = new Request({
-        body: { access_token: 'foo' },
-        headers: { 'content-type': 'application/x-www-form-urlencoded', 'transfer-encoding': 'chunked' },
+        body: body,
+        headers: {
+          'content-type': 'application/x-www-form-urlencoded',
+          'transfer-encoding': 'chunked'
+        },
         method: {},
         query: {}
       });
 
-      handler.getTokenFromRequestBody(request).should.equal('foo');
+      let token;
+
+      try {
+        token = await handler.getTokenFromRequestBody(request);
+      } catch (err) {
+        should.fail(err.stack);
+      }
+
+      should.exist(token);
+      token.should.equal(body.access_token);
+
     });
   });
 
   describe('getAccessToken()', function() {
+
     it('should throw an error if `accessToken` is missing', function() {
+
       const model = {
         getAccessToken: function() {}
       };
@@ -358,14 +550,17 @@ describe('AuthenticateHandler integration', function() {
           e.should.be.an.instanceOf(InvalidTokenError);
           e.message.should.equal('Invalid token: access token is invalid');
         });
+
     });
 
     it('should throw an error if `accessToken.user` is missing', function() {
+
       const model = {
         getAccessToken: function() {
           return {};
         }
       };
+
       const handler = new AuthenticateHandler({ model: model });
 
       return handler.getAccessToken('foo')
@@ -374,15 +569,19 @@ describe('AuthenticateHandler integration', function() {
           e.should.be.an.instanceOf(ServerError);
           e.message.should.equal('Server error: `getAccessToken()` did not return a `user` object');
         });
+
     });
 
     it('should return an access token', function() {
+
       const accessToken = { user: {} };
+
       const model = {
         getAccessToken: function() {
           return accessToken;
         }
       };
+
       const handler = new AuthenticateHandler({ model: model });
 
       return handler.getAccessToken('foo')
@@ -390,77 +589,79 @@ describe('AuthenticateHandler integration', function() {
           data.should.equal(accessToken);
         })
         .catch(should.fail);
-    });
-
-    it('should support promises', function() {
-      const model = {
-        getAccessToken: function() {
-          return Promise.resolve({ user: {} });
-        }
-      };
-      const handler = new AuthenticateHandler({ model: model });
 
-      handler.getAccessToken('foo').should.be.an.instanceOf(Promise);
     });
 
-    it('should support non-promises', function() {
-      const model = {
-        getAccessToken: function() {
-          return { user: {} };
-        }
-      };
-      const handler = new AuthenticateHandler({ model: model });
-
-      handler.getAccessToken('foo').should.be.an.instanceOf(Promise);
-    });
 
-    it('should support callbacks', function() {
-      const model = {
-        getAccessToken: function(token, callback) {
-          callback(null, { user: {} });
-        }
-      };
-      const handler = new AuthenticateHandler({ model: model });
-
-      handler.getAccessToken('foo').should.be.an.instanceOf(Promise);
-    });
   });
 
   describe('validateAccessToken()', function() {
-    it('should throw an error if `accessToken` is expired', function() {
+
+    it('should throw an error if `accessToken` is expired', async function() {
       const accessToken = { accessTokenExpiresAt: new Date(new Date() / 2) };
-      const handler = new AuthenticateHandler({ model: { getAccessToken: function() {} } });
+      const handler = new AuthenticateHandler({
+        model: {
+          getAccessToken: function() {}
+        }
+      });
 
-      try {
-        handler.validateAccessToken(accessToken);
+      let valid;
 
-        should.fail();
+      try {
+        valid = await handler.validateAccessToken(accessToken);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidTokenError);
         e.message.should.equal('Invalid token: access token has expired');
       }
+
+      should.not.exist(valid);
     });
 
-    it('should return an access token', function() {
+    it('should return an access token', async function() {
+
       const accessToken = {
         user: {},
         accessTokenExpiresAt: new Date(new Date().getTime() + 10000)
       };
-      const handler = new AuthenticateHandler({ model: { getAccessToken: function() {} } });
 
-      handler.validateAccessToken(accessToken).should.equal(accessToken);
+      const handler = new AuthenticateHandler({
+        model: {
+          getAccessToken: function() {}
+        }
+      });
+
+      let token;
+
+      try {
+        token = await handler.validateAccessToken(accessToken);
+      } catch (err) {
+        should.fail(err.stack);
+      }
+
+      should.exist(token);
+      token.should.eql(accessToken);
+
     });
+
   });
 
   describe('verifyScope()', function() {
+
     it('should throw an error if `scope` is insufficient', function() {
+
       const model = {
         getAccessToken: function() {},
         verifyScope: function() {
           return false;
         }
       };
-      const handler = new AuthenticateHandler({ addAcceptedScopesHeader: true, addAuthorizedScopesHeader: true, model: model, scope: 'foo' });
+
+      const handler = new AuthenticateHandler({ 
+        addAcceptedScopesHeader: true,
+        addAuthorizedScopesHeader: true,
+        model: model,
+        scope: 'foo'
+      });
 
       return handler.verifyScope('foo')
         .then(should.fail)
@@ -468,43 +669,39 @@ describe('AuthenticateHandler integration', function() {
           e.should.be.an.instanceOf(InsufficientScopeError);
           e.message.should.equal('Insufficient scope: authorized scope is insufficient');
         });
+
     });
 
-    it('should support promises', function() {
-      const model = {
-        getAccessToken: function() {},
-        verifyScope: function() {
-          return true;
-        }
-      };
-      const handler = new AuthenticateHandler({ addAcceptedScopesHeader: true, addAuthorizedScopesHeader: true, model: model, scope: 'foo' });
+    it('should validate scope', async function() {
 
-      handler.verifyScope('foo').should.be.an.instanceOf(Promise);
-    });
+      const scope = 'foo';
 
-    it('should support non-promises', function() {
       const model = {
         getAccessToken: function() {},
-        verifyScope: function() {
-          return true;
-        }
+        verifyScope: sinon.stub().resolves(false),
       };
-      const handler = new AuthenticateHandler({ addAcceptedScopesHeader: true, addAuthorizedScopesHeader: true, model: model, scope: 'foo' });
 
-      handler.verifyScope('foo').should.be.an.instanceOf(Promise);
-    });
+      const handler = new AuthenticateHandler({ 
+        addAcceptedScopesHeader: true,
+        addAuthorizedScopesHeader: true,
+        model: model,
+        scope: scope
+      });
 
-    it('should support callbacks', function() {
-      const model = {
-        getAccessToken: function() {},
-        verifyScope: function(token, scope, callback) {
-          callback(null, true);
-        }
-      };
-      const handler = new AuthenticateHandler({ addAcceptedScopesHeader: true, addAuthorizedScopesHeader: true, model: model, scope: 'foo' });
+      let valid;
+
+      try {
+        valid = await handler.verifyScope(scope);
+      } catch (err) {
+        err.should.be.an.instanceOf(InsufficientScopeError);
+        err.message.should.equal('Insufficient scope: authorized scope is insufficient');
+      }
+
+      should.not.exist(valid);
 
-      handler.verifyScope('foo').should.be.an.instanceOf(Promise);
     });
+
+
   });
 
   describe('updateResponse()', function() {
@@ -513,12 +710,19 @@ describe('AuthenticateHandler integration', function() {
         getAccessToken: function() {},
         verifyScope: function() {}
       };
-      const handler = new AuthenticateHandler({ addAcceptedScopesHeader: true, addAuthorizedScopesHeader: false, model: model });
+
+      const handler = new AuthenticateHandler({
+        addAcceptedScopesHeader: true,
+        addAuthorizedScopesHeader: false,
+        model: model
+      });
+
       const response = new Response({ body: {}, headers: {} });
 
       handler.updateResponse(response, { scope: 'foo biz' });
 
       response.headers.should.not.have.property('x-accepted-oauth-scopes');
+
     });
 
     it('should set the `X-Accepted-OAuth-Scopes` header if `scope` is specified', function() {
@@ -526,7 +730,12 @@ describe('AuthenticateHandler integration', function() {
         getAccessToken: function() {},
         verifyScope: function() {}
       };
-      const handler = new AuthenticateHandler({ addAcceptedScopesHeader: true, addAuthorizedScopesHeader: false, model: model, scope: 'foo bar' });
+      const handler = new AuthenticateHandler({
+        addAcceptedScopesHeader: true,
+        addAuthorizedScopesHeader: false,
+        model: model,
+        scope: 'foo bar'
+      });
       const response = new Response({ body: {}, headers: {} });
 
       handler.updateResponse(response, { scope: 'foo biz' });
@@ -539,7 +748,11 @@ describe('AuthenticateHandler integration', function() {
         getAccessToken: function() {},
         verifyScope: function() {}
       };
-      const handler = new AuthenticateHandler({ addAcceptedScopesHeader: false, addAuthorizedScopesHeader: true, model: model });
+      const handler = new AuthenticateHandler({
+        addAcceptedScopesHeader: false,
+        addAuthorizedScopesHeader: true,
+        model: model
+      });
       const response = new Response({ body: {}, headers: {} });
 
       handler.updateResponse(response, { scope: 'foo biz' });
@@ -552,12 +765,18 @@ describe('AuthenticateHandler integration', function() {
         getAccessToken: function() {},
         verifyScope: function() {}
       };
-      const handler = new AuthenticateHandler({ addAcceptedScopesHeader: false, addAuthorizedScopesHeader: true, model: model, scope: 'foo bar' });
+      const handler = new AuthenticateHandler({
+        addAcceptedScopesHeader: false,
+        addAuthorizedScopesHeader: true,
+        model: model,
+        scope: 'foo bar'
+      });
       const response = new Response({ body: {}, headers: {} });
 
       handler.updateResponse(response, { scope: 'foo biz' });
 
       response.get('X-OAuth-Scopes').should.equal('foo biz');
     });
+
   });
 });
diff --git a/test/integration/handlers/authorize-handler_test.js b/test/integration/handlers/authorize-handler_test.js
index 3e597ad..00b6f44 100644
--- a/test/integration/handlers/authorize-handler_test.js
+++ b/test/integration/handlers/authorize-handler_test.js
@@ -13,7 +13,7 @@ const InvalidClientError = require('../../../lib/errors/invalid-client-error');
 const InvalidRequestError = require('../../../lib/errors/invalid-request-error');
 const InvalidScopeError = require('../../../lib/errors/invalid-scope-error');
 const UnsupportedResponseTypeError = require('../../../lib/errors/unsupported-response-type-error');
-const Promise = require('bluebird');
+// const Promise = require('bluebird');
 const Request = require('../../../lib/request');
 const Response = require('../../../lib/response');
 const ServerError = require('../../../lib/errors/server-error');
@@ -26,52 +26,55 @@ const url = require('url');
  */
 
 describe('AuthorizeHandler integration', function() {
+
   describe('constructor()', function() {
+
     it('should throw an error if `options.authorizationCodeLifetime` is missing', function() {
+
       try {
         new AuthorizeHandler();
-
-        should.fail();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `authorizationCodeLifetime`');
       }
+
     });
 
     it('should throw an error if `options.model` is missing', function() {
+
       try {
         new AuthorizeHandler({ authorizationCodeLifetime: 120 });
-
-        should.fail();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `model`');
       }
+
     });
 
     it('should throw an error if the model does not implement `getClient()`', function() {
+
       try {
         new AuthorizeHandler({ authorizationCodeLifetime: 120, model: {} });
-
-        should.fail();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: model does not implement `getClient()`');
       }
+
     });
 
     it('should throw an error if the model does not implement `saveAuthorizationCode()`', function() {
+
       try {
         new AuthorizeHandler({ authorizationCodeLifetime: 120, model: { getClient: function() {} } });
-
-        should.fail();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: model does not implement `saveAuthorizationCode()`');
       }
+
     });
 
     it('should throw an error if the model does not implement `getAccessToken()`', function() {
+
       const model = {
         getClient: function() {},
         saveAuthorizationCode: function() {}
@@ -79,87 +82,129 @@ describe('AuthorizeHandler integration', function() {
 
       try {
         new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
-
-        should.fail();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: model does not implement `getAccessToken()`');
       }
+
     });
 
     it('should set the `authorizationCodeLifetime`', function() {
+
       const model = {
         getAccessToken: function() {},
         getClient: function() {},
         saveAuthorizationCode: function() {}
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
+
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
 
       handler.authorizationCodeLifetime.should.equal(120);
+
     });
 
     it('should set the `authenticateHandler`', function() {
+
       const model = {
         getAccessToken: function() {},
         getClient: function() {},
         saveAuthorizationCode: function() {}
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
+
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
 
       handler.authenticateHandler.should.be.an.instanceOf(AuthenticateHandler);
+
     });
 
     it('should set the `model`', function() {
+
       const model = {
         getAccessToken: function() {},
         getClient: function() {},
         saveAuthorizationCode: function() {}
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
+
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
 
       handler.model.should.equal(model);
+
     });
   });
 
   describe('handle()', function() {
-    it('should throw an error if `request` is missing', function() {
+
+
+    it('should throw an error if `request` is missing', async function() {
+
       const model = {
         getAccessToken: function() {},
         getClient: function() {},
         saveAuthorizationCode: function() {}
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
 
-      try {
-        handler.handle();
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
 
-        should.fail();
+      let res;
+
+      try {
+        res = await handler.handle();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: `request` must be an instance of Request');
       }
+
+      should.not.exist(res);
+
     });
 
-    it('should throw an error if `response` is missing', function() {
+    it('should throw an error if `response` is missing', async function() {
+
       const model = {
         getAccessToken: function() {},
         getClient: function() {},
         saveAuthorizationCode: function() {}
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
-      const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
 
-      try {
-        handler.handle(request);
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
 
-        should.fail();
+      const request = new Request({
+        body: {},
+        headers: {},
+        method: {},
+        query: {}
+      });
+
+      let res;
+
+      try {
+        res = await handler.handle(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: `response` must be an instance of Response');
       }
+
+      should.not.exist(res);
+
     });
 
     it('should throw an error if `allowed` is `false`', function() {
+
       const model = {
         getAccessToken: function() {
           return {
@@ -167,14 +212,23 @@ describe('AuthorizeHandler integration', function() {
             accessTokenExpiresAt: new Date(new Date().getTime() + 10000)
           };
         },
+
         getClient: function() {
-          return { grants: ['authorization_code'], redirectUris: ['http://example.com/cb'] };
+          return {
+            grants: ['authorization_code'],
+            redirectUris: ['http://example.com/cb']
+          };
         },
         saveAuthorizationCode: function() {
           throw new Error('Unhandled exception');
         }
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
+
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
+      
       const request = new Request({
         body: {
           client_id: 'test'
@@ -188,7 +242,11 @@ describe('AuthorizeHandler integration', function() {
           state: 'foobar'
         }
       });
-      const response = new Response({ body: {}, headers: {} });
+
+      const response = new Response({
+        body: {},
+        headers: {}
+      });
 
       return handler.handle(request, response)
         .then(should.fail)
@@ -196,9 +254,11 @@ describe('AuthorizeHandler integration', function() {
           e.should.be.an.instanceOf(AccessDeniedError);
           e.message.should.equal('Access denied: user denied access to application');
         });
+
     });
 
     it('should redirect to an error response if a non-oauth error is thrown', function() {
+
       const model = {
         getAccessToken: function() {
           return {
@@ -207,13 +267,22 @@ describe('AuthorizeHandler integration', function() {
           };
         },
         getClient: function() {
-          return { grants: ['authorization_code'], redirectUris: ['http://example.com/cb'] };
+          return {
+            grants: ['authorization_code'],
+            redirectUris: ['http://example.com/cb']
+          };
         },
         saveAuthorizationCode: function() {
           throw new Error('Unhandled exception');
         }
+
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
+
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
+
       const request = new Request({
         body: {
           client_id: 12345,
@@ -227,13 +296,16 @@ describe('AuthorizeHandler integration', function() {
           state: 'foobar'
         }
       });
+
       const response = new Response({ body: {}, headers: {} });
 
       return handler.handle(request, response)
         .then(should.fail)
         .catch(function() {
-          response.get('location').should.equal('http://example.com/cb?error=server_error&error_description=Unhandled%20exception&state=foobar');
+          response.get('location').should
+            .equal('http://example.com/cb?error=server_error&error_description=Service%20Unavailable&state=foobar');
         });
+
     });
 
     it('should redirect to an error response if an oauth error is thrown', function() {
@@ -270,7 +342,9 @@ describe('AuthorizeHandler integration', function() {
       return handler.handle(request, response)
         .then(should.fail)
         .catch(function() {
-          response.get('location').should.equal('http://example.com/cb?error=access_denied&error_description=Cannot%20request%20this%20auth%20code&state=foobar');
+          response.get('location').should.equal(
+            'http://example.com/cb?error=access_denied&error_description=Cannot%20request%20this%20auth%20code&state=foobar'
+          );
         });
     });
 
@@ -309,7 +383,8 @@ describe('AuthorizeHandler integration', function() {
 
       return handler.handle(request, response)
         .then(function() {
-          response.get('location').should.equal('http://example.com/cb?code=12345&state=foobar');
+          response.get('location').should
+            .equal('http://example.com/cb?code=12345&state=foobar');
         })
         .catch(should.fail);
     });
@@ -323,13 +398,21 @@ describe('AuthorizeHandler integration', function() {
           };
         },
         getClient: function() {
-          return { grants: ['authorization_code'], redirectUris: ['http://example.com/cb'] };
+          return { 
+            grants: ['authorization_code'],
+            redirectUris: ['http://example.com/cb']
+          };
         },
         saveAuthorizationCode: function() {
           return {};
         }
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
+
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
+
       const request = new Request({
         body: {
           client_id: 12345,
@@ -344,12 +427,15 @@ describe('AuthorizeHandler integration', function() {
           state: 'foobar'
         }
       });
+
       const response = new Response({ body: {}, headers: {} });
 
       return handler.handle(request, response)
         .then(should.fail)
-        .catch(function() {
-          response.get('location').should.equal('http://example.com/cb?error=invalid_scope&error_description=Invalid%20parameter%3A%20%60scope%60&state=foobar');
+        .catch( function(err) {
+          response.get('location').should.equal(
+            'http://example.com/cb?error=invalid_scope&error_description=Invalid%20parameter%3A%20%60scope%60&state=foobar'
+          );
         });
     });
 
@@ -554,7 +640,14 @@ describe('AuthorizeHandler integration', function() {
     });
 
     it('should return the `code` if successful', function() {
-      const client = { grants: ['authorization_code'], redirectUris: ['http://example.com/cb'] };
+
+      const authCode = 12345;
+
+      const client = {
+        grants: ['authorization_code'],
+        redirectUris: ['http://example.com/cb']
+      };
+
       const model = {
         getAccessToken: function() {
           return {
@@ -567,13 +660,18 @@ describe('AuthorizeHandler integration', function() {
           return client;
         },
         saveAuthorizationCode: function() {
-          return { authorizationCode: 12345, client: client };
+          return { authorizationCode: authCode, client: client };
         }
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
+
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
+
       const request = new Request({
         body: {
-          client_id: 12345,
+          client_id: authCode,
           response_type: 'code'
         },
         headers: {
@@ -584,20 +682,24 @@ describe('AuthorizeHandler integration', function() {
           state: 'foobar'
         }
       });
+
       const response = new Response({ body: {}, headers: {} });
 
       return handler.handle(request, response)
         .then(function(data) {
           data.should.eql({
-            authorizationCode: 12345,
+            authorizationCode: authCode,
             client: client
           });
-        })
+        })  
         .catch(should.fail);
+
     });
+
   });
 
   describe('generateAuthorizationCode()', function() {
+
     it('should return an auth code', function() {
       const model = {
         getAccessToken: function() {},
@@ -613,33 +715,6 @@ describe('AuthorizeHandler integration', function() {
         .catch(should.fail);
     });
 
-    it('should support promises', function() {
-      const model = {
-        generateAuthorizationCode: function() {
-          return Promise.resolve({});
-        },
-        getAccessToken: function() {},
-        getClient: function() {},
-        saveAuthorizationCode: function() {}
-      };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
-
-      handler.generateAuthorizationCode().should.be.an.instanceOf(Promise);
-    });
-
-    it('should support non-promises', function() {
-      const model = {
-        generateAuthorizationCode: function() {
-          return {};
-        },
-        getAccessToken: function() {},
-        getClient: function() {},
-        saveAuthorizationCode: function() {}
-      };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
-
-      handler.generateAuthorizationCode().should.be.an.instanceOf(Promise);
-    });
   });
 
   describe('getAuthorizationCodeLifetime()', function() {
@@ -656,61 +731,107 @@ describe('AuthorizeHandler integration', function() {
   });
 
   describe('getClient()', function() {
-    it('should throw an error if `client_id` is missing', function() {
+
+    it('should throw an error if `client_id` is missing', async function() {
+
       const model = {
         getAccessToken: function() {},
         getClient: function() {},
         saveAuthorizationCode: function() {}
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
-      const request = new Request({ body: { response_type: 'code' }, headers: {}, method: {}, query: {} });
+      
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
+      
+      const request = new Request({
+        body: { response_type: 'code' },
+        headers: {},
+        method: {},
+        query: {} 
+      });
 
-      try {
-        handler.getClient(request);
+      let res;
 
-        should.fail();
+      try {
+        res = await handler.getClient(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Missing parameter: `client_id`');
       }
+
+      should.not.exist(res);
     });
 
-    it('should throw an error if `client_id` is invalid', function() {
+    it('should throw an error if `client_id` is invalid', async function() {
+
       const model = {
         getAccessToken: function() {},
         getClient: function() {},
         saveAuthorizationCode: function() {}
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
-      const request = new Request({ body: { client_id: 'øå€£‰', response_type: 'code' }, headers: {}, method: {}, query: {} });
 
-      try {
-        handler.getClient(request);
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
 
-        should.fail();
+      const request = new Request({
+        body: { client_id: 'øå€£‰', response_type: 'code' },
+        headers: {},
+        method: {},
+        query: {}
+      });
+
+      let res;
+
+      try {
+        res = await handler.getClient(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Invalid parameter: `client_id`');
       }
+
+      should.not.exist(res);
+
     });
 
-    it('should throw an error if `client.redirectUri` is invalid', function() {
+    it('should throw an error if `client.redirectUri` is invalid', async function() {
+
       const model = {
         getAccessToken: function() {},
         getClient: function() {},
         saveAuthorizationCode: function() {}
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
-      const request = new Request({ body: { client_id: 12345, response_type: 'code', redirect_uri: 'foobar' }, headers: {}, method: {}, query: {} });
 
-      try {
-        handler.getClient(request);
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
 
-        should.fail();
+      const request = new Request({
+        body: {
+          client_id: 12345,
+          response_type: 'code',
+          redirect_uri: 'foobar'
+        },
+        headers: {},
+        method: {},
+        query: {} 
+      });
+
+      let res;
+
+      try {
+        res = await handler.getClient(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Invalid request: `redirect_uri` is not a valid URI');
       }
+
+      should.not.exist(res);
+
     });
 
     it('should throw an error if `client` is missing', function() {
@@ -1057,62 +1178,32 @@ describe('AuthorizeHandler integration', function() {
   });
 
   describe('saveAuthorizationCode()', function() {
+
     it('should return an auth code', function() {
+
       const authorizationCode = {};
+
       const model = {
         getAccessToken: function() {},
         getClient: function() {},
         saveAuthorizationCode: function() {
-          return authorizationCode;
+          return Promise.resolve(authorizationCode);
         }
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
+
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
 
       return handler.saveAuthorizationCode('foo', 'bar', 'biz', 'baz')
         .then(function(data) {
           data.should.equal(authorizationCode);
         })
         .catch(should.fail);
-    });
 
-    it('should support promises when calling `model.saveAuthorizationCode()`', function() {
-      const model = {
-        getAccessToken: function() {},
-        getClient: function() {},
-        saveAuthorizationCode: function() {
-          return Promise.resolve({});
-        }
-      };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
-
-      handler.saveAuthorizationCode('foo', 'bar', 'biz', 'baz').should.be.an.instanceOf(Promise);
-    });
-
-    it('should support non-promises when calling `model.saveAuthorizationCode()`', function() {
-      const model = {
-        getAccessToken: function() {},
-        getClient: function() {},
-        saveAuthorizationCode: function() {
-          return {};
-        }
-      };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
-
-      handler.saveAuthorizationCode('foo', 'bar', 'biz', 'baz').should.be.an.instanceOf(Promise);
     });
 
-    it('should support callbacks when calling `model.saveAuthorizationCode()`', function() {
-      const model = {
-        getAccessToken: function() {},
-        getClient: function() {},
-        saveAuthorizationCode: function(code, client, user, callback) {
-          return callback(null, true);
-        }
-      };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
-
-      handler.saveAuthorizationCode('foo', 'bar', 'biz', 'baz').should.be.an.instanceOf(Promise);
-    });
   });
 
   describe('getResponseType()', function() {
diff --git a/test/integration/handlers/token-handler_test.js b/test/integration/handlers/token-handler_test.js
index 41ec524..85c356c 100644
--- a/test/integration/handlers/token-handler_test.js
+++ b/test/integration/handlers/token-handler_test.js
@@ -11,7 +11,6 @@ const InvalidClientError = require('../../../lib/errors/invalid-client-error');
 const InvalidGrantError = require('../../../lib/errors/invalid-grant-error');
 const InvalidRequestError = require('../../../lib/errors/invalid-request-error');
 const PasswordGrantType = require('../../../lib/grant-types/password-grant-type');
-const Promise = require('bluebird');
 const Request = require('../../../lib/request');
 const Response = require('../../../lib/response');
 const ServerError = require('../../../lib/errors/server-error');
@@ -20,12 +19,14 @@ const UnauthorizedClientError = require('../../../lib/errors/unauthorized-client
 const UnsupportedGrantTypeError = require('../../../lib/errors/unsupported-grant-type-error');
 const should = require('chai').should();
 const util = require('util');
+const sinon = require('sinon');
 
 /**
  * Test `TokenHandler` integration.
  */
 
 describe('TokenHandler integration', function() {
+
   describe('constructor()', function() {
     it('should throw an error if `options.accessTokenLifetime` is missing', function() {
       try {
@@ -147,39 +148,61 @@ describe('TokenHandler integration', function() {
   });
 
   describe('handle()', function() {
-    it('should throw an error if `request` is missing', function() {
+
+    it('should throw an error if `request` is missing', async function() {
+
       const model = {
         getClient: function() {},
         saveToken: function() {}
       };
-      const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 });
 
-      try {
-        handler.handle();
+      const handler = new TokenHandler({
+        accessTokenLifetime: 120,
+        model: model,
+        refreshTokenLifetime: 120
+      });
 
-        should.fail();
+      let res;
+
+      try {
+        res = await handler.handle();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: `request` must be an instance of Request');
       }
+
+      should.not.exist(res);
     });
 
-    it('should throw an error if `response` is missing', function() {
+    it('should throw an error if `response` is missing', async function() {
+
       const model = {
         getClient: function() {},
         saveToken: function() {}
       };
-      const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 });
-      const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
 
-      try {
-        handler.handle(request);
+      const handler = new TokenHandler({
+        accessTokenLifetime: 120,
+        model: model,
+        refreshTokenLifetime: 120
+      });
 
-        should.fail();
+      const request = new Request({
+        body: {},
+        headers: {},
+        method: {},
+        query: {}
+      });
+      
+      let res;
+
+      try {
+        res = await handler.handle(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Invalid argument: `response` must be an instance of Response');
       }
+      should.not.exist(res);
     });
 
     it('should throw an error if the method is not `POST`', function() {
@@ -363,14 +386,30 @@ describe('TokenHandler integration', function() {
     });
 
     it('should return custom attributes in a bearer token if the allowExtendedTokenAttributes is set', function() {
-      const token = { accessToken: 'foo', client: {}, refreshToken: 'bar', scope: 'foobar', user: {}, foo: 'bar' };
+
+      const token = {
+        accessToken: 'foo',
+        client: {},
+        refreshToken: 'bar',
+        scope: 'foobar',
+        user: {},
+        foo: 'bar'
+      };
+
       const model = {
         getClient: function() { return { grants: ['password'] }; },
         getUser: function() { return {}; },
         saveToken: function() { return token; },
         validateScope: function() { return 'baz'; }
       };
-      const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120, allowExtendedTokenAttributes: true });
+
+      const handler = new TokenHandler({
+        accessTokenLifetime: 120,
+        model: model,
+        refreshTokenLifetime: 120,
+        allowExtendedTokenAttributes: true
+      });
+
       const request = new Request({
         body: {
           client_id: 12345,
@@ -388,52 +427,88 @@ describe('TokenHandler integration', function() {
 
       return handler.handle(request, response)
         .then(function() {
-          should.exist(response.body.access_token);
-          should.exist(response.body.refresh_token);
-          should.exist(response.body.token_type);
-          should.exist(response.body.scope);
-          should.exist(response.body.foo);
+          response.should.have.property('body');
+          response.body.should.have.property('access_token');
+          response.body.access_token.should.eql(token.accessToken);
+          response.body.should.have.property('refresh_token');
+          response.body.refresh_token.should.eql(token.refreshToken);
+          response.body.should.have.property('token_type');
+          response.body.token_type.should.eql('Bearer');
+          response.body.should.have.property('scope');
+          response.body.scope.should.eql(token.scope);
+          response.body.should.have.property('foo');
+          response.body.foo.should.eql(token.foo);
         })
         .catch(should.fail);
     });
   });
 
-
   describe('getClient()', function() {
-    it('should throw an error if `clientId` is invalid', function() {
+
+    it('should throw an error if `clientId` is invalid', async function() {
+
       const model = {
         getClient: function() {},
         saveToken: function() {}
       };
-      const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 });
-      const request = new Request({ body: { client_id: 'øå€£‰', client_secret: 'foo' }, headers: {}, method: {}, query: {} });
 
-      try {
-        handler.getClient(request);
+      const handler = new TokenHandler({
+        accessTokenLifetime: 120,
+        model: model,
+        refreshTokenLifetime: 120
+      });
 
-        should.fail();
+      const request = new Request({
+        body: { client_id: 'øå€£‰', client_secret: 'foo' },
+        headers: {},
+        method: {},
+        query: {}
+      });
+
+      let res;
+
+      try {
+        res = await handler.getClient(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Invalid parameter: `client_id`');
       }
+
+      should.not.exist(res);
+
     });
 
-    it('should throw an error if `clientSecret` is invalid', function() {
+    it('should throw an error if `clientSecret` is invalid', async function() {
+
       const model = {
         getClient: function() {},
         saveToken: function() {}
       };
-      const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 });
-      const request = new Request({ body: { client_id: 'foo', client_secret: 'øå€£‰' }, headers: {}, method: {}, query: {} });
 
-      try {
-        handler.getClient(request);
+      const handler = new TokenHandler({
+        accessTokenLifetime: 120,
+        model: model,
+        refreshTokenLifetime: 120
+      });
 
-        should.fail();
+      const request = new Request({
+        body: { client_id: 'foo', client_secret: 'øå€£‰' },
+        headers: {},
+        method: {},
+        query: {}
+      });
+
+      let res;
+
+      try {
+        res = await handler.getClient(request);
       } catch (e) {
         e.should.be.an.instanceOf(InvalidRequestError);
         e.message.should.equal('Invalid parameter: `client_secret`');
       }
+
+      should.not.exist(res);
+
     });
 
     it('should throw an error if `client` is missing', function() {
@@ -584,41 +659,10 @@ describe('TokenHandler integration', function() {
       });
     });
 
-    it('should support promises', function() {
-      const model = {
-        getClient: function() { return Promise.resolve({ grants: [] }); },
-        saveToken: function() {}
-      };
-      const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 });
-      const request = new Request({ body: { client_id: 12345, client_secret: 'secret' }, headers: {}, method: {}, query: {} });
-
-      handler.getClient(request).should.be.an.instanceOf(Promise);
-    });
-
-    it('should support non-promises', function() {
-      const model = {
-        getClient: function() { return { grants: [] }; },
-        saveToken: function() {}
-      };
-      const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 });
-      const request = new Request({ body: { client_id: 12345, client_secret: 'secret' }, headers: {}, method: {}, query: {} });
-
-      handler.getClient(request).should.be.an.instanceOf(Promise);
-    });
-
-    it('should support callbacks', function() {
-      const model = {
-        getClient: function(clientId, clientSecret, callback) { callback(null, { grants: [] }); },
-        saveToken: function() {}
-      };
-      const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 });
-      const request = new Request({ body: { client_id: 12345, client_secret: 'secret' }, headers: {}, method: {}, query: {} });
-
-      handler.getClient(request).should.be.an.instanceOf(Promise);
-    });
   });
 
   describe('getClientCredentials()', function() {
+
     it('should throw an error if `client_id` is missing', function() {
       const model = {
         getClient: function() {},
@@ -706,6 +750,7 @@ describe('TokenHandler integration', function() {
   });
 
   describe('handleGrantType()', function() {
+
     it('should throw an error if `grant_type` is missing', function() {
       const model = {
         getClient: function() {},
@@ -779,22 +824,45 @@ describe('TokenHandler integration', function() {
       }
     });
 
-    it('should throw an invalid grant error if a non-oauth error is thrown', function() {
+    it('should throw an invalid grant error if a non-oauth error is thrown', async function() {
+      
       const client = { grants: ['password'] };
+      
       const model = {
-        getClient: function(clientId, password, callback) { callback(null, client); },
-        getUser: function(uid, pwd, callback) { callback(); },
-        saveToken: function() {}
+        getClient: sinon.stub().resolves(client),
+        getUser: sinon.stub().resolves(undefined),
+        saveToken: sinon.stub().resolves(undefined),
       };
-      const handler = new TokenHandler({ accessTokenLifetime: 120, model: model, refreshTokenLifetime: 120 });
-      const request = new Request({ body: { grant_type: 'password', username: 'foo', password: 'bar' }, headers: {}, method: {}, query: {} });
+      
+      const handler = new TokenHandler({
+        accessTokenLifetime: 120,
+        model: model,
+        refreshTokenLifetime: 120
+      });
+      
+      const request = new Request({ 
+        body: {
+          grant_type: 'password',
+          username: 'foo',
+          password: 'bar'
+        },
+        headers: {},
+        method: {},
+        query: {}
+      });
+      
+      let res;
+
+      try {
+        res = await handler.handleGrantType(request, client);  
+      } catch (err) {
+        should.exist(err);
+        err.should.be.an.instanceOf(InvalidGrantError);
+        err.message.should.equal('Invalid grant: user credentials are invalid');
+      }
+
+      should.not.exist(res);
 
-      return handler.handleGrantType(request, client)
-        .then(should.fail)
-        .catch(function(e) {
-          e.should.be.an.instanceOf(InvalidGrantError);
-          e.message.should.equal('Invalid grant: user credentials are invalid');
-        });
     });
 
     describe('with grant_type `authorization_code`', function() {
diff --git a/test/integration/server_test.js b/test/integration/server_test.js
index db10544..d40f473 100644
--- a/test/integration/server_test.js
+++ b/test/integration/server_test.js
@@ -5,7 +5,6 @@
  */
 
 const InvalidArgumentError = require('../../lib/errors/invalid-argument-error');
-const Promise = require('bluebird');
 const Request = require('../../lib/request');
 const Response = require('../../lib/response');
 const Server = require('../../lib/server');
@@ -16,12 +15,12 @@ const should = require('chai').should();
  */
 
 describe('Server integration', function() {
+
   describe('constructor()', function() {
+
     it('should throw an error if `model` is missing', function() {
       try {
         new Server({});
-
-        should.fail();
       } catch (e) {
         e.should.be.an.instanceOf(InvalidArgumentError);
         e.message.should.equal('Missing parameter: `model`');
@@ -31,13 +30,15 @@ describe('Server integration', function() {
     it('should set the `model`', function() {
       const model = {};
       const server = new Server({ model: model });
-
       server.options.model.should.equal(model);
     });
+
   });
 
   describe('authenticate()', function() {
+
     it('should set the default `options`', function() {
+
       const model = {
         getAccessToken: function() {
           return {
@@ -46,54 +47,48 @@ describe('Server integration', function() {
           };
         }
       };
-      const server = new Server({ model: model });
-      const request = new Request({ body: {}, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: {} });
-      const response = new Response({ body: {}, headers: {} });
+
+      const server = new Server({
+        model: model
+      });
+
+      const request = new Request({
+        body: {},
+        headers: { 'Authorization': 'Bearer foo' },
+        method: {},
+        query: {}
+      });
+
+      const response = new Response({
+        body: {},
+        headers: {}
+      });
 
       return server.authenticate(request, response)
-        .then(function() {
-          this.addAcceptedScopesHeader.should.be.true;
-          this.addAuthorizedScopesHeader.should.be.true;
-          this.allowBearerTokensInQueryString.should.be.false;
-        })
-        .catch(should.fail);
-    });
+        .then( function() {
+          // REVIEW: 'this' is not standard promise behaviour.
+          // Instaead access the handler from the server.
 
-    it('should return a promise', function() {
-      const model = {
-        getAccessToken: function(token, callback) {
-          callback(null, {
-            user: {},
-            accessTokenExpiresAt: new Date(new Date().getTime() + 10000)
-          });
-        }
-      };
-      const server = new Server({ model: model });
-      const request = new Request({ body: {}, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: {} });
-      const response = new Response({ body: {}, headers: {} });
-      const handler = server.authenticate(request, response);
+          // old way 
+          // this.addAcceptedScopesHeader.should.be.true;
+          // this.addAuthorizedScopesHeader.should.be.true;
+          // this.allowBearerTokensInQueryString.should.be.false;
 
-      handler.should.be.an.instanceOf(Promise);
-    });
+          // new way
+          // server.should.have.property('authenticateHandler');
+          server.authenticateHandler.addAcceptedScopesHeader.should.be.true;
+          server.authenticateHandler.addAuthorizedScopesHeader.should.be.true;
+          server.authenticateHandler.allowBearerTokensInQueryString.should.be.false;
 
-    it('should support callbacks', function(next) {
-      const model = {
-        getAccessToken: function() {
-          return {
-            user: {},
-            accessTokenExpiresAt: new Date(new Date().getTime() + 10000)
-          };
-        }
-      };
-      const server = new Server({ model: model });
-      const request = new Request({ body: {}, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: {} });
-      const response = new Response({ body: {}, headers: {} });
 
-      server.authenticate(request, response, null, next);
+        })
+        .catch(should.fail);
     });
+
   });
 
   describe('authorize()', function() {
+
     it('should set the default `options`', function() {
       const model = {
         getAccessToken: function() {
@@ -115,59 +110,16 @@ describe('Server integration', function() {
 
       return server.authorize(request, response)
         .then(function() {
-          this.allowEmptyState.should.be.false;
-          this.authorizationCodeLifetime.should.equal(300);
+          server.authorizeHandler.allowEmptyState.should.be.false;
+          server.authorizeHandler.authorizationCodeLifetime.should.equal(300);
         })
         .catch(should.fail);
     });
 
-    it('should return a promise', function() {
-      const model = {
-        getAccessToken: function() {
-          return {
-            user: {},
-            accessTokenExpiresAt: new Date(new Date().getTime() + 10000)
-          };
-        },
-        getClient: function() {
-          return { grants: ['authorization_code'], redirectUris: ['http://example.com/cb'] };
-        },
-        saveAuthorizationCode: function() {
-          return { authorizationCode: 123 };
-        }
-      };
-      const server = new Server({ model: model });
-      const request = new Request({ body: { client_id: 1234, client_secret: 'secret', response_type: 'code' }, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: { state: 'foobar' } });
-      const response = new Response({ body: {}, headers: {} });
-      const handler = server.authorize(request, response);
-
-      handler.should.be.an.instanceOf(Promise);
-    });
-
-    it('should support callbacks', function(next) {
-      const model = {
-        getAccessToken: function() {
-          return {
-            user: {},
-            accessTokenExpiresAt: new Date(new Date().getTime() + 10000)
-          };
-        },
-        getClient: function() {
-          return { grants: ['authorization_code'], redirectUris: ['http://example.com/cb'] };
-        },
-        saveAuthorizationCode: function() {
-          return { authorizationCode: 123 };
-        }
-      };
-      const server = new Server({ model: model });
-      const request = new Request({ body: { client_id: 1234, client_secret: 'secret', response_type: 'code' }, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: { state: 'foobar' } });
-      const response = new Response({ body: {}, headers: {} });
-
-      server.authorize(request, response, null, next);
-    });
   });
 
   describe('token()', function() {
+
     it('should set the default `options`', function() {
       const model = {
         getClient: function() {
@@ -187,52 +139,12 @@ describe('Server integration', function() {
 
       return server.token(request, response)
         .then(function() {
-          this.accessTokenLifetime.should.equal(3600);
-          this.refreshTokenLifetime.should.equal(1209600);
+          server.tokenHandler.accessTokenLifetime.should.equal(3600);
+          server.tokenHandler.refreshTokenLifetime.should.equal(1209600);
         })
         .catch(should.fail);
     });
 
-    it('should return a promise', function() {
-      const model = {
-        getClient: function() {
-          return { grants: ['password'] };
-        },
-        getUser: function() {
-          return {};
-        },
-        saveToken: function() {
-          return { accessToken: 1234, client: {}, user: {} };
-        }
-      };
-      const server = new Server({ model: model });
-      const request = new Request({ body: { client_id: 1234, client_secret: 'secret', grant_type: 'password', username: 'foo', password: 'pass' }, headers: { 'content-type': 'application/x-www-form-urlencoded', 'transfer-encoding': 'chunked' }, method: 'POST', query: {} });
-      const response = new Response({ body: {}, headers: {} });
-      const handler = server.token(request, response);
-
-      handler.should.be.an.instanceOf(Promise);
-    });
-
-    it('should support callbacks', function(next) {
-      const model = {
-        getClient: function() {
-          return { grants: ['password'] };
-        },
-        getUser: function() {
-          return {};
-        },
-        saveToken: function() {
-          return { accessToken: 1234, client: {}, user: {} };
-        },
-        validateScope: function() {
-          return 'foo';
-        }
-      };
-      const server = new Server({ model: model });
-      const request = new Request({ body: { client_id: 1234, client_secret: 'secret', grant_type: 'password', username: 'foo', password: 'pass', scope: 'foo' }, headers: { 'content-type': 'application/x-www-form-urlencoded', 'transfer-encoding': 'chunked' }, method: 'POST', query: {} });
-      const response = new Response({ body: {}, headers: {} });
-
-      server.token(request, response, null, next);
-    });
   });
+
 });
diff --git a/test/integration/utils/token-util_test.js b/test/integration/utils/token-util_test.js
index d4f368e..e005df2 100644
--- a/test/integration/utils/token-util_test.js
+++ b/test/integration/utils/token-util_test.js
@@ -10,15 +10,25 @@ const should = require('chai').should();
 /**
  * Test `TokenUtil` integration.
  */
-
 describe('TokenUtil integration', function() {
+
   describe('generateRandomToken()', function() {
-    it('should return a sha-256 token', function() {
-      return TokenUtil.generateRandomToken()
-        .then(function(token) {
-          token.should.be.a.sha256();
-        })
-        .catch(should.fail);
+
+    it('should return a sha-256 token', async function() {
+
+      let token;
+
+      try {
+        token = await TokenUtil.generateRandomToken();
+      } catch (err) {
+        should.not.exist(err, err.stack);
+      }
+
+      should.exist(token);
+      token.should.be.a.sha256();
+
     });
+
   });
-});
+
+});
\ No newline at end of file
diff --git a/test/unit/grant-types/abstract-grant-type_test.js b/test/unit/grant-types/abstract-grant-type_test.js
index f6cb13a..6273977 100644
--- a/test/unit/grant-types/abstract-grant-type_test.js
+++ b/test/unit/grant-types/abstract-grant-type_test.js
@@ -13,35 +13,167 @@ const should = require('chai').should();
  */
 
 describe('AbstractGrantType', function() {
+
   describe('generateAccessToken()', function() {
-    it('should call `model.generateAccessToken()`', function() {
+
+    it('should generate an random access token dispite function not being provided', async function() {
+
+      const abstractGrantType = new AbstractGrantType(
+        {
+          accessTokenLifetime: 120,
+          model: {}
+        }
+      );
+
+      let accessToken;
+
+      try {
+        accessToken = await abstractGrantType.generateAccessToken();
+      } catch (err) {
+        should.not.exist(err, err.stack);
+      }
+
+      should.exist(accessToken);
+      accessToken.should.be.a.sha256();
+
+    });
+
+    it('should generate an access token', async function() {
+
+      const token = (new Date().getTime()).toString(36);
       const model = {
-        generateAccessToken: sinon.stub().returns({ client: {}, expiresAt: new Date(), user: {} })
+        generateAccessToken: sinon.stub().resolves(token)
       };
-      const handler = new AbstractGrantType({ accessTokenLifetime: 120, model: model });
-
-      return handler.generateAccessToken()
-        .then(function() {
-          model.generateAccessToken.callCount.should.equal(1);
-          model.generateAccessToken.firstCall.thisValue.should.equal(model);
-        })
-        .catch(should.fail);
+      const abstractGrantType = new AbstractGrantType(
+        {
+          accessTokenLifetime: 120,
+          model: model
+        }
+      );
+
+      let accessToken;
+
+      try {
+        accessToken = await abstractGrantType.generateAccessToken();
+      } catch (err) {
+        should.not.exist(err, err.stack);
+      }
+
+      should.exist(accessToken);
+      accessToken.should.eql(token.toString());
+      model.generateAccessToken.callCount.should.equal(1);
+      model.generateAccessToken.firstCall.thisValue.should.equal(model);
+
     });
+
   });
 
   describe('generateRefreshToken()', function() {
-    it('should call `model.generateRefreshToken()`', function() {
+
+    it('should generate an random refresh token dispite function not being provided', async function() {
+
+      const abstractGrantType = new AbstractGrantType(
+        {
+          accessTokenLifetime: 120,
+          model: {}
+        }
+      );
+
+      let refreshToken;
+
+      try {
+        refreshToken = await abstractGrantType.generateRefreshToken();
+      } catch (err) {
+        should.not.exist(err, err.stack);
+      }
+
+      should.exist(refreshToken);
+      refreshToken.should.be.a.sha256();
+
+    });
+
+    it('should generate a refresh token', async function() {
+
+      const token = (new Date().getTime()).toString(36);
+      const model = {
+        generateRefreshToken: sinon.stub().resolves(token)
+      };
+      const abstractGrantType = new AbstractGrantType(
+        {
+          accessTokenLifetime: 120,
+          model: model
+        }
+      );
+
+      let refreshToken;
+
+      try {
+        refreshToken = await abstractGrantType.generateRefreshToken();
+      } catch (err) {
+        should.not.exist(err, err.stack);
+      }
+
+      should.exist(refreshToken);
+      refreshToken.should.eql(token.toString());
+      model.generateRefreshToken.callCount.should.equal(1);
+      model.generateRefreshToken.firstCall.thisValue.should.equal(model);
+
+    });
+
+  });
+
+
+  describe('validateScope()', function() {
+
+    it('should validate scope since model has no validate scope function', async function() {
+
+      const abstractGrantType = new AbstractGrantType(
+        {
+          accessTokenLifetime: 120,
+          model: {}
+        }
+      );
+
+      let success;
+
+      try {
+        success = await abstractGrantType.validateScope();
+      } catch (err) {
+        should.not.exist(err, err.stack);
+      }
+
+      should.exist(success);
+      success.should.be.eql(true);
+
+    });
+
+    it('should validate scope', async function() {
+
       const model = {
-        generateRefreshToken: sinon.stub().returns({ client: {}, expiresAt: new Date(new Date() / 2), user: {} })
+        validateScope: sinon.stub().resolves(true)
       };
-      const handler = new AbstractGrantType({ accessTokenLifetime: 120, model: model });
-
-      return handler.generateRefreshToken()
-        .then(function() {
-          model.generateRefreshToken.callCount.should.equal(1);
-          model.generateRefreshToken.firstCall.thisValue.should.equal(model);
-        })
-        .catch(should.fail);
+      const abstractGrantType = new AbstractGrantType(
+        {
+          accessTokenLifetime: 120,
+          model: model
+        }
+      );
+
+      let success;
+
+      try {
+        success = await abstractGrantType.validateScope();
+      } catch (err) {
+        should.not.exist(err, err.stack);
+      }
+
+      should.exist(success);
+      success.should.eql(true);
+      model.validateScope.callCount.should.equal(1);
+      model.validateScope.firstCall.thisValue.should.equal(model);
+
     });
+
   });
+
 });
diff --git a/test/unit/grant-types/client-credentials-grant-type_test.js b/test/unit/grant-types/client-credentials-grant-type_test.js
index 3997823..3cbf568 100644
--- a/test/unit/grant-types/client-credentials-grant-type_test.js
+++ b/test/unit/grant-types/client-credentials-grant-type_test.js
@@ -13,7 +13,9 @@ const should = require('chai').should();
  */
 
 describe('ClientCredentialsGrantType', function() {
+
   describe('getUserFromClient()', function() {
+
     it('should call `model.getUserFromClient()`', function() {
       const model = {
         getUserFromClient: sinon.stub().returns(true),
diff --git a/test/unit/grant-types/password-grant-type_test.js b/test/unit/grant-types/password-grant-type_test.js
index ceb2ad9..07394a0 100644
--- a/test/unit/grant-types/password-grant-type_test.js
+++ b/test/unit/grant-types/password-grant-type_test.js
@@ -14,53 +14,93 @@ const should = require('chai').should();
  */
 
 describe('PasswordGrantType', function() {
+
   describe('getUser()', function() {
-    it('should call `model.getUser()`', function() {
+
+    it('should call `model.getUser()`', async function() {
+      const user = {};
       const model = {
-        getUser: sinon.stub().returns(true),
+        getUser: sinon.stub().resolves(user),
         saveToken: function() {}
       };
-      const handler = new PasswordGrantType({ accessTokenLifetime: 120, model: model });
-      const request = new Request({ body: { username: 'foo', password: 'bar' }, headers: {}, method: {}, query: {} });
-
-      return handler.getUser(request)
-        .then(function() {
-          model.getUser.callCount.should.equal(1);
-          model.getUser.firstCall.args.should.have.length(2);
-          model.getUser.firstCall.args[0].should.equal('foo');
-          model.getUser.firstCall.args[1].should.equal('bar');
-          model.getUser.firstCall.thisValue.should.equal(model);
-        })
-        .catch(should.fail);
+
+      const handler = new PasswordGrantType({
+        accessTokenLifetime: 120,
+        model: model
+      });
+
+      const request = new Request({
+        body: { username: 'foo', password: 'bar' },
+        headers: {},
+        method: {},
+        query: {}
+      });
+
+      let res;
+
+      try {
+        res = await handler.getUser(request);
+      } catch (err) {
+        should.fail(err);
+      }
+      should.exist(res);
+      res.should.eql(user);
+      model.getUser.callCount.should.equal(1);
+      model.getUser.firstCall.args.should.have.length(2);
+      model.getUser.firstCall.args[0].should.equal('foo');
+      model.getUser.firstCall.args[1].should.equal('bar');
+      model.getUser.firstCall.thisValue.should.equal(model);
+
     });
   });
 
   describe('saveToken()', function() {
-    it('should call `model.saveToken()`', function() {
+
+    it('should call `model.saveToken()`', async function() {
+
       const client = {};
       const user = {};
+      
       const model = {
-        getUser: function() {},
-        saveToken: sinon.stub().returns(true)
+        getUser: sinon.stub().resolves(user),
+        saveToken: sinon.stub().resolves(true)
       };
-      const handler = new PasswordGrantType({ accessTokenLifetime: 120, model: model });
-
-      sinon.stub(handler, 'validateScope').returns('foobar');
-      sinon.stub(handler, 'generateAccessToken').returns('foo');
-      sinon.stub(handler, 'generateRefreshToken').returns('bar');
-      sinon.stub(handler, 'getAccessTokenExpiresAt').returns('biz');
-      sinon.stub(handler, 'getRefreshTokenExpiresAt').returns('baz');
-
-      return handler.saveToken(user, client, 'foobar')
-        .then(function() {
-          model.saveToken.callCount.should.equal(1);
-          model.saveToken.firstCall.args.should.have.length(3);
-          model.saveToken.firstCall.args[0].should.eql({ accessToken: 'foo', accessTokenExpiresAt: 'biz', refreshToken: 'bar', refreshTokenExpiresAt: 'baz', scope: 'foobar' });
-          model.saveToken.firstCall.args[1].should.equal(client);
-          model.saveToken.firstCall.args[2].should.equal(user);
-          model.saveToken.firstCall.thisValue.should.equal(model);
-        })
-        .catch(should.fail);
+      const handler = new PasswordGrantType({
+        accessTokenLifetime: 120,
+        model: model
+      });
+
+      sinon.stub(handler, 'validateScope').resolves('foobar');
+      sinon.stub(handler, 'generateAccessToken').resolves('foo');
+      sinon.stub(handler, 'generateRefreshToken').resolves('bar');
+      sinon.stub(handler, 'getAccessTokenExpiresAt').resolves('biz');
+      sinon.stub(handler, 'getRefreshTokenExpiresAt').resolves('baz');
+
+      let res;
+
+      try {
+        res = await handler.saveToken(user, client, 'foobar');
+      } catch (err) {
+        should.fail(err);
+      }
+
+      should.exist(res);
+      res.should.eql(true);
+
+      model.saveToken.callCount.should.equal(1);
+      model.saveToken.firstCall.args.should.have.length(3);
+      model.saveToken.firstCall.args[0].should.eql({ 
+        accessToken: 'foo',
+        accessTokenExpiresAt: 'biz',
+        refreshToken: 'bar',
+        refreshTokenExpiresAt: 'baz',
+        scope: 'foobar'
+      });
+      model.saveToken.firstCall.args[1].should.equal(client);
+      model.saveToken.firstCall.args[2].should.equal(user);
+      model.saveToken.firstCall.thisValue.should.equal(model);
+
     });
+
   });
 });
diff --git a/test/unit/handlers/authorize-handler_test.js b/test/unit/handlers/authorize-handler_test.js
index 86ce336..82ec475 100644
--- a/test/unit/handlers/authorize-handler_test.js
+++ b/test/unit/handlers/authorize-handler_test.js
@@ -7,7 +7,6 @@
 const AuthorizeHandler = require('../../../lib/handlers/authorize-handler');
 const Request = require('../../../lib/request');
 const Response = require('../../../lib/response');
-const Promise = require('bluebird');
 const sinon = require('sinon');
 const should = require('chai').should();
 
@@ -16,15 +15,22 @@ const should = require('chai').should();
  */
 
 describe('AuthorizeHandler', function() {
+
   describe('generateAuthorizationCode()', function() {
+
     it('should call `model.generateAuthorizationCode()`', function() {
+
       const model = {
-        generateAuthorizationCode: sinon.stub().returns({}),
+        generateAuthorizationCode: sinon.stub().resolves({}),
         getAccessToken: function() {},
         getClient: function() {},
         saveAuthorizationCode: function() {}
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
+
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
 
       return handler.generateAuthorizationCode()
         .then(function() {
@@ -32,18 +38,35 @@ describe('AuthorizeHandler', function() {
           model.generateAuthorizationCode.firstCall.thisValue.should.equal(model);
         })
         .catch(should.fail);
+
     });
+
   });
 
   describe('getClient()', function() {
+
     it('should call `model.getClient()`', function() {
+
       const model = {
         getAccessToken: function() {},
-        getClient: sinon.stub().returns({ grants: ['authorization_code'], redirectUris: ['http://example.com/cb'] }),
+        getClient: sinon.stub().resolves({
+          grants: ['authorization_code'],
+          redirectUris: ['http://example.com/cb']
+        }),
         saveAuthorizationCode: function() {}
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
-      const request = new Request({ body: { client_id: 12345, client_secret: 'secret' }, headers: {}, method: {}, query: {} });
+
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
+
+      const request = new Request({
+        body: { client_id: 12345, client_secret: 'secret' },
+        headers: {},
+        method: {},
+        query: {},
+      });
 
       return handler.getClient(request)
         .then(function() {
@@ -57,14 +80,31 @@ describe('AuthorizeHandler', function() {
   });
 
   describe('getUser()', function() {
+
     it('should call `authenticateHandler.getUser()`', function() {
-      const authenticateHandler = { handle: sinon.stub().returns(Promise.resolve({})) };
+
+      const authenticateHandler = { 
+        handle: sinon.stub().resolves({id:'1234'})
+      };
+
       const model = {
         getClient: function() {},
         saveAuthorizationCode: function() {}
       };
-      const handler = new AuthorizeHandler({ authenticateHandler: authenticateHandler, authorizationCodeLifetime: 120, model: model });
-      const request = new Request({ body: {}, headers: {}, method: {}, query: {} });
+
+      const handler = new AuthorizeHandler({
+        authenticateHandler: authenticateHandler,
+        authorizationCodeLifetime: 120,
+        model: model
+      });
+
+      const request = new Request({
+        body: {},
+        headers: {},
+        method: {},
+        query: {}
+      });
+
       const response = new Response();
 
       return handler.getUser(request, response)
@@ -75,28 +115,51 @@ describe('AuthorizeHandler', function() {
           authenticateHandler.handle.firstCall.args[1].should.equal(response);
         })
         .catch(should.fail);
+
     });
+
   });
 
   describe('saveAuthorizationCode()', function() {
+
     it('should call `model.saveAuthorizationCode()`', function() {
+
+      const authorizationCode = 'foo';
+      const expiresAt = 'bar';
+      const redirectUri = 'baz';
+      const scope = 'qux';
+      const client = 'client';
+      const user = 'user';
+      
       const model = {
         getAccessToken: function() {},
         getClient: function() {},
-        saveAuthorizationCode: sinon.stub().returns({})
+        saveAuthorizationCode: sinon.stub().resolves({})
       };
-      const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
+      
+      const handler = new AuthorizeHandler({
+        authorizationCodeLifetime: 120,
+        model: model
+      });
 
-      return handler.saveAuthorizationCode('foo', 'bar', 'qux', 'biz', 'baz', 'boz')
+      return handler.saveAuthorizationCode(authorizationCode, expiresAt, scope, client, redirectUri, user)
         .then(function() {
           model.saveAuthorizationCode.callCount.should.equal(1);
           model.saveAuthorizationCode.firstCall.args.should.have.length(3);
-          model.saveAuthorizationCode.firstCall.args[0].should.eql({ authorizationCode: 'foo', expiresAt: 'bar', redirectUri: 'baz', scope: 'qux' });
-          model.saveAuthorizationCode.firstCall.args[1].should.equal('biz');
-          model.saveAuthorizationCode.firstCall.args[2].should.equal('boz');
+          model.saveAuthorizationCode.firstCall.args[0].should.eql({
+            authorizationCode: authorizationCode, 
+            expiresAt: expiresAt, 
+            redirectUri: redirectUri, 
+            scope: scope 
+          });
+          model.saveAuthorizationCode.firstCall.args[1].should.equal(client);
+          model.saveAuthorizationCode.firstCall.args[2].should.equal(user);
           model.saveAuthorizationCode.firstCall.thisValue.should.equal(model);
         })
         .catch(should.fail);
+
     });
+
+
   });
 });