refactor with promisify helper

refactor getToken, signin, and getProfile with promisify for a more standard Promise interface. You see the benefit the signin refactor

getToken
```javascript
      auth.getToken = function(clientID, options) {
        options = options || { scope: 'openid' };

        var getDelegationTokenAsync = promisify(config.auth0js.getDelegationToken, applied);

        return getDelegationTokenAsync(clientID, auth.idToken, options).then(function(delegationResult) {
          return delegationResult.id_token;
        });
      };
```

signin
```javascript
      auth.signin = function(options, lib) {
        options = options || {};
        checkHandlers(options);

        var auth0lib = lib || config.auth0lib;

        var signinPromisify = promisify(auth0lib.signin, applied);
        var signinAsync = (config.isWidget) ? signinPromisify(options, null) : signinPromisify(options);

        // Monkey patch promisify promise for .spread()
        return signinAsync.spread(function(profile, idToken, accessToken, state) {
          return onSigninOk(idToken, accessToken, state);
        // bracket notation for IE support
        })['catch'](function(err) {
          callHandler('loginFailure', {error: err});
          return err;
        });
      };
```

getProfile
```javascript
      auth.getProfile = function(idToken) {
        var getProfileAsync = promisify(config.auth0lib.getProfile, applied);

        return getProfileAsync(idToken || auth.idToken).then(function(profile) {
          auth.profile = profile;
          return profile;
        });
      };
```
promisify helper
```javascript
      var promisify = function(nodeback, func) {
        // Allow user to apply wrapper around callback
        var _applied = func || function(fn) { return function() {return fn(); }; };
        if (angular.isFunction(nodeback)) {
          return function(args) {
            args = Array.prototype.slice.call(arguments);
            var dfd = $q.defer();

            args.push(_applied(function(err, response, etc) {
              if (err) {
                dfd.reject(err);
              }
              // if more arguments then turn into an array for spread
              etc = Array.prototype.slice.call(arguments, 1);
              dfd.resolve((etc.length > 1) ? etc : response);
            }));
            nodeback.apply(this, args);

            // spread polyfill only for promisify
            dfd.promise.spread = dfd.promise.spread || function(fulfilled, rejected) {
              return dfd.promise.then(function(array) {
                return (Array.isArray(array)) ? fulfilled.apply(null, array) : func(array);
              }, rejected);
            };

            return dfd.promise;
          };
        } else {
          return angular.noop;
        }
      };
```
What is this spread?