text: "use strict";
  module.exports =
  function(Promise, PromiseArray, tryConvertToPromise, INTERNAL, async) {
  var util = require("./util");
  var canEvaluate = util.canEvaluate;
  var tryCatch = util.tryCatch;
  var errorObj = util.errorObj;
  var reject;
  
  if (!false) {
  if (canEvaluate) {
      var thenCallback = function(i) {
          return new Function("value", "holder", "                             \n\
              'use strict';                                                    \n\
              holder.pIndex = value;                                           \n\
              holder.checkFulfillment(this);                                   \n\
              ".replace(/Index/g, i));
      };
  
      var promiseSetter = function(i) {
          return new Function("promise", "holder", "                           \n\
              'use strict';                                                    \n\
              holder.pIndex = promise;                                         \n\
              ".replace(/Index/g, i));
      };
  
      var generateHolderClass = function(total) {
          var props = new Array(total);
          for (var i = 0; i < props.length; ++i) {
              props[i] = "this.p" + (i+1);
          }
          var assignment = props.join(" = ") + " = null;";
          var cancellationCode= "var promise;\n" + props.map(function(prop) {
              return "                                                         \n\
                  promise = " + prop + ";                                      \n\
                  if (promise instanceof Promise) {                            \n\
                      promise.cancel();                                        \n\
                  }                                                            \n\
              ";
          }).join("\n");
          var passedArguments = props.join(", ");
          var name = "Holder$" + total;
  
  
          var code = "return function(tryCatch, errorObj, Promise, async) {    \n\
              'use strict';                                                    \n\
              function [TheName](fn) {                                         \n\
                  [TheProperties]                                              \n\
                  this.fn = fn;                                                \n\
                  this.asyncNeeded = true;                                     \n\
                  this.now = 0;                                                \n\
              }                                                                \n\
                                                                               \n\
              [TheName].prototype._callFunction = function(promise) {          \n\
                  promise._pushContext();                                      \n\
                  var ret = tryCatch(this.fn)([ThePassedArguments]);           \n\
                  promise._popContext();                                       \n\
                  if (ret === errorObj) {                                      \n\
                      promise._rejectCallback(ret.e, false);                   \n\
                  } else {                                                     \n\
                      promise._resolveCallback(ret);                           \n\
                  }                                                            \n\
              };                                                               \n\
                                                                               \n\
              [TheName].prototype.checkFulfillment = function(promise) {       \n\
                  var now = ++this.now;                                        \n\
                  if (now === [TheTotal]) {                                    \n\
                      if (this.asyncNeeded) {                                  \n\
                          async.invoke(this._callFunction, this, promise);     \n\
                      } else {                                                 \n\
                          this._callFunction(promise);                         \n\
                      }                                                        \n\
                                                                               \n\
                  }                                                            \n\
              };                                                               \n\
                                                                               \n\
              [TheName].prototype._resultCancelled = function() {              \n\
                  [CancellationCode]                                           \n\
              };                                                               \n\
                                                                               \n\
              return [TheName];                                                \n\
          }(tryCatch, errorObj, Promise, async);                               \n\
          ";
  
          code = code.replace(/\[TheName\]/g, name)
              .replace(/\[TheTotal\]/g, total)
              .replace(/\[ThePassedArguments\]/g, passedArguments)
              .replace(/\[TheProperties\]/g, assignment)
              .replace(/\[CancellationCode\]/g, cancellationCode);
  
          return new Function("tryCatch", "errorObj", "Promise", "async", code)
                             (tryCatch, errorObj, Promise, async);
      };
  
      var holderClasses = [];
      var thenCallbacks = [];
      var promiseSetters = [];
  
      for (var i = 0; i < 8; ++i) {
          holderClasses.push(generateHolderClass(i + 1));
          thenCallbacks.push(thenCallback(i + 1));
          promiseSetters.push(promiseSetter(i + 1));
      }
  
      reject = function (reason) {
          this._reject(reason);
      };
  }}
  
  Promise.join = function () {
      var last = arguments.length - 1;
      var fn;
      if (last > 0 && typeof arguments[last] === "function") {
          fn = arguments[last];
          if (!false) {
              if (last <= 8 && canEvaluate) {
                  var ret = new Promise(INTERNAL);
                  ret._captureStackTrace();
                  var HolderClass = holderClasses[last - 1];
                  var holder = new HolderClass(fn);
                  var callbacks = thenCallbacks;
  
                  for (var i = 0; i < last; ++i) {
                      var maybePromise = tryConvertToPromise(arguments[i], ret);
                      if (maybePromise instanceof Promise) {
                          maybePromise = maybePromise._target();
                          var bitField = maybePromise._bitField;
                          ;
                          if (((bitField & 50397184) === 0)) {
                              maybePromise._then(callbacks[i], reject,
                                                 undefined, ret, holder);
                              promiseSetters[i](maybePromise, holder);
                              holder.asyncNeeded = false;
                          } else if (((bitField & 33554432) !== 0)) {
                              callbacks[i].call(ret,
                                                maybePromise._value(), holder);
                          } else if (((bitField & 16777216) !== 0)) {
                              ret._reject(maybePromise._reason());
                          } else {
                              ret._cancel();
                          }
                      } else {
                          callbacks[i].call(ret, maybePromise, holder);
                      }
                  }
  
                  if (!ret._isFateSealed()) {
                      if (holder.asyncNeeded) {
                          var context = Promise._getContext();
                          holder.fn = util.contextBind(context, holder.fn);
                      }
                      ret._setAsyncGuaranteed();
                      ret._setOnCancel(holder);
                  }
                  return ret;
              }
          }
      }
      var $_len = arguments.length;var args = new Array($_len); for(var $_i = 0; $_i < $_len ; ++$_i) {args[$_i] = arguments[$_i ];};
      if (fn) args.pop();
      var ret = new PromiseArray(args).promise();
      return fn !== undefined ? ret.spread(fn) : ret;
  };
  
  };
  