“use strict”; module.exports = function(

Promise, PromiseArray, tryConvertToPromise, apiRejection) {

var util = require(“./util”); var isObject = util.isObject; var es5 = require(“./es5”); var Es6Map; if (typeof Map === “function”) Es6Map = Map;

var mapToEntries = (function() {

var index = 0;
var size = 0;

function extractEntry(value, key) {
    this[index] = value;
    this[index + size] = key;
    index++;
}

return function mapToEntries(map) {
    size = map.size;
    index = 0;
    var ret = new Array(map.size * 2);
    map.forEach(extractEntry, ret);
    return ret;
};

})();

var entriesToMap = function(entries) {

var ret = new Es6Map();
var length = entries.length / 2 | 0;
for (var i = 0; i < length; ++i) {
    var key = entries[length + i];
    var value = entries[i];
    ret.set(key, value);
}
return ret;

};

function PropertiesPromiseArray(obj) {

var isMap = false;
var entries;
if (Es6Map !== undefined && obj instanceof Es6Map) {
    entries = mapToEntries(obj);
    isMap = true;
} else {
    var keys = es5.keys(obj);
    var len = keys.length;
    entries = new Array(len * 2);
    for (var i = 0; i < len; ++i) {
        var key = keys[i];
        entries[i] = obj[key];
        entries[i + len] = key;
    }
}
this.constructor$(entries);
this._isMap = isMap;
this._init$(undefined, isMap ? -6 : -3);

} util.inherits(PropertiesPromiseArray, PromiseArray);

PropertiesPromiseArray.prototype._init = function () {};

PropertiesPromiseArray.prototype._promiseFulfilled = function (value, index) {

this._values[index] = value;
var totalResolved = ++this._totalResolved;
if (totalResolved >= this._length) {
    var val;
    if (this._isMap) {
        val = entriesToMap(this._values);
    } else {
        val = {};
        var keyOffset = this.length();
        for (var i = 0, len = this.length(); i < len; ++i) {
            val[this._values[i + keyOffset]] = this._values[i];
        }
    }
    this._resolve(val);
    return true;
}
return false;

};

PropertiesPromiseArray.prototype.shouldCopyValues = function () {

return false;

};

PropertiesPromiseArray.prototype.getActualLength = function (len) {

return len >> 1;

};

function props(promises) {

var ret;
var castValue = tryConvertToPromise(promises);

if (!isObject(castValue)) {
    return apiRejection("cannot await properties of a non-object\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
} else if (castValue instanceof Promise) {
    ret = castValue._then(
        Promise.props, undefined, undefined, undefined, undefined);
} else {
    ret = new PropertiesPromiseArray(castValue).promise();
}

if (castValue instanceof Promise) {
    ret._propagateFrom(castValue, 2);
}
return ret;

}

Promise.prototype.props = function () {

return props(this);

};

Promise.props = function (promises) {

return props(promises);

}; };