text: /**
   * The MIT License (MIT)
   * 
   * Copyright (c) 2014 Petka Antonov
   * 
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:</p>
   * 
   * The above copyright notice and this permission notice shall be included in
   * all copies or substantial portions of the Software.
   * 
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   * THE SOFTWARE.
   * 
   */
  "use strict";
  var old;
  if (typeof Promise !== "undefined") old = Promise;
  function noConflict(bluebird) {
      try { if (Promise === bluebird) Promise = old; }
      catch (e) {}
      return bluebird;
  }
  module.exports = function() {
  var util = require("./util.js");
  var async = require("./async.js");
  var errors = require("./errors.js");
  
  var INTERNAL = function(){};
  var APPLY = {};
  var NEXT_FILTER = {e: null};
  
  var cast = require("./thenables.js")(Promise, INTERNAL);
  var PromiseArray = require("./promise_array.js")(Promise, INTERNAL, cast);
  var CapturedTrace = require("./captured_trace.js")();
  var CatchFilter = require("./catch_filter.js")(NEXT_FILTER);
  var PromiseResolver = require("./promise_resolver.js");
  
  var isArray = util.isArray;
  
  var errorObj = util.errorObj;
  var tryCatch1 = util.tryCatch1;
  var tryCatch2 = util.tryCatch2;
  var tryCatchApply = util.tryCatchApply;
  var RangeError = errors.RangeError;
  var TypeError = errors.TypeError;
  var CancellationError = errors.CancellationError;
  var TimeoutError = errors.TimeoutError;
  var OperationalError = errors.OperationalError;
  var originatesFromRejection = errors.originatesFromRejection;
  var markAsOriginatingFromRejection = errors.markAsOriginatingFromRejection;
  var canAttach = errors.canAttach;
  var thrower = util.thrower;
  var apiRejection = require("./errors_api_rejection")(Promise);
  
  
  var makeSelfResolutionError = function Promise$_makeSelfResolutionError() {
      return new TypeError("circular promise resolution chain");
  };
  
  function Promise(resolver) {
      if (typeof resolver !== "function") {
          throw new TypeError("the promise constructor requires a resolver function");
      }
      if (this.constructor !== Promise) {
          throw new TypeError("the promise constructor cannot be invoked directly");
      }
      this._bitField = 0;
      this._fulfillmentHandler0 = void 0;
      this._rejectionHandler0 = void 0;
      this._promise0 = void 0;
      this._receiver0 = void 0;
      this._settledValue = void 0;
      this._boundTo = void 0;
      if (resolver !== INTERNAL) this._resolveFromResolver(resolver);
  }
  
  function returnFirstElement(elements) {
      return elements[0];
  }
  
  Promise.prototype.bind = function Promise$bind(thisArg) {
      var maybePromise = cast(thisArg, void 0);
      var ret = new Promise(INTERNAL);
      if (maybePromise instanceof Promise) {
          var binder = maybePromise.then(function(thisArg) {
              ret._setBoundTo(thisArg);
          });
          var p = Promise.all([this, binder]).then(returnFirstElement);
          ret._follow(p);
      } else {
          ret._follow(this);
          ret._setBoundTo(thisArg);
      }
      ret._propagateFrom(this, 2 | 1);
      return ret;
  };
  
  Promise.prototype.toString = function Promise$toString() {
      return "[object Promise]";
  };
  
  Promise.prototype.caught = Promise.prototype["catch"] =
  function Promise$catch(fn) {
      var len = arguments.length;
      if (len > 1) {
          var catchInstances = new Array(len - 1),
              j = 0, i;
          for (i = 0; i < len - 1; ++i) {
              var item = arguments[i];
              if (typeof item === "function") {
                  catchInstances[j++] = item;
              } else {
                  var catchFilterTypeError =
                      new TypeError(
                          "A catch filter must be an error constructor "
                          + "or a filter function");
  
                  this._attachExtraTrace(catchFilterTypeError);
                  return Promise.reject(catchFilterTypeError);
              }
          }
          catchInstances.length = j;
          fn = arguments[i];
  
          this._resetTrace();
          var catchFilter = new CatchFilter(catchInstances, fn, this);
          return this._then(void 0, catchFilter.doFilter, void 0,
              catchFilter, void 0);
      }
      return this._then(void 0, fn, void 0, void 0, void 0);
  };
  
  function reflect() {
      return new Promise.PromiseInspection(this);
  }
  
  Promise.prototype.reflect = function Promise$reflect() {
      return this._then(reflect, reflect, void 0, this, void 0);
  };
  
  Promise.prototype.then =
  function Promise$then(didFulfill, didReject, didProgress) {
      return this._then(didFulfill, didReject, didProgress,
          void 0, void 0);
  };
  
  
  Promise.prototype.done =
  function Promise$done(didFulfill, didReject, didProgress) {
      var promise = this._then(didFulfill, didReject, didProgress,
          void 0, void 0);
      promise._setIsFinal();
  };
  
  Promise.prototype.spread = function Promise$spread(didFulfill, didReject) {
      return this._then(didFulfill, didReject, void 0,
          APPLY, void 0);
  };
  
  Promise.prototype.isCancellable = function Promise$isCancellable() {
      return !this.isResolved() &&
          this._cancellable();
  };
  
  Promise.prototype.toJSON = function Promise$toJSON() {
      var ret = {
          isFulfilled: false,
          isRejected: false,
          fulfillmentValue: void 0,
          rejectionReason: void 0
      };
      if (this.isFulfilled()) {
          ret.fulfillmentValue = this._settledValue;
          ret.isFulfilled = true;
      } else if (this.isRejected()) {
          ret.rejectionReason = this._settledValue;
          ret.isRejected = true;
      }
      return ret;
  };
  
  Promise.prototype.all = function Promise$all() {
      return new PromiseArray(this).promise();
  };
  
  
  Promise.is = function Promise$Is(val) {
      return val instanceof Promise;
  };
  
  Promise.all = function Promise$All(promises) {
      return new PromiseArray(promises).promise();
  };
  
  Promise.prototype.error = function Promise$_error(fn) {
      return this.caught(originatesFromRejection, fn);
  };
  
  Promise.prototype._resolveFromSyncValue =
  function Promise$_resolveFromSyncValue(value) {
      if (value === errorObj) {
          this._cleanValues();
          this._setRejected();
          var reason = value.e;
          this._settledValue = reason;
          this._tryAttachExtraTrace(reason);
          this._ensurePossibleRejectionHandled();
      } else {
          var maybePromise = cast(value, void 0);
          if (maybePromise instanceof Promise) {
              this._follow(maybePromise);
          } else {
              this._cleanValues();
              this._setFulfilled();
              this._settledValue = value;
          }
      }
  };
  
  Promise.method = function Promise$_Method(fn) {
      if (typeof fn !== "function") {
          throw new TypeError("fn must be a function");
      }
      return function Promise$_method() {
          var value;
          switch(arguments.length) {
          case 0: value = tryCatch1(fn, this, void 0); break;
          case 1: value = tryCatch1(fn, this, arguments[0]); break;
          case 2: value = tryCatch2(fn, this, arguments[0], arguments[1]); break;
          default:
              var $_len = arguments.length;var args = new Array($_len); for(var $_i = 0; $_i < $_len; ++$_i) {args[$_i] = arguments[$_i];}
              value = tryCatchApply(fn, args, this); break;
          }
          var ret = new Promise(INTERNAL);
          ret._setTrace(void 0);
          ret._resolveFromSyncValue(value);
          return ret;
      };
  };
  
  Promise.attempt = Promise["try"] = function Promise$_Try(fn, args, ctx) {
      if (typeof fn !== "function") {
          return apiRejection("fn must be a function");
      }
      var value = isArray(args)
          ? tryCatchApply(fn, args, ctx)
          : tryCatch1(fn, ctx, args);
  
      var ret = new Promise(INTERNAL);
      ret._setTrace(void 0);
      ret._resolveFromSyncValue(value);
      return ret;
  };
  
  Promise.defer = Promise.pending = function Promise$Defer() {
      var promise = new Promise(INTERNAL);
      promise._setTrace(void 0);
      return new PromiseResolver(promise);
  };
  
  Promise.bind = function Promise$Bind(thisArg) {
      var maybePromise = cast(thisArg, void 0);
      var ret = new Promise(INTERNAL);
      ret._setTrace(void 0);
  
      if (maybePromise instanceof Promise) {
          var p = maybePromise.then(function(thisArg) {
              ret._setBoundTo(thisArg);
          });
          ret._follow(p);
      } else {
          ret._setBoundTo(thisArg);
          ret._setFulfilled();
      }
      return ret;
  };
  
  Promise.cast = function Promise$_Cast(obj) {
      var ret = cast(obj, void 0);
      if (!(ret instanceof Promise)) {
          var val = ret;
          ret = new Promise(INTERNAL);
          ret._setTrace(void 0);
          ret._setFulfilled();
          ret._cleanValues();
          ret._settledValue = val;
      }
      return ret;
  };
  
  Promise.resolve = Promise.fulfilled = Promise.cast;
  
  Promise.reject = Promise.rejected = function Promise$Reject(reason) {
      var ret = new Promise(INTERNAL);
      ret._setTrace(void 0);
      markAsOriginatingFromRejection(reason);
      ret._cleanValues();
      ret._setRejected();
      ret._settledValue = reason;
      if (!canAttach(reason)) {
          var trace = new Error(reason + "");
          ret._setCarriedStackTrace(trace);
      }
      ret._ensurePossibleRejectionHandled();
      return ret;
  };
  
  Promise.onPossiblyUnhandledRejection =
  function Promise$OnPossiblyUnhandledRejection(fn) {
          CapturedTrace.possiblyUnhandledRejection = typeof fn === "function"
                                                      ? fn : void 0;
  };
  
  var unhandledRejectionHandled;
  Promise.onUnhandledRejectionHandled =
  function Promise$onUnhandledRejectionHandled(fn) {
      unhandledRejectionHandled = typeof fn === "function" ? fn : void 0;
  };
  
  var debugging = false || !!(
      typeof process !== "undefined" &&
      typeof process.execPath === "string" &&
      typeof process.env === "object" &&
      (process.env["BLUEBIRD_DEBUG"] ||
          process.env["NODE_ENV"] === "development")
  );
  
  
  Promise.longStackTraces = function Promise$LongStackTraces() {
      if (async.haveItemsQueued() &&
          debugging === false
     ) {
          throw new Error("cannot enable long stack traces after promises have been created");
      }
      debugging = CapturedTrace.isSupported();
  };
  
  Promise.hasLongStackTraces = function Promise$HasLongStackTraces() {
      return debugging && CapturedTrace.isSupported();
  };
  
  Promise.prototype._then =
  function Promise$_then(
      didFulfill,
      didReject,
      didProgress,
      receiver,
      internalData
  ) {
      var haveInternalData = internalData !== void 0;
      var ret = haveInternalData ? internalData : new Promise(INTERNAL);
  
      if (!haveInternalData) {
          if (debugging) {
              var haveSameContext = this._peekContext() === this._traceParent;
              ret._traceParent = haveSameContext ? this._traceParent : this;
          }
          ret._propagateFrom(this, 7);
      }
  
      var callbackIndex =
          this._addCallbacks(didFulfill, didReject, didProgress, ret, receiver);
  
      if (this.isResolved()) {
          async.invoke(this._queueSettleAt, this, callbackIndex);
      }
  
      return ret;
  };
  
  Promise.prototype._length = function Promise$_length() {
      return this._bitField & 262143;
  };
  
  Promise.prototype._isFollowingOrFulfilledOrRejected =
  function Promise$_isFollowingOrFulfilledOrRejected() {
      return (this._bitField & 939524096) > 0;
  };
  
  Promise.prototype._isFollowing = function Promise$_isFollowing() {
      return (this._bitField & 536870912) === 536870912;
  };
  
  Promise.prototype._setLength = function Promise$_setLength(len) {
      this._bitField = (this._bitField & -262144) |
          (len & 262143);
  };
  
  Promise.prototype._setFulfilled = function Promise$_setFulfilled() {
      this._bitField = this._bitField | 268435456;
  };
  
  Promise.prototype._setRejected = function Promise$_setRejected() {
      this._bitField = this._bitField | 134217728;
  };
  
  Promise.prototype._setFollowing = function Promise$_setFollowing() {
      this._bitField = this._bitField | 536870912;
  };
  
  Promise.prototype._setIsFinal = function Promise$_setIsFinal() {
      this._bitField = this._bitField | 33554432;
  };
  
  Promise.prototype._isFinal = function Promise$_isFinal() {
      return (this._bitField & 33554432) > 0;
  };
  
  Promise.prototype._cancellable = function Promise$_cancellable() {
      return (this._bitField & 67108864) > 0;
  };
  
  Promise.prototype._setCancellable = function Promise$_setCancellable() {
      this._bitField = this._bitField | 67108864;
  };
  
  Promise.prototype._unsetCancellable = function Promise$_unsetCancellable() {
      this._bitField = this._bitField & (~67108864);
  };
  
  Promise.prototype._setRejectionIsUnhandled =
  function Promise$_setRejectionIsUnhandled() {
      this._bitField = this._bitField | 2097152;
  };
  
  Promise.prototype._unsetRejectionIsUnhandled =
  function Promise$_unsetRejectionIsUnhandled() {
      this._bitField = this._bitField & (~2097152);
      if (this._isUnhandledRejectionNotified()) {
          this._unsetUnhandledRejectionIsNotified();
          this._notifyUnhandledRejectionIsHandled();
      }
  };
  
  Promise.prototype._isRejectionUnhandled =
  function Promise$_isRejectionUnhandled() {
      return (this._bitField & 2097152) > 0;
  };
  
  Promise.prototype._setUnhandledRejectionIsNotified =
  function Promise$_setUnhandledRejectionIsNotified() {
      this._bitField = this._bitField | 524288;
  };
  
  Promise.prototype._unsetUnhandledRejectionIsNotified =
  function Promise$_unsetUnhandledRejectionIsNotified() {
      this._bitField = this._bitField & (~524288);
  };
  
  Promise.prototype._isUnhandledRejectionNotified =
  function Promise$_isUnhandledRejectionNotified() {
      return (this._bitField & 524288) > 0;
  };
  
  Promise.prototype._setCarriedStackTrace =
  function Promise$_setCarriedStackTrace(capturedTrace) {
      this._bitField = this._bitField | 1048576;
      this._fulfillmentHandler0 = capturedTrace;
  };
  
  Promise.prototype._unsetCarriedStackTrace =
  function Promise$_unsetCarriedStackTrace() {
      this._bitField = this._bitField & (~1048576);
      this._fulfillmentHandler0 = void 0;
  };
  
  Promise.prototype._isCarryingStackTrace =
  function Promise$_isCarryingStackTrace() {
      return (this._bitField & 1048576) > 0;
  };
  
  Promise.prototype._getCarriedStackTrace =
  function Promise$_getCarriedStackTrace() {
      return this._isCarryingStackTrace()
          ? this._fulfillmentHandler0
          : void 0;
  };
  
  Promise.prototype._receiverAt = function Promise$_receiverAt(index) {
      var ret = index === 0
          ? this._receiver0
          : this[(index << 2) + index - 5 + 4];
      if (this._isBound() && ret === void 0) {
          return this._boundTo;
      }
      return ret;
  };
  
  Promise.prototype._promiseAt = function Promise$_promiseAt(index) {
      return index === 0
          ? this._promise0
          : this[(index << 2) + index - 5 + 3];
  };
  
  Promise.prototype._fulfillmentHandlerAt =
  function Promise$_fulfillmentHandlerAt(index) {
      return index === 0
          ? this._fulfillmentHandler0
          : this[(index << 2) + index - 5 + 0];
  };
  
  Promise.prototype._rejectionHandlerAt =
  function Promise$_rejectionHandlerAt(index) {
      return index === 0
          ? this._rejectionHandler0
          : this[(index << 2) + index - 5 + 1];
  };
  
  Promise.prototype._addCallbacks = function Promise$_addCallbacks(
      fulfill,
      reject,
      progress,
      promise,
      receiver
  ) {
      var index = this._length();
  
      if (index >= 262143 - 5) {
          index = 0;
          this._setLength(0);
      }
  
      if (index === 0) {
          this._promise0 = promise;
          if (receiver !== void 0) this._receiver0 = receiver;
          if (typeof fulfill === "function" && !this._isCarryingStackTrace())
              this._fulfillmentHandler0 = fulfill;
          if (typeof reject === "function") this._rejectionHandler0 = reject;
          if (typeof progress === "function") this._progressHandler0 = progress;
      } else {
          var base = (index << 2) + index - 5;
          this[base + 3] = promise;
          this[base + 4] = receiver;
          this[base + 0] = typeof fulfill === "function"
                                              ? fulfill : void 0;
          this[base + 1] = typeof reject === "function"
                                              ? reject : void 0;
          this[base + 2] = typeof progress === "function"
                                              ? progress : void 0;
      }
      this._setLength(index + 1);
      return index;
  };
  
  Promise.prototype._setProxyHandlers =
  function Promise$_setProxyHandlers(receiver, promiseSlotValue) {
      var index = this._length();
  
      if (index >= 262143 - 5) {
          index = 0;
          this._setLength(0);
      }
      if (index === 0) {
          this._promise0 = promiseSlotValue;
          this._receiver0 = receiver;
      } else {
          var base = (index << 2) + index - 5;
          this[base + 3] = promiseSlotValue;
          this[base + 4] = receiver;
          this[base + 0] =
          this[base + 1] =
          this[base + 2] = void 0;
      }
      this._setLength(index + 1);
  };
  
  Promise.prototype._proxyPromiseArray =
  function Promise$_proxyPromiseArray(promiseArray, index) {
      this._setProxyHandlers(promiseArray, index);
  };
  
  Promise.prototype._proxyPromise = function Promise$_proxyPromise(promise) {
      promise._setProxied();
      this._setProxyHandlers(promise, -15);
  };
  
  Promise.prototype._setBoundTo = function Promise$_setBoundTo(obj) {
      if (obj !== void 0) {
          this._bitField = this._bitField | 8388608;
          this._boundTo = obj;
      } else {
          this._bitField = this._bitField & (~8388608);
      }
  };
  
  Promise.prototype._isBound = function Promise$_isBound() {
      return (this._bitField & 8388608) === 8388608;
  };
  
  Promise.prototype._resolveFromResolver =
  function Promise$_resolveFromResolver(resolver) {
      var promise = this;
      this._setTrace(void 0);
      this._pushContext();
  
      function Promise$_resolver(val) {
          if (promise._tryFollow(val)) {
              return;
          }
          promise._fulfill(val);
      }
      function Promise$_rejecter(val) {
          var trace = canAttach(val) ? val : new Error(val + "");
          promise._attachExtraTrace(trace);
          markAsOriginatingFromRejection(val);
          promise._reject(val, trace === val ? void 0 : trace);
      }
      var r = tryCatch2(resolver, void 0, Promise$_resolver, Promise$_rejecter);
      this._popContext();
  
      if (r !== void 0 && r === errorObj) {
          var e = r.e;
          var trace = canAttach(e) ? e : new Error(e + "");
          promise._reject(e, trace);
      }
  };
  
  Promise.prototype._spreadSlowCase =
  function Promise$_spreadSlowCase(targetFn, promise, values, boundTo) {
      var promiseForAll = new PromiseArray(values).promise();
      var promise2 = promiseForAll._then(function() {
          return targetFn.apply(boundTo, arguments);
      }, void 0, void 0, APPLY, void 0);
      promise._follow(promise2);
  };
  
  Promise.prototype._callSpread =
  function Promise$_callSpread(handler, promise, value) {
      var boundTo = this._boundTo;
      if (isArray(value)) {
          for (var i = 0, len = value.length; i < len; ++i) {
              if (cast(value[i], void 0) instanceof Promise) {
                  this._spreadSlowCase(handler, promise, value, boundTo);
                  return;
              }
          }
      }
      promise._pushContext();
      return tryCatchApply(handler, value, boundTo);
  };
  
  Promise.prototype._callHandler =
  function Promise$_callHandler(
      handler, receiver, promise, value) {
      var x;
      if (receiver === APPLY && !this.isRejected()) {
          x = this._callSpread(handler, promise, value);
      } else {
          promise._pushContext();
          x = tryCatch1(handler, receiver, value);
      }
      promise._popContext();
      return x;
  };
  
  Promise.prototype._settlePromiseFromHandler =
  function Promise$_settlePromiseFromHandler(
      handler, receiver, value, promise
  ) {
      if (!(promise instanceof Promise)) {
          handler.call(receiver, value, promise);
          return;
      }
      if (promise.isResolved()) return;
      var x = this._callHandler(handler, receiver, promise, value);
      if (promise._isFollowing()) return;
  
      if (x === errorObj || x === promise || x === NEXT_FILTER) {
          var err = x === promise
                      ? makeSelfResolutionError()
                      : x.e;
          var trace = canAttach(err) ? err : new Error(err + "");
          if (x !== NEXT_FILTER) promise._attachExtraTrace(trace);
          promise._rejectUnchecked(err, trace);
      } else {
          var castValue = cast(x, promise);
          if (castValue instanceof Promise) {
              if (castValue.isRejected() &&
                  !castValue._isCarryingStackTrace() &&
                  !canAttach(castValue._settledValue)) {
                  var trace = new Error(castValue._settledValue + "");
                  promise._attachExtraTrace(trace);
                  castValue._setCarriedStackTrace(trace);
              }
              promise._follow(castValue);
              promise._propagateFrom(castValue, 1);
          } else {
              promise._fulfillUnchecked(x);
          }
      }
  };
  
  Promise.prototype._follow =
  function Promise$_follow(promise) {
      this._setFollowing();
  
      if (promise.isPending()) {
          this._propagateFrom(promise, 1);
          promise._proxyPromise(this);
      } else if (promise.isFulfilled()) {
          this._fulfillUnchecked(promise._settledValue);
      } else {
          this._rejectUnchecked(promise._settledValue,
              promise._getCarriedStackTrace());
      }
  
      if (promise._isRejectionUnhandled()) promise._unsetRejectionIsUnhandled();
  
      if (debugging &&
          promise._traceParent == null) {
          promise._traceParent = this;
      }
  };
  
  Promise.prototype._tryFollow =
  function Promise$_tryFollow(value) {
      if (this._isFollowingOrFulfilledOrRejected() ||
          value === this) {
          return false;
      }
      var maybePromise = cast(value, void 0);
      if (!(maybePromise instanceof Promise)) {
          return false;
      }
      this._follow(maybePromise);
      return true;
  };
  
  Promise.prototype._resetTrace = function Promise$_resetTrace() {
      if (debugging) {
          this._trace = new CapturedTrace(this._peekContext() === void 0);
      }
  };
  
  Promise.prototype._setTrace = function Promise$_setTrace(parent) {
      if (debugging) {
          var context = this._peekContext();
          this._traceParent = context;
          var isTopLevel = context === void 0;
          if (parent !== void 0 &&
              parent._traceParent === context) {
              this._trace = parent._trace;
          } else {
              this._trace = new CapturedTrace(isTopLevel);
          }
      }
      return this;
  };
  
  Promise.prototype._tryAttachExtraTrace =
  function Promise$_tryAttachExtraTrace(error) {
      if (canAttach(error)) {
          this._attachExtraTrace(error);
      }
  };
  
  Promise.prototype._attachExtraTrace =
  function Promise$_attachExtraTrace(error) {
      if (debugging) {
          var promise = this;
          var stack = error.stack;
          stack = typeof stack === "string" ? stack.split("\n") : [];
          CapturedTrace.protectErrorMessageNewlines(stack);
          var headerLineCount = 1;
          var combinedTraces = 1;
          while(promise != null &&
              promise._trace != null) {
              stack = CapturedTrace.combine(
                  stack,
                  promise._trace.stack.split("\n")
              );
              promise = promise._traceParent;
              combinedTraces++;
          }
  
          var stackTraceLimit = Error.stackTraceLimit || 10;
          var max = (stackTraceLimit + headerLineCount) * combinedTraces;
          var len = stack.length;
          if (len > max) {
              stack.length = max;
          }
  
          if (len > 0)
              stack[0] = stack[0].split("\u0002\u0000\u0001").join("\n");
  
          if (stack.length <= headerLineCount) {
              error.stack = "(No stack trace)";
          } else {
              error.stack = stack.join("\n");
          }
      }
  };
  
  Promise.prototype._cleanValues = function Promise$_cleanValues() {
      if (this._cancellable()) {
          this._cancellationParent = void 0;
      }
  };
  
  Promise.prototype._propagateFrom =
  function Promise$_propagateFrom(parent, flags) {
      if ((flags & 1) > 0 && parent._cancellable()) {
          this._setCancellable();
          this._cancellationParent = parent;
      }
      if ((flags & 4) > 0) {
          this._setBoundTo(parent._boundTo);
      }
      if ((flags & 2) > 0) {
          this._setTrace(parent);
      }
  };
  
  Promise.prototype._fulfill = function Promise$_fulfill(value) {
      if (this._isFollowingOrFulfilledOrRejected()) return;
      this._fulfillUnchecked(value);
  };
  
  Promise.prototype._reject =
  function Promise$_reject(reason, carriedStackTrace) {
      if (this._isFollowingOrFulfilledOrRejected()) return;
      this._rejectUnchecked(reason, carriedStackTrace);
  };
  
  Promise.prototype._settlePromiseAt = function Promise$_settlePromiseAt(index) {
      var handler = this.isFulfilled()
          ? this._fulfillmentHandlerAt(index)
          : this._rejectionHandlerAt(index);
  
      var value = this._settledValue;
      var receiver = this._receiverAt(index);
      var promise = this._promiseAt(index);
  
      if (typeof handler === "function") {
          this._settlePromiseFromHandler(handler, receiver, value, promise);
      } else {
          var done = false;
          var isFulfilled = this.isFulfilled();
          if (receiver !== void 0) {
              if (receiver instanceof Promise &&
                  receiver._isProxied()) {
                  receiver._unsetProxied();
  
                  if (isFulfilled) receiver._fulfillUnchecked(value);
                  else receiver._rejectUnchecked(value,
                      this._getCarriedStackTrace());
                  done = true;
              } else if (receiver instanceof PromiseArray) {
                  if (isFulfilled) receiver._promiseFulfilled(value, promise);
                  else receiver._promiseRejected(value, promise);
                  done = true;
              }
          }
  
          if (!done) {
              if (isFulfilled) promise._fulfill(value);
              else promise._reject(value, this._getCarriedStackTrace());
          }
      }
  
      if (index >= 4) {
          this._queueGC();
      }
  };
  
  Promise.prototype._isProxied = function Promise$_isProxied() {
      return (this._bitField & 4194304) === 4194304;
  };
  
  Promise.prototype._setProxied = function Promise$_setProxied() {
      this._bitField = this._bitField | 4194304;
  };
  
  Promise.prototype._unsetProxied = function Promise$_unsetProxied() {
      this._bitField = this._bitField & (~4194304);
  };
  
  Promise.prototype._isGcQueued = function Promise$_isGcQueued() {
      return (this._bitField & -1073741824) === -1073741824;
  };
  
  Promise.prototype._setGcQueued = function Promise$_setGcQueued() {
      this._bitField = this._bitField | -1073741824;
  };
  
  Promise.prototype._unsetGcQueued = function Promise$_unsetGcQueued() {
      this._bitField = this._bitField & (~-1073741824);
  };
  
  Promise.prototype._queueGC = function Promise$_queueGC() {
      if (this._isGcQueued()) return;
      this._setGcQueued();
      async.invokeLater(this._gc, this, void 0);
  };
  
  Promise.prototype._gc = function Promise$gc() {
      var len = this._length() * 5 - 5;
      for (var i = 0; i < len; i++) {
          delete this[i];
      }
      this._clearFirstHandlerData();
      this._setLength(0);
      this._unsetGcQueued();
  };
  
  Promise.prototype._clearFirstHandlerData =
  function Promise$_clearFirstHandlerData() {
      this._fulfillmentHandler0 = void 0;
      this._rejectionHandler0 = void 0;
      this._promise0 = void 0;
      this._receiver0 = void 0;
  };
  
  Promise.prototype._queueSettleAt = function Promise$_queueSettleAt(index) {
      if (this._isRejectionUnhandled()) this._unsetRejectionIsUnhandled();
      async.invoke(this._settlePromiseAt, this, index);
  };
  
  Promise.prototype._fulfillUnchecked =
  function Promise$_fulfillUnchecked(value) {
      if (!this.isPending()) return;
      if (value === this) {
          var err = makeSelfResolutionError();
          this._attachExtraTrace(err);
          return this._rejectUnchecked(err, void 0);
      }
      this._cleanValues();
      this._setFulfilled();
      this._settledValue = value;
      var len = this._length();
  
      if (len > 0) {
          async.invoke(this._settlePromises, this, len);
      }
  };
  
  Promise.prototype._rejectUncheckedCheckError =
  function Promise$_rejectUncheckedCheckError(reason) {
      var trace = canAttach(reason) ? reason : new Error(reason + "");
      this._rejectUnchecked(reason, trace === reason ? void 0 : trace);
  };
  
  Promise.prototype._rejectUnchecked =
  function Promise$_rejectUnchecked(reason, trace) {
      if (!this.isPending()) return;
      if (reason === this) {
          var err = makeSelfResolutionError();
          this._attachExtraTrace(err);
          return this._rejectUnchecked(err);
      }
      this._cleanValues();
      this._setRejected();
      this._settledValue = reason;
  
      if (this._isFinal()) {
          async.invokeLater(thrower, void 0, trace === void 0 ? reason : trace);
          return;
      }
      var len = this._length();
  
      if (trace !== void 0) this._setCarriedStackTrace(trace);
  
      if (len > 0) {
          async.invoke(this._rejectPromises, this, null);
      } else {
          this._ensurePossibleRejectionHandled();
      }
  };
  
  Promise.prototype._rejectPromises = function Promise$_rejectPromises() {
      this._settlePromises();
      this._unsetCarriedStackTrace();
  };
  
  Promise.prototype._settlePromises = function Promise$_settlePromises() {
      var len = this._length();
      for (var i = 0; i < len; i++) {
          this._settlePromiseAt(i);
      }
  };
  
  Promise.prototype._ensurePossibleRejectionHandled =
  function Promise$_ensurePossibleRejectionHandled() {
      this._setRejectionIsUnhandled();
      if (CapturedTrace.possiblyUnhandledRejection !== void 0) {
          async.invokeLater(this._notifyUnhandledRejection, this, void 0);
      }
  };
  
  Promise.prototype._notifyUnhandledRejectionIsHandled =
  function Promise$_notifyUnhandledRejectionIsHandled() {
      if (typeof unhandledRejectionHandled === "function") {
          async.invokeLater(unhandledRejectionHandled, void 0, this);
      }
  };
  
  Promise.prototype._notifyUnhandledRejection =
  function Promise$_notifyUnhandledRejection() {
      if (this._isRejectionUnhandled()) {
          var reason = this._settledValue;
          var trace = this._getCarriedStackTrace();
  
          this._setUnhandledRejectionIsNotified();
  
          if (trace !== void 0) {
              this._unsetCarriedStackTrace();
              reason = trace;
          }
          if (typeof CapturedTrace.possiblyUnhandledRejection === "function") {
              CapturedTrace.possiblyUnhandledRejection(reason, this);
          }
      }
  };
  
  var contextStack = [];
  Promise.prototype._peekContext = function Promise$_peekContext() {
      var lastIndex = contextStack.length - 1;
      if (lastIndex >= 0) {
          return contextStack[lastIndex];
      }
      return void 0;
  
  };
  
  Promise.prototype._pushContext = function Promise$_pushContext() {
      if (!debugging) return;
      contextStack.push(this);
  };
  
  Promise.prototype._popContext = function Promise$_popContext() {
      if (!debugging) return;
      contextStack.pop();
  };
  
  Promise.noConflict = function Promise$NoConflict() {
      return noConflict(Promise);
  };
  
  Promise.setScheduler = function(fn) {
      if (typeof fn !== "function") throw new TypeError("fn must be a function");
      async._schedule = fn;
  };
  
  if (!CapturedTrace.isSupported()) {
      Promise.longStackTraces = function(){};
      debugging = false;
  }
  
  Promise._makeSelfResolutionError = makeSelfResolutionError;
  require("./finally.js")(Promise, NEXT_FILTER, cast);
  require("./direct_resolve.js")(Promise);
  require("./synchronous_inspection.js")(Promise);
  require("./join.js")(Promise, PromiseArray, cast, INTERNAL);
  Promise.RangeError = RangeError;
  Promise.CancellationError = CancellationError;
  Promise.TimeoutError = TimeoutError;
  Promise.TypeError = TypeError;
  Promise.OperationalError = OperationalError;
  Promise.RejectionError = OperationalError;
  Promise.AggregateError = errors.AggregateError;
  
  util.toFastProperties(Promise);
  util.toFastProperties(Promise.prototype);
  Promise.Promise = Promise;
  require('./timers.js')(Promise,INTERNAL,cast);
  require('./race.js')(Promise,INTERNAL,cast);
  require('./call_get.js')(Promise);
  require('./generators.js')(Promise,apiRejection,INTERNAL,cast);
  require('./map.js')(Promise,PromiseArray,apiRejection,cast,INTERNAL);
  require('./nodeify.js')(Promise);
  require('./promisify.js')(Promise,INTERNAL);
  require('./props.js')(Promise,PromiseArray,cast);
  require('./reduce.js')(Promise,PromiseArray,apiRejection,cast,INTERNAL);
  require('./settle.js')(Promise,PromiseArray);
  require('./some.js')(Promise,PromiseArray,apiRejection);
  require('./progress.js')(Promise,PromiseArray);
  require('./cancel.js')(Promise,INTERNAL);
  require('./filter.js')(Promise,INTERNAL);
  require('./any.js')(Promise,PromiseArray);
  require('./each.js')(Promise,INTERNAL);
  require('./using.js')(Promise,apiRejection,cast);
  
  Promise.prototype = Promise.prototype;
  return Promise;
  
  };
  