text: "use strict";
  module.exports = function(Promise,
                            PromiseArray,
                            apiRejection,
                            tryConvertToPromise,
                            INTERNAL) {
  var getDomain = Promise._getDomain;
  var async = require("./async.js");
  var util = require("./util.js");
  var tryCatch = util.tryCatch;
  var errorObj = util.errorObj;
  var PENDING = {};
  var EMPTY_ARRAY = [];
  
  function MappingPromiseArray(promises, fn, limit, _filter) {
      this.constructor$(promises);
      this._promise._captureStackTrace();
      var domain = getDomain();
      this._callback = domain === null ? fn : domain.bind(fn);
      this._preservedValues = _filter === INTERNAL
          ? new Array(this.length())
          : null;
      this._limit = limit;
      this._inFlight = 0;
      this._queue = limit >= 1 ? [] : EMPTY_ARRAY;
      async.invoke(init, this, undefined);
  }
  util.inherits(MappingPromiseArray, PromiseArray);
  function init() {this._init$(undefined, -2);}
  
  MappingPromiseArray.prototype._init = function () {};
  
  MappingPromiseArray.prototype._promiseFulfilled = function (value, index) {
      var values = this._values;
      var length = this.length();
      var preservedValues = this._preservedValues;
      var limit = this._limit;
      if (values[index] === PENDING) {
          values[index] = value;
          if (limit >= 1) {
              this._inFlight--;
              this._drainQueue();
              if (this._isResolved()) return;
          }
      } else {
          if (limit >= 1 && this._inFlight >= limit) {
              values[index] = value;
              this._queue.push(index);
              return;
          }
          if (preservedValues !== null) preservedValues[index] = value;
  
          var callback = this._callback;
          var receiver = this._promise._boundValue();
          this._promise._pushContext();
          var ret = tryCatch(callback).call(receiver, value, index, length);
          this._promise._popContext();
          if (ret === errorObj) return this._reject(ret.e);
  
          var maybePromise = tryConvertToPromise(ret, this._promise);
          if (maybePromise instanceof Promise) {
              maybePromise = maybePromise._target();
              if (maybePromise._isPending()) {
                  if (limit >= 1) this._inFlight++;
                  values[index] = PENDING;
                  return maybePromise._proxyPromiseArray(this, index);
              } else if (maybePromise._isFulfilled()) {
                  ret = maybePromise._value();
              } else {
                  return this._reject(maybePromise._reason());
              }
          }
          values[index] = ret;
      }
      var totalResolved = ++this._totalResolved;
      if (totalResolved >= length) {
          if (preservedValues !== null) {
              this._filter(values, preservedValues);
          } else {
              this._resolve(values);
          }
  
      }
  };
  
  MappingPromiseArray.prototype._drainQueue = function () {
      var queue = this._queue;
      var limit = this._limit;
      var values = this._values;
      while (queue.length > 0 && this._inFlight < limit) {
          if (this._isResolved()) return;
          var index = queue.pop();
          this._promiseFulfilled(values[index], index);
      }
  };
  
  MappingPromiseArray.prototype._filter = function (booleans, values) {
      var len = values.length;
      var ret = new Array(len);
      var j = 0;
      for (var i = 0; i < len; ++i) {
          if (booleans[i]) ret[j++] = values[i];
      }
      ret.length = j;
      this._resolve(ret);
  };
  
  MappingPromiseArray.prototype.preservedValues = function () {
      return this._preservedValues;
  };
  
  function map(promises, fn, options, _filter) {
      var limit = typeof options === "object" && options !== null
          ? options.concurrency
          : 0;
      limit = typeof limit === "number" &&
          isFinite(limit) && limit >= 1 ? limit : 0;
      return new MappingPromiseArray(promises, fn, limit, _filter);
  }
  
  Promise.prototype.map = function (fn, options) {
      if (typeof fn !== "function") return apiRejection("fn must be a function\u000a\u000a    See http://goo.gl/916lJJ\u000a");
  
      return map(this, fn, options, null).promise();
  };
  
  Promise.map = function (promises, fn, options, _filter) {
      if (typeof fn !== "function") return apiRejection("fn must be a function\u000a\u000a    See http://goo.gl/916lJJ\u000a");
      return map(promises, fn, options, _filter).promise();
  };
  
  
  };
  