docs: function promise() {
      var deferred = [];   // this function calls the functions supplied by then()
  
      var assimilatedPromises = arguments;
      var assimilatedNum = assimilatedPromises.length;
      var numCompleted = 0; // number of completed, assimilated promises
      var rejectionHandlerNum = 0;
  
      var obj = new Promise();
  
      obj['errHandled'] = function() {
        rejectionHandlerNum++;
        if (obj['parent'])
          obj['parent']['errHandled']();
      };
  
      /*$
       * @id fire
       * @name promise.fire()
       * @syntax _.fire(newState)
       * @syntax _.fire(newState, values)
       * @module WEB+UTIL
       *
       * Changes the state of the promise into either fulfilled or rejected. This will also notify all ##then() handlers. If the promise
       * already has a state, the call will be ignored.
       *
       * <var>fire()</var> can be invoked as a function without context ('this'). Every promise has its own instance.
       *
       * @example A simple promise that is fulfilled after 1 second, using Minified's invocation syntax:
       * <pre>var p = _.promise();
       * setTimeout(function() {
       *     p.fire(true, []);
       * }, 1000);
       * </pre>
       *
       * @example Call <var>fire()</var> without a context:
       * <pre>var p = _.promise(function(resolve, reject) {
       *     setTimeout(resolve.fire, 1000);
       * });
       * </pre>
       *
       * @param newState <var>true</var> to set the Promise to fulfilled, <var>false</var> to set the state as rejected. If you pass <var>null</var> or
       * <var>undefined</var>, the promise's state does not change.
       * @param values optional an array of values to pass to ##then() handlers as arguments. You can also pass a non-list argument, which will then
       *               be passed as only argument.
       * @return the promise
       */
      var fire = obj['fire'] = function(newState, newValues) {
        if (obj['state'] == null && newState != null) {
          obj['state'] = !!newState;
          obj['values'] = isList(newValues) ? newValues : [newValues];
          setTimeout(function() {
            each(deferred, function(f) {f();});
          }, 0);
        }
        return obj;
      };
  
      // use promise varargs
      each(assimilatedPromises, function assimilate(promise, index) {
        try {
          if (promise['then'])
            promise['then'](function(v) {
                var then;
                if ((isObject(v) || isFunction(v)) && isFunction(then = v['then']))
                  assimilate(v, index);
                else {
                  obj['values'][index] = array(arguments);
                  if (++numCompleted == assimilatedNum)
                    fire(true, assimilatedNum < 2 ? obj['values'][index] : obj['values']);
                }
              },
              function(e) {
                obj['values'][index] = array(arguments);
                fire(false, assimilatedNum < 2 ? obj['values'][index] : [obj['values'][index][0], obj['values'], index]);
              });
          else
            promise(function() {fire(true, array(arguments));}, function() {fire(false, array(arguments)); });
        }
        catch (e) {
          fire(false, [e, obj['values'], index]);
        }
      });
  
      /*$
       * @id stop
       * @name promise.stop()
       * @syntax promise.stop()
       * @module WEB+UTIL
       * Stops an ongoing operation, if supported. Currently the only promises supporting this are those returned by ##request(), ##animate(), ##wait() and
       * ##asyncEach().
       * stop() invocation will be propagated over promises returned by ##then() and promises assimilated by ##promise(). You only need to invoke stop
       * with the last promise, and all dependent promises will automatically stop as well.
       *
       *  <var>stop()</var> can be invoked as a function without context ('this'). Every promise has its own instance.
       *
       * @return In some cases, the <var>stop()</var> can return a value. This is currently only done by ##animate() and ##wait(), which will return the actual duration.
       *         ##asyncEach()'s promise will also return any value it got from the promise that it stopped.
       *
       * @example Animation chain that can be stopped.
       * <pre>
       * var div = $('#myMovingDiv').set({$left: '0px', $top: '0px'});
       * var prom = div.animate({$left: '200px', $top: '0px'}, 600, 0)
       *    .then(function() {
       *           return _.promise(div.animate({$left: '200px', $top: '200px'}, 800, 0),
       *                            div.animate({$backgroundColor: '#f00'}, 200));
       *    }).then(function() {
       *           return div.animate({$left: '100px', $top: '100px'}, 400);
       *    });
       *
       * $('#stopButton').on('click', prom.stop);
       * </pre>
       */
      obj['stop'] = function() {
        each(assimilatedPromises, function(promise) {
          if (promise['stop'])
            promise['stop']();
        });
  
        return obj['stop0'] && call(obj['stop0']);
      };
  
      /*$
       * @id then
       * @name promise.then()
       * @syntax promise.then()
       * @syntax promise.then(onSuccess)
       * @syntax promise.then(onSuccess, onError)
       *
       * @module WEB
       * Registers two callbacks that will be invoked when the ##promise#Promise##'s asynchronous operation finished
       * successfully (<var>onSuccess</var>) or an error occurred (<var>onError</var>). The callbacks will be called after
       * <var>then()</var> returned, from the browser's event loop.
       * You can chain <var>then()</var> invocations, as <var>then()</var> returns another Promise object that you can attach to.
       *
       * The full distribution of Minified implements the Promises/A+ specification, allowing interoperability with other Promises frameworks.
       *
       * <strong>Note:</strong> If you use the Web module, you will get a simplified Promises implementation that cuts some corners. The most notable
       * difference is that when a <code>then()</code> handler throws an exception, this will not be caught and the promise returned by
       * <code>then</code> will not be automatically rejected.
       *
       * @example Simple handler for an HTTP request. Handles only success and ignores errors.
       * <pre>
       * $.request('get', '/weather.html')
       *     .then(function(txt) {
       *        alert('Got response!');
       *     });
       * </pre>
       *
       * @example Including an error handler.
       * <pre>
       * $.request('get', '/weather.html')
       *     .then(function(txt) {
       *        alert('Got response!');
       *     }, function(err) {
       *        alert('Error!');
       *     }));
       * </pre>
       *
       * @example Chained handler.
       * <pre>
       * $.request('get', '/weather.do')
       *     .then(function(txt) {
       *        showWeather(txt);
       *     }
       *     .then(function() {
       *        return $.request('get', '/traffic.do');
       *     }
       *     .then(function(txt) {
       *        showTraffic(txt);
       *     }
       *     .then(function() {
       *        alert('All result displayed');
       *     }, function() {
       *        alert('An error occurred');
       *     });
       * </pre>
       *
       * @param onSuccess optional a callback function to be called when the operation has been completed successfully. The exact arguments it receives depend on the operation.
       *                           If the function returns a ##promise#Promise##, that Promise will be evaluated to determine the state of the promise returned by <var>then()</var>. If it returns any other value, the
       *                           returned Promise will also succeed. If the function throws an error, the returned Promise will be in error state.
       *                           Pass <var>null</var> or <var>undefined</var> if you do not need the success handler.
       * @param onError optional a callback function to be called when the operation failed. The exact arguments it receives depend on the operation. If the function returns a ##promise#Promise##, that promise will
       *                           be evaluated to determine the state of the Promise returned by <var>then()</var>. If it returns anything else, the returned Promise will
       *                           have success status. If the function throws an error, the returned Promise will be in the error state.
       *                           You can pass <var>null</var> or <var>undefined</var> if you do not need the error handler.
       * @return a new ##promise#Promise## object. If you specified a callback for success or error, the new Promises's state will be determined by that callback if it is called.
       *         If no callback has been provided and the original Promise changes to that state, the new Promise will change to that state as well.
       */
      var then = obj['then'] = function (onFulfilled, onRejected) {
        var promise2 = promise();
        var callCallbacks = function() {
          try {
            var f = (obj['state'] ? onFulfilled : onRejected);
            if (isFunction(f)) {
              (function resolve(x) {
                try {
                  var then, cbCalled = 0;
                  if ((isObject(x) || isFunction(x)) && isFunction(then = x['then'])) {
                    if (x === promise2)
                      throw new TypeError();
                    then.call(x, function(x) { if (!cbCalled++) resolve(x); }, function(value) { if (!cbCalled++) promise2['fire'](false, [value]);});
                    promise2['stop0'] = x['stop'];
                  }
                  else
                    promise2['fire'](true, [x]);
                }
                catch(e) {
                  if (!(cbCalled++)) {
                    promise2['fire'](false, [e]);
                    if (!rejectionHandlerNum)
                      throw e;
                  }
                }
              })(call(f, undef, obj['values']));
            }
            else
              promise2['fire'](obj['state'], obj['values']);
          }
          catch (e) {
            promise2['fire'](false, [e]);
            if (!rejectionHandlerNum)
              throw e;
          }
        };
        if (isFunction(onRejected))
          obj['errHandled']();
        promise2['stop0'] = obj['stop'];
        promise2['parent'] = obj;
        if (obj['state'] != null)
          setTimeout(callCallbacks, 0);
        else
          deferred.push(callCallbacks);
        return promise2;
      };
  
      /*$
       * @id always
       * @group REQUEST
       * @name promise.always()
       * @syntax promise.always(callback)
       * @configurable default
       * @module WEB+UTIL
       * Registers a callback that will always be called when the ##promise#Promise##'s operation ended, no matter whether the operation succeeded or not.
       * This is a convenience function that will call ##then() with the same function for both arguments. It shares all of its semantics.
       *
       * @example Simple handler for a HTTP request.
       * <pre>
       * $.request('get', '/weather.html')
       *     .always(function() {
       *        alert('Got response or error!');
       *     });
       * </pre>
       *
       * @param callback a function to be called when the operation has been finished, no matter what its result was. The exact arguments depend on the operation and may
       *                 vary depending on whether it succeeded or not. If the function returns a ##promise#Promise##, that Promise will
       *                 be evaluated to determine the state of the returned Promise. If provided and it returns regularly, the returned promise will
       *                 have success status. If it throws an error, the returned Promise will be in the error state.
       * @return a new ##promise#Promise## object. Its state is determined by the callback.
       */
      obj['always'] = function(func) { return then(func, func); };
  
      /*$
       * @id error
       * @group REQUEST
       * @name promise.error()
       * @syntax promise.error(callback)
       * @configurable default
       * @module WEB, UTIL
       * Registers a callback that will be called when the operation failed.
       * This is a convenience function that will invoke ##then() with only the second argument set.  It shares all of its semantics.
       *
       * @example Simple handler for a HTTP request.
       * <pre>
       * $.request('get', '/weather.html')
       *     .error(function() {
       *        alert('Got error!');
       *     });
       * </pre>
       *
       * @param callback a function to be called when the operation has failed. The exact arguments depend on the operation. If the function returns a ##promise#Promise##, that Promise will
       *                           be evaluated to determine the state of the returned Promise. If it returns regularly, the returned Promise will
       *                           have success status. If it throws an error, the returned Promise will be in error state.
       * @return a new ##promise#Promise## object. Its state is determined by the callback.
       */
      obj['error'] = function(func) { return then(0, func); };
  
      return obj;
    }