diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_arity.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_arity.js
new file mode 100644
index 0000000000000000000000000000000000000000..11de52decb864ad4c6416d77d0e507d7ddfa1f83
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_arity.js
@@ -0,0 +1,9 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat arity
+---*/
+assert.sameValue(Array.prototype.concat.length, 1);
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-to-string-throws.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-to-string-throws.js
new file mode 100644
index 0000000000000000000000000000000000000000..176c632cfdbe6ddc387690261b5ae40824f68830
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-to-string-throws.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat array like length to string throws
+---*/
+function MyError() {}
+var obj = {
+  "length": { toString: function() {
+      throw new MyError();
+    }, valueOf: null
+  },
+  "1": "A",
+  "3": "B",
+  "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+assert.throws(MyError, function() {
+  [].concat(obj);
+});
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-value-of-throws.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-value-of-throws.js
new file mode 100644
index 0000000000000000000000000000000000000000..982d38769d1b66d555d26ba722b595a9c5a2a7e4
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-value-of-throws.js
@@ -0,0 +1,25 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat array like length valueOf throws
+---*/
+function MyError() {}
+var obj = {
+  "length": {
+    valueOf: function() {
+      throw new MyError();
+    },
+    toString: null
+  },
+  "1": "A",
+  "3": "B",
+  "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+assert.throws(MyError, function() {
+  [].concat(obj);
+});
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-negative-length.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-negative-length.js
new file mode 100644
index 0000000000000000000000000000000000000000..c16a442f2762c45dfcff1eaa6c3019fc3b49889b
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-negative-length.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat array like negative length
+includes: [compareArray.js]
+---*/
+var obj = {
+  "length": -6,
+  "1": "A",
+  "3": "B",
+  "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+assert(compareArray([].concat(obj), []));
+obj.length = -6.7;
+assert(compareArray([].concat(obj), []));
+obj.length = "-6";
+assert(compareArray([].concat(obj), []));
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-primitive-non-number-length.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-primitive-non-number-length.js
new file mode 100644
index 0000000000000000000000000000000000000000..01a242c3b113218bb731f1ca591a275d86fc14d9
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-primitive-non-number-length.js
@@ -0,0 +1,20 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat array like primitive non number length
+includes: [compareArray.js]
+---*/
+var obj = {
+  "1": "A",
+  "3": "B",
+  "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+obj.length = {toString: function() { return "SIX"; }, valueOf: null };
+assert(compareArray([].concat(obj), []));
+obj.length = {toString: null, valueOf: function() { return "SIX"; } };
+assert(compareArray([].concat(obj), []));
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-string-length.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-string-length.js
new file mode 100644
index 0000000000000000000000000000000000000000..d47ef8c6f3d2b4499dbe0c141b77043a1226ec3e
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-string-length.js
@@ -0,0 +1,28 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat array like string length
+includes: [compareArray.js]
+---*/
+var obj = {
+  "length": "6",
+  "1": "A",
+  "3": "B",
+  "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
+var arr = ["X", "Y", "Z"];
+
+var expected = [
+  void 0, "A", void 0, "B", void 0, "C",
+  obj2,
+  "X", "Y", "Z"
+];
+var actual = Array.prototype.concat.call(obj, obj2, arr);
+
+assert(compareArray(actual, expected));
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-to-length-throws.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-to-length-throws.js
new file mode 100644
index 0000000000000000000000000000000000000000..d0b7458dfa7c457a46d95f850501dd6fb58ecafb
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-to-length-throws.js
@@ -0,0 +1,21 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat array like to length throws
+---*/
+var obj = {
+  "length": {valueOf: null, toString: null},
+  "1": "A",
+  "3": "B",
+  "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
+var arr = ["X", "Y", "Z"];
+assert.throws(TypeError, function() {
+  Array.prototype.concat.call(obj, obj2, arr);
+});
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like.js
new file mode 100644
index 0000000000000000000000000000000000000000..3cfe7e59b779abb0b2d07abf21a08e952a57269a
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_array-like.js
@@ -0,0 +1,28 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat array like
+includes: [compareArray.js]
+---*/
+var obj = {
+  "length": 6,
+  "1": "A",
+  "3": "B",
+  "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
+var arr = ["X", "Y", "Z"];
+
+var expected = [
+  void 0, "A", void 0, "B", void 0, "C",
+  obj2,
+  "X", "Y", "Z"
+];
+var actual = Array.prototype.concat.call(obj, obj2, arr);
+
+assert(compareArray(actual, expected));
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_descriptor.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_descriptor.js
new file mode 100644
index 0000000000000000000000000000000000000000..b2c0a167f41eeb77d48862a7e940be0a49280a01
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_descriptor.js
@@ -0,0 +1,11 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat descriptor
+---*/
+var desc = Object.getOwnPropertyDescriptor(Array.prototype, "concat");
+assert.sameValue(desc.enumerable, false);
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_holey-sloppy-arguments.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_holey-sloppy-arguments.js
new file mode 100644
index 0000000000000000000000000000000000000000..8519574a0bf8a278749fecce5a27d917c6dc4f05
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_holey-sloppy-arguments.js
@@ -0,0 +1,14 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat holey sloppy arguments
+includes: [compareArray.js]
+---*/
+var args = (function(a) { return arguments; })(1,2,3);
+delete args[1];
+args[Symbol.isConcatSpreadable] = true;
+assert(compareArray([1, void 0, 3, 1, void 0, 3], [].concat(args, args)));
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_large-typed-array.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_large-typed-array.js
new file mode 100644
index 0000000000000000000000000000000000000000..d5f4e0e9661a152846ba2bfb64ed7c78b9f21151
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_large-typed-array.js
@@ -0,0 +1,46 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat large typed array
+includes: [compareArray.js]
+---*/
+function concatTypedArray(type, elems, modulo) {
+  var items = new Array(elems);
+  var ta_by_len = new type(elems);
+  for (var i = 0; i < elems; ++i) {
+    ta_by_len[i] = items[i] = modulo === false ? i : elems % modulo;
+  }
+  var ta = new type(items);
+  assert(compareArray([].concat(ta, ta), [ta, ta]));
+  ta[Symbol.isConcatSpreadable] = true;
+  assert(compareArray([].concat(ta), items));
+
+  assert(compareArray([].concat(ta_by_len, ta_by_len), [ta_by_len, ta_by_len]));
+  ta_by_len[Symbol.isConcatSpreadable] = true;
+  assert(compareArray([].concat(ta_by_len), items));
+
+  // TypedArray with fake `length`.
+  ta = new type(1);
+  var defValue = ta[0];
+  var expected = new Array(4000);
+  expected[0] = defValue;
+
+  Object.defineProperty(ta, "length", { value: 4000 });
+  ta[Symbol.isConcatSpreadable] = true;
+  assert(compareArray([].concat(ta), expected));
+}
+
+var max = [Math.pow(2, 8), Math.pow(2, 16), Math.pow(2, 32), false, false];
+[
+  Uint8Array,
+  Uint16Array,
+  Uint32Array,
+  Float32Array,
+  Float64Array
+].forEach(function(ctor, i) {
+  concatTypedArray(ctor, 4000, max[i]);
+});
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_length-throws.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_length-throws.js
new file mode 100644
index 0000000000000000000000000000000000000000..4f40007370f835c32780779abe325e5e671a8e92
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_length-throws.js
@@ -0,0 +1,23 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat length throws
+---*/
+function MyError() {}
+var obj = {};
+obj[Symbol.isConcatSpreadable] = true;
+Object.defineProperty(obj, "length", {
+  get: function() { throw new MyError(); }
+});
+
+assert.throws(MyError, function() {
+  [].concat(obj);
+});
+
+assert.throws(MyError, function() {
+  Array.prototype.concat.call(obj, 1, 2, 3);
+});
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_no-prototype.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_no-prototype.js
new file mode 100644
index 0000000000000000000000000000000000000000..ebd38238a83013588d96f7b5f22848adea9dd898
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_no-prototype.js
@@ -0,0 +1,10 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat no prototype
+---*/
+assert.sameValue(Array.prototype.concat.prototype, void 0);
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_non-array.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_non-array.js
new file mode 100644
index 0000000000000000000000000000000000000000..a6ed1b23cf09a3ba62a34f5c8d0ca70fb64165ff
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_non-array.js
@@ -0,0 +1,25 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: array-concat-non-array
+includes: [compareArray.js]
+---*/
+
+//
+// test262 --command "v8 --harmony-classes  --harmony_object_literals" array-concat-non-array
+//
+class NonArray {
+  constructor() {
+    Array.apply(this, arguments);
+  }
+}
+
+var obj = new NonArray(1,2,3);
+var result = Array.prototype.concat.call(obj, 4, 5, 6);
+assert.sameValue(Array, result.constructor);
+assert.sameValue(result instanceof NonArray, false);
+assert(compareArray(result, [obj,4,5,6]));
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-throws.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-throws.js
new file mode 100644
index 0000000000000000000000000000000000000000..f13263f9bc84a84cc8e76a69a77f33bfabda5b00
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-throws.js
@@ -0,0 +1,18 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat sloppy arguments throws
+---*/
+function MyError() {}
+var args = (function(a) { return arguments; })(1,2,3);
+Object.defineProperty(args, 0, {
+  get: function() { throw new MyError(); }
+});
+args[Symbol.isConcatSpreadable] = true;
+assert.throws(MyError, function() {
+  return [].concat(args, args);
+});
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-with-dupes.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-with-dupes.js
new file mode 100644
index 0000000000000000000000000000000000000000..7e5d67b2b121be74e9100c9921de4937fbe001e2
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-with-dupes.js
@@ -0,0 +1,16 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat sloppy arguments with dupes
+includes: [compareArray.js]
+---*/
+var args = (function(a, a, a) { return arguments; })(1,2,3);
+args[Symbol.isConcatSpreadable] = true;
+assert(compareArray([].concat(args, args), [1, 2, 3, 1, 2, 3]));
+
+Object.defineProperty(args, "length", { value: 6 });
+assert(compareArray([].concat(args), [1, 2, 3, void 0, void 0, void 0]));
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments.js
new file mode 100644
index 0000000000000000000000000000000000000000..3cfc75df5edf06acad1ff5db45e506c3fb5bf376
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments.js
@@ -0,0 +1,16 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat sloppy arguments
+includes: [compareArray.js]
+---*/
+var args = (function(a, b, c) { return arguments; })(1,2,3);
+args[Symbol.isConcatSpreadable] = true;
+assert(compareArray([].concat(args, args), [1, 2, 3, 1, 2, 3]));
+
+Object.defineProperty(args, "length", { value: 6 });
+assert(compareArray([].concat(args), [1, 2, 3, void 0, void 0, void 0]));
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_small-typed-array.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_small-typed-array.js
new file mode 100644
index 0000000000000000000000000000000000000000..b126c746f3ea1c9d15da3c89c865ae916e8c77ea
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_small-typed-array.js
@@ -0,0 +1,45 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat small typed array
+includes: [compareArray.js]
+---*/
+function concatTypedArray(type, elems, modulo) {
+  var items = new Array(elems);
+  var ta_by_len = new type(elems);
+  for (var i = 0; i < elems; ++i) {
+    ta_by_len[i] = items[i] = modulo === false ? i : elems % modulo;
+  }
+  var ta = new type(items);
+  assert(compareArray([].concat(ta, ta), [ta, ta]));
+  ta[Symbol.isConcatSpreadable] = true;
+  assert(compareArray([].concat(ta), items));
+
+  assert(compareArray([].concat(ta_by_len, ta_by_len), [ta_by_len, ta_by_len]));
+  ta_by_len[Symbol.isConcatSpreadable] = true;
+  assert(compareArray([].concat(ta_by_len), items));
+
+  // TypedArray with fake `length`.
+  ta = new type(1);
+  var defValue = ta[0];
+  var expected = new Array(4000);
+  expected[0] = defValue;
+
+  Object.defineProperty(ta, "length", { value: 4000 });
+  ta[Symbol.isConcatSpreadable] = true;
+  assert(compareArray([].concat(ta), expected));
+}
+var max = [Math.pow(2, 8), Math.pow(2, 16), Math.pow(2, 32), false, false];
+[
+  Uint8Array,
+  Uint16Array,
+  Uint32Array,
+  Float32Array,
+  Float64Array
+].forEach(function(ctor, i) {
+  concatTypedArray(ctor, 1, max[i]);
+});
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-boolean-wrapper.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-boolean-wrapper.js
new file mode 100644
index 0000000000000000000000000000000000000000..b62193df4e571fa69bb756f186d7b9bcda9a65ee
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-boolean-wrapper.js
@@ -0,0 +1,36 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat Symbol.isConcatSpreadable boolean wrapper
+includes: [compareArray.js]
+---*/
+var bool = new Boolean(true)
+// Boolean wrapper objects are not concat-spreadable by default
+assert(compareArray([bool], [].concat(bool)));
+
+// Boolean wrapper objects may be individually concat-spreadable
+bool[Symbol.isConcatSpreadable] = true;
+bool.length = 3;
+bool[0] = 1, bool[1] = 2, bool[2] = 3;
+assert(compareArray([1, 2, 3], [].concat(bool)));
+
+Boolean.prototype[Symbol.isConcatSpreadable] = true;
+// Boolean wrapper objects may be concat-spreadable
+assert(compareArray([], [].concat(new Boolean(true))));
+Boolean.prototype[0] = 1;
+Boolean.prototype[1] = 2;
+Boolean.prototype[2] = 3;
+Boolean.prototype.length = 3;
+assert(compareArray([1,2,3], [].concat(new Boolean(true))));
+
+// Boolean values are never concat-spreadable
+assert(compareArray([true], [].concat(true)));
+delete Boolean.prototype[Symbol.isConcatSpreadable];
+delete Boolean.prototype[0];
+delete Boolean.prototype[1];
+delete Boolean.prototype[2];
+delete Boolean.prototype.length;
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-function.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-function.js
new file mode 100644
index 0000000000000000000000000000000000000000..8a1d0edacb4f9c33b2e5e11e84d845630ce61507
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-function.js
@@ -0,0 +1,31 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat Symbol.isConcatSpreadable function
+includes: [compareArray.js]
+---*/
+var fn = function(a, b, c) {}
+// Functions are not concat-spreadable by default
+assert(compareArray([fn], [].concat(fn)));
+
+// Functions may be individually concat-spreadable
+fn[Symbol.isConcatSpreadable] = true;
+fn[0] = 1, fn[1] = 2, fn[2] = 3;
+assert(compareArray([1, 2, 3], [].concat(fn)));
+
+Function.prototype[Symbol.isConcatSpreadable] = true;
+// Functions may be concat-spreadable
+assert(compareArray([void 0, void 0, void 0], [].concat(function(a,b,c) {})));
+Function.prototype[0] = 1;
+Function.prototype[1] = 2;
+Function.prototype[2] = 3;
+assert(compareArray([1,2,3], [].concat(function(a, b, c) {})));
+
+delete Function.prototype[Symbol.isConcatSpreadable];
+delete Function.prototype[0];
+delete Function.prototype[1];
+delete Function.prototype[2];
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-getter-throws.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-getter-throws.js
new file mode 100644
index 0000000000000000000000000000000000000000..98e7d98de01f01955744faef60b99c69a3ba0d19
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-getter-throws.js
@@ -0,0 +1,22 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat Symbol.isConcatSpreadable getter throws
+---*/
+function MyError() {}
+var obj = {};
+Object.defineProperty(obj, Symbol.isConcatSpreadable, {
+  get: function() { throw new MyError(); }
+});
+
+assert.throws(MyError, function() {
+  [].concat(obj);
+});
+
+assert.throws(MyError, function() {
+  Array.prototype.concat.call(obj, 1, 2, 3);
+});
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-number-wrapper.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-number-wrapper.js
new file mode 100644
index 0000000000000000000000000000000000000000..3319415333e9e25f6a93013b3ce4d847f1355b69
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-number-wrapper.js
@@ -0,0 +1,36 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat Symbol.isConcatSpreadable number wrapper
+includes: [compareArray.js]
+---*/
+var num = new Number(true)
+// Number wrapper objects are not concat-spreadable by default
+assert(compareArray([num], [].concat(num)));
+
+// Number wrapper objects may be individually concat-spreadable
+num[Symbol.isConcatSpreadable] = true;
+num.length = 3;
+num[0] = 1, num[1] = 2, num[2] = 3;
+assert(compareArray([1, 2, 3], [].concat(num)));
+
+Number.prototype[Symbol.isConcatSpreadable] = true;
+// Number wrapper objects may be concat-spreadable
+assert(compareArray([], [].concat(new Number(123))));
+Number.prototype[0] = 1;
+Number.prototype[1] = 2;
+Number.prototype[2] = 3;
+Number.prototype.length = 3;
+assert(compareArray([1,2,3], [].concat(new Number(123))));
+
+// Number values are never concat-spreadable
+assert(compareArray([true], [].concat(true)));
+delete Number.prototype[Symbol.isConcatSpreadable];
+delete Number.prototype[0];
+delete Number.prototype[1];
+delete Number.prototype[2];
+delete Number.prototype.length;
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-reg-exp.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-reg-exp.js
new file mode 100644
index 0000000000000000000000000000000000000000..f3c60a3658486699ba7e04ed5bd524d446b5c5ae
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-reg-exp.js
@@ -0,0 +1,34 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat Symbol.isConcatSpreadable reg exp
+includes: [compareArray.js]
+---*/
+var re = /abc/;
+// RegExps are not concat-spreadable by default
+assert(compareArray([].concat(re), [re]));
+
+// RegExps may be individually concat-spreadable
+re[Symbol.isConcatSpreadable] = true;
+re[0] = 1, re[1] = 2, re[2] = 3, re.length = 3;
+assert(compareArray([].concat(re), [1, 2, 3]));
+
+// RegExps may be concat-spreadable
+RegExp.prototype[Symbol.isConcatSpreadable] = true;
+RegExp.prototype.length = 3;
+
+assert(compareArray([].concat(/abc/), [void 0, void 0, void 0]));
+RegExp.prototype[0] = 1;
+RegExp.prototype[1] = 2;
+RegExp.prototype[2] = 3;
+assert(compareArray([].concat(/abc/), [1,2,3]));
+
+delete RegExp.prototype[Symbol.isConcatSpreadable];
+delete RegExp.prototype[0];
+delete RegExp.prototype[1];
+delete RegExp.prototype[2];
+delete RegExp.prototype.length;
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-sparse-object.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-sparse-object.js
new file mode 100644
index 0000000000000000000000000000000000000000..e657331386ed443f12bb49377d3aa7f6b98f1351
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-sparse-object.js
@@ -0,0 +1,16 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat Symbol.isConcatSpreadable sparse object
+includes: [compareArray.js]
+---*/
+var obj = { length: 5 };
+obj[Symbol.isConcatSpreadable] = true;
+assert(compareArray([void 0, void 0, void 0, void 0, void 0], [].concat(obj)));
+
+obj.length = 4000;
+assert(compareArray(new Array(4000), [].concat(obj)));
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-string-wrapper.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-string-wrapper.js
new file mode 100644
index 0000000000000000000000000000000000000000..3983b68fcd157482fba99317ffc7e7d02be69821
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-string-wrapper.js
@@ -0,0 +1,25 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat Symbol.isConcatSpreadable string wrapper
+includes: [compareArray.js]
+---*/
+var str1 = new String("yuck\uD83D\uDCA9")
+// String wrapper objects are not concat-spreadable by default
+assert(compareArray([str1], [].concat(str1)));
+
+// String wrapper objects may be individually concat-spreadable
+str1[Symbol.isConcatSpreadable] = true;
+assert(compareArray(["y", "u", "c", "k", "\uD83D", "\uDCA9"], [].concat(str1)));
+
+String.prototype[Symbol.isConcatSpreadable] = true;
+// String wrapper objects may be concat-spreadable
+assert(compareArray(["y", "u", "c", "k", "\uD83D", "\uDCA9"], [].concat(new String("yuck\uD83D\uDCA9"))));
+
+// String values are never concat-spreadable
+assert(compareArray(["yuck\uD83D\uDCA9"], [].concat("yuck\uD83D\uDCA9")));
+delete String.prototype[Symbol.isConcatSpreadable];
diff --git a/test/built-ins/Array/prototype/concat/Array.prototype.concat_strict-arguments.js b/test/built-ins/Array/prototype/concat/Array.prototype.concat_strict-arguments.js
new file mode 100644
index 0000000000000000000000000000000000000000..5c24876d17d8db7862a66fd0aa2132180c23c315
--- /dev/null
+++ b/test/built-ins/Array/prototype/concat/Array.prototype.concat_strict-arguments.js
@@ -0,0 +1,16 @@
+// Copyright (c) 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+/*---
+es6id: 22.1.3.1_3
+description: Array.prototype.concat strict arguments
+includes: [compareArray.js]
+---*/
+var args = (function(a, b, c) { "use strict"; return arguments; })(1,2,3);
+args[Symbol.isConcatSpreadable] = true;
+assert(compareArray([].concat(args, args), [1, 2, 3, 1, 2, 3]));
+
+Object.defineProperty(args, "length", { value: 6 });
+assert(compareArray([].concat(args), [1, 2, 3, void 0, void 0, void 0]));
diff --git a/test/built-ins/Array/prototype/concat/S15.4.4.4_A3_T2.js b/test/built-ins/Array/prototype/concat/S15.4.4.4_A3_T2.js
index 771862b347a39616287a303747c036ff2aaa4fc6..68dc0eab1a7d5c9d17b7c7fdc34249f77feb923e 100644
--- a/test/built-ins/Array/prototype/concat/S15.4.4.4_A3_T2.js
+++ b/test/built-ins/Array/prototype/concat/S15.4.4.4_A3_T2.js
@@ -1,4 +1,4 @@
-// Copyright 2014 Ecma International.  All rights reserved.
+// Copyright (c) 2014 Ecma International.  All rights reserved.
 // See LICENSE or https://github.com/tc39/test262/blob/master/LICENSE
 
 /*---
diff --git a/test/built-ins/Array/prototype/concat/S15.4.4.4_A3_T3.js b/test/built-ins/Array/prototype/concat/S15.4.4.4_A3_T3.js
index 84357465250f8f6c002c7a6482cec4844628f8bb..f85c78b1bc01b061aa702b4af8366a071e1c88d1 100644
--- a/test/built-ins/Array/prototype/concat/S15.4.4.4_A3_T3.js
+++ b/test/built-ins/Array/prototype/concat/S15.4.4.4_A3_T3.js
@@ -1,4 +1,4 @@
-// Copyright 2014 Ecma International.  All rights reserved.
+// Copyright (c) 2014 Ecma International.  All rights reserved.
 // See LICENSE or https://github.com/tc39/test262/blob/master/LICENSE
 
 /*---