'use strict';

var isArguments    = require('../function/is-arguments')
  , callable       = require('../object/valid-callable')
  , validValue     = require('../object/valid-value')

  , isArray = Array.isArray, call = Function.prototype.call
  , hasOwnProperty = Object.prototype.hasOwnProperty;

module.exports = function (arrayLike/*, mapFn, thisArg*/) {
	var mapFn = arguments[1], thisArg = arguments[2], Constructor
	  , i, arr, l, iterator, result;

	validValue(arrayLike);

	if (!this || !Array.isPrototypeOf(this)) Constructor = Array;
	else Constructor = this;

	l = arrayLike.length >>> 0;
	if (mapFn != null) {
		callable(mapFn);
		arr = new Constructor(l);
		for (i = 0; i < l; ++i) {
			if (!hasOwnProperty.call(arrayLike, i)) continue;
			arr[i] = call.call(mapFn, thisArg, arrayLike[i]);
		}
		return arr;
	}

	if (isArguments(arrayLike)) {
		if (l !== 1) return Constructor.apply(null, arrayLike);
		arr = new Constructor(1);
		arr[0] = arrayLike[0];
		return arr;
	}

	arr = new Constructor(l);
	if (!isArray(arrayLike) && (typeof arrayLike['@@iterator'] === 'function')) {
		iterator = arrayLike['@@iterator']();
		result = iterator.next();
		i = 0;
		while (!result.done) {
			arr[i++] = result.value;
			result = iterator.next();
		}
		return arr;
	}
	for (i = 0; i < l; ++i) {
		if (!hasOwnProperty.call(arrayLike, i)) continue;
		arr[i] = arrayLike[i];
	}
	return arr;
};

@@ -565,16 +565,363 @@
  this;%0A%0A
+%09if (mapFn != null) callable(mapFn);%0A%09if (!isArray(arrayLike) && (typeof arrayLike%5B'@@iterator'%5D === 'function')) %7B%0A%09%09iterator = arrayLike%5B'@@iterator'%5D();%0A%09%09result = iterator.next();%0A%09%09i = 0;%0A%09%09while (!result.done) %7B%0A%09%09%09arr%5Bi++%5D = mapFn ? call.call(mapFn, thisArg, result.value) : result.value;%0A%09%09%09result = iterator.next();%0A%09%09%7D%0A%09%09return arr;%0A%09%7D%0A%0A
 %09l = arr
@@ -941,16 +941,16 @@
  %3E%3E%3E 0;%0A
-
 %09if (map
@@ -967,27 +967,8 @@
 ) %7B%0A
-%09%09callable(mapFn);%0A
 %09%09ar
@@ -1307,16 +1307,16 @@
 rr;%0A%09%7D%0A%0A
+
 %09arr = n
@@ -1338,267 +1338,8 @@
 l);%0A
-%09if (!isArray(arrayLike) && (typeof arrayLike%5B'@@iterator'%5D === 'function')) %7B%0A%09%09iterator = arrayLike%5B'@@iterator'%5D();%0A%09%09result = iterator.next();%0A%09%09i = 0;%0A%09%09while (!result.done) %7B%0A%09%09%09arr%5Bi++%5D = result.value;%0A%09%09%09result = iterator.next();%0A%09%09%7D%0A%09%09return arr;%0A%09%7D%0A
 %09for

Support mapping of iterators