Import Cobalt 13.102542

Change-Id: I6bda7b03a2e33edfd735efcb981e2a731696b90d
diff --git a/src/v8/test/inspector/BUILD.gn b/src/v8/test/inspector/BUILD.gn
new file mode 100644
index 0000000..eec613b
--- /dev/null
+++ b/src/v8/test/inspector/BUILD.gn
@@ -0,0 +1,33 @@
+# Copyright 2016 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.
+
+import("../../gni/v8.gni")
+
+v8_executable("inspector-test") {
+  testonly = true
+
+  sources = [
+    "inspector-test.cc",
+    "isolate-data.cc",
+    "isolate-data.h",
+    "task-runner.cc",
+    "task-runner.h",
+  ]
+
+  configs = [
+    "../..:external_config",
+    "../..:internal_config_base",
+  ]
+
+  deps = [
+    "../..:v8",
+    "../..:v8_libbase",
+    "../..:v8_libplatform",
+    "//build/config:exe_and_shlib_deps",
+    "//build/win:default_exe_manifest",
+  ]
+
+  cflags = []
+  ldflags = []
+}
diff --git a/src/v8/test/inspector/console/destroy-context-during-log-expected.txt b/src/v8/test/inspector/console/destroy-context-during-log-expected.txt
new file mode 100644
index 0000000..d345b12
--- /dev/null
+++ b/src/v8/test/inspector/console/destroy-context-during-log-expected.txt
@@ -0,0 +1,9 @@
+Tests that destroying context from inside of console.log does not crash
+{
+    type : string
+    value : First inspector activity after attaching inspector
+}
+{
+    type : string
+    value : End of test
+}
diff --git a/src/v8/test/inspector/console/destroy-context-during-log.js b/src/v8/test/inspector/console/destroy-context-during-log.js
new file mode 100644
index 0000000..0fa7c16
--- /dev/null
+++ b/src/v8/test/inspector/console/destroy-context-during-log.js
@@ -0,0 +1,42 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that destroying context from inside of console.log does not crash');
+
+const expression = `
+  Object.defineProperty(Object.prototype, 'RemoteObject', {
+    configurable: true,
+    set(v) {
+      console.log("Should never be called");
+      delete Object.prototype.RemoteObject;
+      this.RemoteObject = v;
+
+      inspector.fireContextDestroyed();
+      setTimeout(function() {
+        // Attach the inspector again for the sake of establishing a
+        // communication channel with the frontend test runner.
+        inspector.fireContextCreated();
+        console.log("End of test");
+      }, 0);
+    },
+  });
+
+  // Before the whole script runs, the inspector is already attached.
+  // Re-attach the inspector and trigger the console API to make sure that the
+  // injected inspector script runs again (and triggers the above setter).
+  inspector.fireContextDestroyed();
+  inspector.fireContextCreated();
+  console.log("First inspector activity after attaching inspector");
+  console.log("End of test");
+`;
+
+Protocol.Runtime.enable();
+Protocol.Runtime.evaluate({ expression: expression });
+
+Protocol.Runtime.onConsoleAPICalled(function(result) {
+  InspectorTest.logObject(result.params.args[0]);
+  if (result.params.args[0].value == "End of test") {
+    InspectorTest.completeTest();
+  }
+});
diff --git a/src/v8/test/inspector/console/scoped-variables-expected.txt b/src/v8/test/inspector/console/scoped-variables-expected.txt
new file mode 100644
index 0000000..cbafd50
--- /dev/null
+++ b/src/v8/test/inspector/console/scoped-variables-expected.txt
@@ -0,0 +1,41 @@
+Tests scoped variable in Runtime.evaluate
+Evaluating 'let a = 42;'
+{
+    type : undefined
+}
+Evaluating 'a'
+{
+    description : 42
+    type : number
+    value : 42
+}
+Evaluating 'let a = 239;'
+{
+    exceptionDetails : {
+        columnNumber : 0
+        exception : {
+            className : SyntaxError
+            description : SyntaxError: Identifier 'a' has already been declared     at <anonymous>:1:1
+            objectId : <objectId>
+            subtype : error
+            type : object
+        }
+        exceptionId : <exceptionId>
+        lineNumber : 0
+        scriptId : <scriptId>
+        text : Uncaught
+    }
+    result : {
+        className : SyntaxError
+        description : SyntaxError: Identifier 'a' has already been declared     at <anonymous>:1:1
+        objectId : <objectId>
+        subtype : error
+        type : object
+    }
+}
+Evaluating 'a'
+{
+    description : 42
+    type : number
+    value : 42
+}
diff --git a/src/v8/test/inspector/console/scoped-variables.js b/src/v8/test/inspector/console/scoped-variables.js
new file mode 100644
index 0000000..19d4926
--- /dev/null
+++ b/src/v8/test/inspector/console/scoped-variables.js
@@ -0,0 +1,26 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} =
+  InspectorTest.start('Tests scoped variable in Runtime.evaluate');
+
+(async function test() {
+  InspectorTest.log('Evaluating \'let a = 42;\'');
+  var {result:{result}} = await Protocol.Runtime.evaluate({
+    expression:'let a = 42;'});
+  InspectorTest.logMessage(result);
+  InspectorTest.log('Evaluating \'a\'');
+  var {result:{result}} = await Protocol.Runtime.evaluate({
+    expression:'a'});
+  InspectorTest.logMessage(result);
+  InspectorTest.log('Evaluating \'let a = 239;\'');
+  var {result} = await Protocol.Runtime.evaluate({
+    expression:'let a = 239;'});
+  InspectorTest.logMessage(result);
+  InspectorTest.log('Evaluating \'a\'');
+  var {result:{result}} = await Protocol.Runtime.evaluate({
+    expression:'a'});
+  InspectorTest.logMessage(result);
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/cpu-profiler/console-profile-end-parameterless-crash-expected.txt b/src/v8/test/inspector/cpu-profiler/console-profile-end-parameterless-crash-expected.txt
new file mode 100644
index 0000000..a2988ad
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/console-profile-end-parameterless-crash-expected.txt
@@ -0,0 +1,3 @@
+Tests that "console.profileEnd()" does not cause crash. (webkit:105759)
+SUCCESS: found 2 profile headers
+SUCCESS: titled profile found
diff --git a/src/v8/test/inspector/cpu-profiler/console-profile-end-parameterless-crash.js b/src/v8/test/inspector/cpu-profiler/console-profile-end-parameterless-crash.js
new file mode 100644
index 0000000..d0d995e
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/console-profile-end-parameterless-crash.js
@@ -0,0 +1,46 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Tests that \"console.profileEnd()\" does not cause crash. (webkit:105759)");
+
+contextGroup.addScript(`
+function collectProfiles()
+{
+  console.profile();
+  console.profile("titled");
+  console.profileEnd();
+  console.profileEnd();
+}`);
+
+InspectorTest.fail = function(message)
+{
+  InspectorTest.log("FAIL: " + message);
+  InspectorTest.completeTest();
+}
+
+Protocol.Profiler.enable();
+Protocol.Runtime.evaluate({ expression: "collectProfiles()"}).then(didCollectProfiles);
+
+var headers = [];
+Protocol.Profiler.onConsoleProfileFinished(function(messageObject)
+{
+  headers.push({
+    title: messageObject["params"]["title"]
+  });
+});
+
+function didCollectProfiles(messageObject)
+{
+  if (headers.length !== 2)
+    return InspectorTest.fail("Cannot retrive headers: " + JSON.stringify(messageObject, null, 4));
+  InspectorTest.log("SUCCESS: found 2 profile headers");
+  for (var i = 0; i < headers.length; i++) {
+    if (headers[i].title === "titled") {
+      InspectorTest.log("SUCCESS: titled profile found");
+      InspectorTest.completeTest();
+      return;
+    }
+  }
+  InspectorTest.fail("Cannot find titled profile");
+}
diff --git a/src/v8/test/inspector/cpu-profiler/console-profile-expected.txt b/src/v8/test/inspector/cpu-profiler/console-profile-expected.txt
new file mode 100644
index 0000000..7bb8bc9
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/console-profile-expected.txt
@@ -0,0 +1,3 @@
+Tests that console.profile/profileEnd will record CPU profile when inspector front-end is connected.
+SUCCESS: retrieved '42' profile
+SUCCESS: found 'collectProfiles' function in the profile
diff --git a/src/v8/test/inspector/cpu-profiler/console-profile.js b/src/v8/test/inspector/cpu-profiler/console-profile.js
new file mode 100644
index 0000000..9aa7542
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/console-profile.js
@@ -0,0 +1,59 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Tests that console.profile/profileEnd will record CPU profile when inspector front-end is connected.");
+
+contextGroup.addScript(`
+function collectProfiles()
+{
+  console.profile("outer");
+  console.profile(42);
+  console.profileEnd("outer");
+  console.profileEnd(42);
+}`);
+
+InspectorTest.fail = function(message)
+{
+  InspectorTest.log("FAIL: " + message);
+  InspectorTest.completeTest();
+}
+
+Protocol.Profiler.enable();
+Protocol.Runtime.evaluate({ expression: "collectProfiles()"}).then(didCollectProfiles);
+
+var headers = [];
+Protocol.Profiler.onConsoleProfileFinished(function(messageObject)
+{
+  headers.push({
+    profile: messageObject["params"]["profile"],
+    title: messageObject["params"]["title"]
+  });
+});
+
+function didCollectProfiles(messageObject)
+{
+  if (headers.length !== 2)
+    return InspectorTest.fail("Cannot retrive headers: " + JSON.stringify(messageObject, null, 4));
+  for (var i = 0; i < headers.length; i++) {
+    if (headers[i].title === "42") {
+      checkInnerProfile(headers[i].profile);
+      return;
+    }
+  }
+  InspectorTest.fail("Cannot find '42' profile header");
+}
+
+function checkInnerProfile(profile)
+{
+  InspectorTest.log("SUCCESS: retrieved '42' profile");
+  if (!findFunctionInProfile(profile.nodes, "collectProfiles"))
+    return InspectorTest.fail("collectProfiles function not found in the profile: " + JSON.stringify(profile, null, 4));
+  InspectorTest.log("SUCCESS: found 'collectProfiles' function in the profile");
+  InspectorTest.completeTest();
+}
+
+function findFunctionInProfile(nodes, functionName)
+{
+  return nodes.some(n => n.callFrame.functionName === functionName);
+}
diff --git a/src/v8/test/inspector/cpu-profiler/coverage-block-expected.txt b/src/v8/test/inspector/cpu-profiler/coverage-block-expected.txt
new file mode 100644
index 0000000..32281e5
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/coverage-block-expected.txt
@@ -0,0 +1,1112 @@
+Test collecting code coverage data with Profiler.collectCoverage.
+
+Running test: testPreciseCountBaseline
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+
+Running test: testPreciseCountCoverage
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 15
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                            [1] : {
+                                count : 8
+                                endOffset : 41
+                                startOffset : 32
+                            }
+                            [2] : {
+                                count : 7
+                                endOffset : 71
+                                startOffset : 41
+                            }
+                            [3] : {
+                                count : 0
+                                endOffset : 72
+                                startOffset : 71
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                            [1] : {
+                                count : 0
+                                endOffset : 207
+                                startOffset : 206
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testPreciseCountCoverage
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 38
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+
+Running test: testPreciseCountCoverageIncremental
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 15
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                            [1] : {
+                                count : 8
+                                endOffset : 41
+                                startOffset : 32
+                            }
+                            [2] : {
+                                count : 7
+                                endOffset : 71
+                                startOffset : 41
+                            }
+                            [3] : {
+                                count : 0
+                                endOffset : 72
+                                startOffset : 71
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                            [1] : {
+                                count : 0
+                                endOffset : 207
+                                startOffset : 206
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testPreciseCountCoverageIncremental
+            }
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : string
+            value : unoptimized
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 10946
+            type : number
+            value : 10946
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : string
+            value : unoptimized
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : fib
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 21891
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                            [1] : {
+                                count : 10946
+                                endOffset : 41
+                                startOffset : 32
+                            }
+                            [2] : {
+                                count : 10945
+                                endOffset : 71
+                                startOffset : 41
+                            }
+                            [3] : {
+                                count : 0
+                                endOffset : 72
+                                startOffset : 71
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : is_optimized
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 2
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                            [1] : {
+                                count : 0
+                                endOffset : 156
+                                startOffset : 145
+                            }
+                            [2] : {
+                                count : 0
+                                endOffset : 174
+                                startOffset : 173
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testPreciseCountCoverageIncremental
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 2
+                                endOffset : 17
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+            [2] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 7
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+
+Running test: testPreciseCoverageFail
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    error : {
+        code : -32000
+        message : Precise coverage has not been started.
+    }
+    id : <messageId>
+}
+
+Running test: testBestEffortCoverage
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+
+Running test: testBestEffortCoverageWithPreciseBinaryEnabled
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testBestEffortCoverageWithPreciseBinaryEnabled
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 38
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testBestEffortCoverageWithPreciseBinaryEnabled
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 38
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+
+Running test: testBestEffortCoverageWithPreciseCountEnabled
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testBestEffortCoverageWithPreciseCountEnabled
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 38
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testBestEffortCoverageWithPreciseCountEnabled
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 38
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+
+Running test: testEnablePreciseCountCoverageAtPause
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 38
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+
+Running test: testPreciseBinaryCoverage
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                            [1] : {
+                                count : 0
+                                endOffset : 72
+                                startOffset : 71
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                            [1] : {
+                                count : 0
+                                endOffset : 207
+                                startOffset : 206
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testPreciseBinaryCoverage
+            }
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : string
+            value : unoptimized
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 10946
+            type : number
+            value : 10946
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : string
+            value : optimized
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : fib
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                            [1] : {
+                                count : 1
+                                endOffset : 71
+                                startOffset : 32
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : is_optimized
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                            [1] : {
+                                count : 0
+                                endOffset : 174
+                                startOffset : 173
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testPreciseBinaryCoverage
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 17
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+            [2] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 7
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+
+Running test: testPreciseEmptyScriptCoverageEntries
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+
+Running test: testPreciseCountCoveragePartial
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 238
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : outer
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 224
+                                startOffset : 10
+                            }
+                            [1] : {
+                                count : 0
+                                endOffset : 223
+                                startOffset : 222
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : nested_0
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 176
+                                startOffset : 31
+                            }
+                            [1] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 172
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : nested_1
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 172
+                                startOffset : 64
+                            }
+                            [1] : {
+                                count : 0
+                                endOffset : 171
+                                startOffset : 166
+                            }
+                        ]
+                    }
+                    [4] : {
+                        functionName : nested_2
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 166
+                                startOffset : 99
+                            }
+                            [1] : {
+                                count : 0
+                                endOffset : 165
+                                startOffset : 158
+                            }
+                        ]
+                    }
+                    [5] : {
+                        functionName : nested_3
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 158
+                                startOffset : 136
+                            }
+                        ]
+                    }
+                    [6] : {
+                        functionName : nested_4
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 201
+                                startOffset : 179
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testPreciseCountCoveragePartial
+            }
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : nested_1
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 172
+                                startOffset : 64
+                            }
+                            [1] : {
+                                count : 0
+                                endOffset : 171
+                                startOffset : 166
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : nested_2
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 166
+                                startOffset : 99
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testPreciseCountCoveragePartial
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : true
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 3
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
diff --git a/src/v8/test/inspector/cpu-profiler/coverage-block.js b/src/v8/test/inspector/cpu-profiler/coverage-block.js
new file mode 100644
index 0000000..cba6d7d
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/coverage-block.js
@@ -0,0 +1,289 @@
+// Copyright 2017 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.
+
+// Flags: --allow-natives-syntax --no-always-opt --opt
+
+var source =
+`
+function fib(x) {
+  if (x < 2) return 1;
+  return fib(x-1) + fib(x-2);
+}
+function is_optimized(f) {
+  return (%GetOptimizationStatus(f) & 16) ? "optimized" : "unoptimized";
+}
+(function iife() {
+  return 1;
+})();
+fib(5);
+`;
+
+var break_source =
+`
+function g() {
+  debugger;
+}
+function f(x) {
+  if (x == 0) g();
+  else f(x - 1);
+}
+function h() {
+  g();
+}
+f(3);
+`;
+
+var nested =
+`
+var f = (function outer() {
+  function nested_0() {
+    return function nested_1() {
+      return function nested_2() {
+        return function nested_3() {}
+      }
+    }
+  }
+  function nested_4() {}
+  return nested_0();
+})();
+f()()();
+`;
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Test collecting code coverage data with Profiler.collectCoverage.");
+
+function ClearAndGC() {
+  return Protocol.Runtime.evaluate({ expression: "fib = g = f = h = is_optimized = null;" })
+             .then(GC);
+}
+
+function GC() {
+  return Protocol.HeapProfiler.collectGarbage();
+}
+
+function LogSorted(message) {
+  message.result.result.sort((a, b) => parseInt(a.scriptId) - parseInt(b.scriptId));
+  return InspectorTest.logMessage(message);
+}
+
+InspectorTest.runTestSuite([
+  function testPreciseCountBaseline(next)
+  {
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(GC)
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: true}))
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testPreciseCountCoverage(next)
+  {
+    Protocol.Runtime.enable()
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: true}))
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testPreciseCountCoverageIncremental(next)
+  {
+    Protocol.Runtime.enable()
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: true}))
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(() => Protocol.Runtime.evaluate({ expression: "is_optimized(fib)" }))
+      .then(message => InspectorTest.logMessage(message))
+      .then(() => Protocol.Runtime.evaluate({ expression: "fib(20)" }))
+      .then(message => InspectorTest.logMessage(message))
+      .then(() => Protocol.Runtime.evaluate({ expression: "is_optimized(fib)" }))
+      .then(message => InspectorTest.logMessage(message))
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testPreciseCoverageFail(next)
+  {
+    Protocol.Runtime.enable()
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(InspectorTest.logMessage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testBestEffortCoverage(next)
+  {
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.getBestEffortCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.getBestEffortCoverage)
+      .then(LogSorted)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testBestEffortCoverageWithPreciseBinaryEnabled(next)
+  {
+    Protocol.Runtime.enable()
+    .then(Protocol.Profiler.enable)
+    .then(() => Protocol.Profiler.startPreciseCoverage({detailed: true}))
+    .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+    .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+    .then(InspectorTest.logMessage)
+    .then(ClearAndGC)
+    .then(Protocol.Profiler.getBestEffortCoverage)
+    .then(LogSorted)
+    .then(Protocol.Profiler.getBestEffortCoverage)
+    .then(LogSorted)
+    .then(ClearAndGC)
+    .then(Protocol.Profiler.stopPreciseCoverage)
+    .then(Protocol.Profiler.disable)
+    .then(Protocol.Runtime.disable)
+    .then(ClearAndGC)
+    .then(next);
+  },
+  function testBestEffortCoverageWithPreciseCountEnabled(next)
+  {
+    Protocol.Runtime.enable()
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: true}))
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.getBestEffortCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.getBestEffortCoverage)
+      .then(LogSorted)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testEnablePreciseCountCoverageAtPause(next)
+  {
+    function handleDebuggerPause() {
+      Protocol.Profiler.enable()
+          .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: true}))
+          .then(Protocol.Debugger.resume)
+    }
+    Protocol.Debugger.enable();
+    Protocol.Debugger.oncePaused().then(handleDebuggerPause);
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: break_source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(Protocol.Debugger.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testPreciseBinaryCoverage(next)
+  {
+    Protocol.Runtime.enable()
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({detailed: true}))
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(() => Protocol.Runtime.evaluate({ expression: "is_optimized(fib)" }))
+      .then(message => InspectorTest.logMessage(message))
+      .then(() => Protocol.Runtime.evaluate({ expression: "fib(20)" }))
+      .then(message => InspectorTest.logMessage(message))
+      .then(() => Protocol.Runtime.evaluate({ expression: "is_optimized(fib)" }))
+      .then(message => InspectorTest.logMessage(message))
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testPreciseEmptyScriptCoverageEntries(next)
+  {
+    // Enabling the debugger holds onto script objects even though its
+    // functions can be garbage collected. We would get empty ScriptCoverage
+    // entires unless we remove them.
+    Protocol.Debugger.enable()
+      .then(Protocol.Runtime.enable)
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({detailed: true}))
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(Protocol.Debugger.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testPreciseCountCoveragePartial(next)
+  {
+    Protocol.Runtime.enable()
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: true}))
+      .then(() => Protocol.Runtime.compileScript({ expression: nested, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(() => Protocol.Runtime.evaluate({ expression: "f()" }))
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+]);
diff --git a/src/v8/test/inspector/cpu-profiler/coverage-expected.txt b/src/v8/test/inspector/cpu-profiler/coverage-expected.txt
new file mode 100644
index 0000000..15b4101
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/coverage-expected.txt
@@ -0,0 +1,825 @@
+Test collecting code coverage data with Profiler.collectCoverage.
+
+Running test: testPreciseCountBaseline
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+
+Running test: testPreciseCountCoverage
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 15
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testPreciseCountCoverage
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 38
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+
+Running test: testPreciseCoverageFail
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    error : {
+        code : -32000
+        message : Precise coverage has not been started.
+    }
+    id : <messageId>
+}
+
+Running test: testBestEffortCoverage
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+
+Running test: testBestEffortCoverageWithPreciseBinaryEnabled
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testBestEffortCoverageWithPreciseBinaryEnabled
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 38
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testBestEffortCoverageWithPreciseBinaryEnabled
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 38
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+
+Running test: testBestEffortCoverageWithPreciseCountEnabled
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testBestEffortCoverageWithPreciseCountEnabled
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 38
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testBestEffortCoverageWithPreciseCountEnabled
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 38
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+
+Running test: testEnablePreciseCountCoverageAtPause
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 38
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+
+Running test: testPreciseBinaryCoverage
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 8
+            type : number
+            value : 8
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 221
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : fib
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 73
+                                startOffset : 1
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : iife
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 208
+                                startOffset : 177
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testPreciseBinaryCoverage
+            }
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : string
+            value : unoptimized
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 10946
+            type : number
+            value : 10946
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : string
+            value : optimized
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : is_optimized
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 175
+                                startOffset : 74
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testPreciseBinaryCoverage
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 17
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+            [2] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 7
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
+
+Running test: testPreciseEmptyScriptCoverageEntries
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+
+Running test: testPreciseCountCoveragePartial
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 238
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : outer
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 224
+                                startOffset : 10
+                            }
+                        ]
+                    }
+                    [2] : {
+                        functionName : nested_0
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 176
+                                startOffset : 31
+                            }
+                        ]
+                    }
+                    [3] : {
+                        functionName : nested_1
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 172
+                                startOffset : 64
+                            }
+                        ]
+                    }
+                    [4] : {
+                        functionName : nested_2
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 166
+                                startOffset : 99
+                            }
+                        ]
+                    }
+                    [5] : {
+                        functionName : nested_3
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 158
+                                startOffset : 136
+                            }
+                        ]
+                    }
+                    [6] : {
+                        functionName : nested_4
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 201
+                                startOffset : 179
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testPreciseCountCoveragePartial
+            }
+        ]
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                functions : [
+                    [0] : {
+                        functionName : nested_1
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 172
+                                startOffset : 64
+                            }
+                        ]
+                    }
+                    [1] : {
+                        functionName : nested_2
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 0
+                                endOffset : 166
+                                startOffset : 99
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : testPreciseCountCoveragePartial
+            }
+            [1] : {
+                functions : [
+                    [0] : {
+                        functionName : 
+                        isBlockCoverage : false
+                        ranges : [
+                            [0] : {
+                                count : 1
+                                endOffset : 3
+                                startOffset : 0
+                            }
+                        ]
+                    }
+                ]
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+    }
+}
diff --git a/src/v8/test/inspector/cpu-profiler/coverage.js b/src/v8/test/inspector/cpu-profiler/coverage.js
new file mode 100644
index 0000000..dbad54b
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/coverage.js
@@ -0,0 +1,265 @@
+// Copyright 2017 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.
+
+// Flags: --allow-natives-syntax --no-always-opt --opt
+
+var source =
+`
+function fib(x) {
+  if (x < 2) return 1;
+  return fib(x-1) + fib(x-2);
+}
+function is_optimized(f) {
+  return (%GetOptimizationStatus(f) & 16) ? "optimized" : "unoptimized";
+}
+(function iife() {
+  return 1;
+})();
+fib(5);
+`;
+
+var break_source =
+`
+function g() {
+  debugger;
+}
+function f(x) {
+  if (x == 0) g();
+  else f(x - 1);
+}
+function h() {
+  g();
+}
+f(3);
+`;
+
+var nested =
+`
+var f = (function outer() {
+  function nested_0() {
+    return function nested_1() {
+      return function nested_2() {
+        return function nested_3() {}
+      }
+    }
+  }
+  function nested_4() {}
+  return nested_0();
+})();
+f()()();
+`;
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Test collecting code coverage data with Profiler.collectCoverage.");
+
+function ClearAndGC() {
+  return Protocol.Runtime.evaluate({ expression: "fib = g = f = h = is_optimized = null;" })
+             .then(GC);
+}
+
+function GC() {
+  return Protocol.HeapProfiler.collectGarbage();
+}
+
+function LogSorted(message) {
+  message.result.result.sort((a, b) => parseInt(a.scriptId) - parseInt(b.scriptId));
+  return InspectorTest.logMessage(message);
+}
+
+InspectorTest.runTestSuite([
+  function testPreciseCountBaseline(next)
+  {
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(GC)
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: false}))
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testPreciseCountCoverage(next)
+  {
+    Protocol.Runtime.enable()
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: false}))
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testPreciseCoverageFail(next)
+  {
+    Protocol.Runtime.enable()
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(InspectorTest.logMessage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testBestEffortCoverage(next)
+  {
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.getBestEffortCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.getBestEffortCoverage)
+      .then(LogSorted)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testBestEffortCoverageWithPreciseBinaryEnabled(next)
+  {
+    Protocol.Runtime.enable()
+    .then(Protocol.Profiler.enable)
+    .then(() => Protocol.Profiler.startPreciseCoverage({detailed: false}))
+    .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+    .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+    .then(InspectorTest.logMessage)
+    .then(ClearAndGC)
+    .then(Protocol.Profiler.getBestEffortCoverage)
+    .then(LogSorted)
+    .then(Protocol.Profiler.getBestEffortCoverage)
+    .then(LogSorted)
+    .then(ClearAndGC)
+    .then(Protocol.Profiler.stopPreciseCoverage)
+    .then(Protocol.Profiler.disable)
+    .then(Protocol.Runtime.disable)
+    .then(ClearAndGC)
+    .then(next);
+  },
+  function testBestEffortCoverageWithPreciseCountEnabled(next)
+  {
+    Protocol.Runtime.enable()
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: false}))
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.getBestEffortCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.getBestEffortCoverage)
+      .then(LogSorted)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testEnablePreciseCountCoverageAtPause(next)
+  {
+    function handleDebuggerPause() {
+      Protocol.Profiler.enable()
+          .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: false}))
+          .then(Protocol.Debugger.resume)
+    }
+    Protocol.Debugger.enable();
+    Protocol.Debugger.oncePaused().then(handleDebuggerPause);
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: break_source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(Protocol.Debugger.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testPreciseBinaryCoverage(next)
+  {
+    Protocol.Runtime.enable()
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({detailed: false}))
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(() => Protocol.Runtime.evaluate({ expression: "is_optimized(fib)" }))
+      .then(message => InspectorTest.logMessage(message))
+      .then(() => Protocol.Runtime.evaluate({ expression: "fib(20)" }))
+      .then(message => InspectorTest.logMessage(message))
+      .then(() => Protocol.Runtime.evaluate({ expression: "is_optimized(fib)" }))
+      .then(message => InspectorTest.logMessage(message))
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testPreciseEmptyScriptCoverageEntries(next)
+  {
+    // Enabling the debugger holds onto script objects even though its
+    // functions can be garbage collected. We would get empty ScriptCoverage
+    // entries unless we remove them.
+    Protocol.Debugger.enable()
+      .then(Protocol.Runtime.enable)
+      .then(() => Protocol.Runtime.compileScript({ expression: source, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(ClearAndGC)
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({detailed: false}))
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(Protocol.Debugger.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+  function testPreciseCountCoveragePartial(next)
+  {
+    Protocol.Runtime.enable()
+      .then(Protocol.Profiler.enable)
+      .then(() => Protocol.Profiler.startPreciseCoverage({callCount: true, detailed: false}))
+      .then(() => Protocol.Runtime.compileScript({ expression: nested, sourceURL: arguments.callee.name, persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then(InspectorTest.logMessage)
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(() => Protocol.Runtime.evaluate({ expression: "f()" }))
+      .then(Protocol.Profiler.takePreciseCoverage)
+      .then(LogSorted)
+      .then(Protocol.Profiler.stopPreciseCoverage)
+      .then(Protocol.Profiler.disable)
+      .then(Protocol.Runtime.disable)
+      .then(ClearAndGC)
+      .then(next);
+  },
+]);
diff --git a/src/v8/test/inspector/cpu-profiler/enable-disable-expected.txt b/src/v8/test/inspector/cpu-profiler/enable-disable-expected.txt
new file mode 100644
index 0000000..aa3507c
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/enable-disable-expected.txt
@@ -0,0 +1,8 @@
+Test that profiling can only be started when Profiler was enabled and that Profiler.disable command will stop recording all profiles.
+PASS: didFailToStartWhenDisabled
+PASS: didStartFrontendProfile
+PASS: console initiated profile started
+PASS: didStartConsoleProfile
+PASS: didDisableProfiler
+PASS: no front-end initiated profiles found
+PASS: didStopConsoleProfile
diff --git a/src/v8/test/inspector/cpu-profiler/enable-disable.js b/src/v8/test/inspector/cpu-profiler/enable-disable.js
new file mode 100644
index 0000000..0e9b94d
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/enable-disable.js
@@ -0,0 +1,89 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Test that profiling can only be started when Profiler was enabled and that Profiler.disable command will stop recording all profiles.");
+
+Protocol.Profiler.start().then(didFailToStartWhenDisabled);
+disallowConsoleProfiles();
+
+function disallowConsoleProfiles()
+{
+  Protocol.Profiler.onConsoleProfileStarted(function(messageObject)
+  {
+    InspectorTest.log("FAIL: console profile started " + JSON.stringify(messageObject, null, 4));
+  });
+  Protocol.Profiler.onConsoleProfileFinished(function(messageObject)
+  {
+    InspectorTest.log("FAIL: unexpected profile received " + JSON.stringify(messageObject, null, 4));
+  });
+}
+function allowConsoleProfiles()
+{
+  Protocol.Profiler.onConsoleProfileStarted(function(messageObject)
+  {
+    InspectorTest.log("PASS: console initiated profile started");
+  });
+  Protocol.Profiler.onConsoleProfileFinished(function(messageObject)
+  {
+    InspectorTest.log("PASS: console initiated profile received");
+  });
+}
+function didFailToStartWhenDisabled(messageObject)
+{
+  if (!expectedError("didFailToStartWhenDisabled", messageObject))
+    return;
+  allowConsoleProfiles();
+  Protocol.Profiler.enable();
+  Protocol.Profiler.start().then(didStartFrontendProfile);
+}
+function didStartFrontendProfile(messageObject)
+{
+  if (!expectedSuccess("didStartFrontendProfile", messageObject))
+    return;
+  Protocol.Runtime.evaluate({expression: "console.profile('p1');"}).then(didStartConsoleProfile);
+}
+
+function didStartConsoleProfile(messageObject)
+{
+  if (!expectedSuccess("didStartConsoleProfile", messageObject))
+    return;
+  Protocol.Profiler.disable().then(didDisableProfiler);
+}
+
+function didDisableProfiler(messageObject)
+{
+  if (!expectedSuccess("didDisableProfiler", messageObject))
+    return;
+  Protocol.Profiler.enable();
+  Protocol.Profiler.stop().then(didStopFrontendProfile);
+}
+
+function didStopFrontendProfile(messageObject)
+{
+  if (!expectedError("no front-end initiated profiles found", messageObject))
+    return;
+  disallowConsoleProfiles();
+  Protocol.Runtime.evaluate({expression: "console.profileEnd();"}).then(didStopConsoleProfile);
+}
+
+function didStopConsoleProfile(messageObject)
+{
+  if (!expectedSuccess("didStopConsoleProfile", messageObject))
+    return;
+  InspectorTest.completeTest();
+}
+
+function checkExpectation(fail, name, messageObject)
+{
+  if (fail === !!messageObject.error) {
+    InspectorTest.log("PASS: " + name);
+    return true;
+  }
+
+  InspectorTest.log("FAIL: " + name + ": " + JSON.stringify(messageObject));
+  InspectorTest.completeTest();
+  return false;
+}
+var expectedSuccess = checkExpectation.bind(null, false);
+var expectedError = checkExpectation.bind(null, true);
diff --git a/src/v8/test/inspector/cpu-profiler/record-cpu-profile-expected.txt b/src/v8/test/inspector/cpu-profiler/record-cpu-profile-expected.txt
new file mode 100644
index 0000000..4ff20a2
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/record-cpu-profile-expected.txt
@@ -0,0 +1,7 @@
+Test that profiler is able to record a profile. Also it tests that profiler returns an error when it unable to find the profile.
+PASS: startFrontendProfile
+PASS: startConsoleProfile
+PASS: stopConsoleProfile
+PASS: stoppedFrontendProfile
+PASS: startFrontendProfileSecondTime
+PASS: stopFrontendProfileSecondTime
diff --git a/src/v8/test/inspector/cpu-profiler/record-cpu-profile.js b/src/v8/test/inspector/cpu-profiler/record-cpu-profile.js
new file mode 100644
index 0000000..3799cf7
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/record-cpu-profile.js
@@ -0,0 +1,62 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Test that profiler is able to record a profile. Also it tests that profiler returns an error when it unable to find the profile.");
+
+Protocol.Profiler.enable();
+Protocol.Profiler.start().then(didStartFrontendProfile);
+function didStartFrontendProfile(messageObject)
+{
+  if (!expectedSuccess("startFrontendProfile", messageObject))
+    return;
+  Protocol.Runtime.evaluate({expression: "console.profile('Profile 1');"}).then(didStartConsoleProfile);
+}
+
+function didStartConsoleProfile(messageObject)
+{
+  if (!expectedSuccess("startConsoleProfile", messageObject))
+    return;
+  Protocol.Runtime.evaluate({expression: "console.profileEnd('Profile 1');"}).then(didStopConsoleProfile);
+}
+
+function didStopConsoleProfile(messageObject)
+{
+  if (!expectedSuccess("stopConsoleProfile", messageObject))
+    return;
+  Protocol.Profiler.stop().then(didStopFrontendProfile);
+}
+
+function didStopFrontendProfile(messageObject)
+{
+  if (!expectedSuccess("stoppedFrontendProfile", messageObject))
+    return;
+  Protocol.Profiler.start().then(didStartFrontendProfile2);
+}
+
+function didStartFrontendProfile2(messageObject)
+{
+  if (!expectedSuccess("startFrontendProfileSecondTime", messageObject))
+    return;
+  Protocol.Profiler.stop().then(didStopFrontendProfile2);
+}
+
+function didStopFrontendProfile2(messageObject)
+{
+  expectedSuccess("stopFrontendProfileSecondTime", messageObject)
+  InspectorTest.completeTest();
+}
+
+function checkExpectation(fail, name, messageObject)
+{
+  if (fail === !!messageObject.error) {
+    InspectorTest.log("PASS: " + name);
+    return true;
+  }
+
+  InspectorTest.log("FAIL: " + name + ": " + JSON.stringify(messageObject));
+  InspectorTest.completeTest();
+  return false;
+}
+var expectedSuccess = checkExpectation.bind(null, false);
+var expectedError = checkExpectation.bind(null, true);
diff --git a/src/v8/test/inspector/cpu-profiler/stop-without-preceeding-start-expected.txt b/src/v8/test/inspector/cpu-profiler/stop-without-preceeding-start-expected.txt
new file mode 100644
index 0000000..0c0f682
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/stop-without-preceeding-start-expected.txt
@@ -0,0 +1,2 @@
+Test that profiler doesn't crash when we call stop without preceding start.
+PASS: ProfileAgent.stop
diff --git a/src/v8/test/inspector/cpu-profiler/stop-without-preceeding-start.js b/src/v8/test/inspector/cpu-profiler/stop-without-preceeding-start.js
new file mode 100644
index 0000000..848e1d2
--- /dev/null
+++ b/src/v8/test/inspector/cpu-profiler/stop-without-preceeding-start.js
@@ -0,0 +1,26 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Test that profiler doesn't crash when we call stop without preceding start.");
+
+Protocol.Profiler.stop().then(didStopProfile);
+function didStopProfile(messageObject)
+{
+  expectedError("ProfileAgent.stop", messageObject);
+  InspectorTest.completeTest();
+}
+
+function checkExpectation(fail, name, messageObject)
+{
+  if (fail === !!messageObject.error) {
+    InspectorTest.log("PASS: " + name);
+    return true;
+  }
+
+  InspectorTest.log("FAIL: " + name + ": " + JSON.stringify(messageObject));
+  InspectorTest.completeTest();
+  return false;
+}
+var expectedSuccess = checkExpectation.bind(null, false);
+var expectedError = checkExpectation.bind(null, true);
diff --git a/src/v8/test/inspector/debugger/access-obsolete-frame-expected.txt b/src/v8/test/inspector/debugger/access-obsolete-frame-expected.txt
new file mode 100644
index 0000000..7093d76
--- /dev/null
+++ b/src/v8/test/inspector/debugger/access-obsolete-frame-expected.txt
@@ -0,0 +1,9 @@
+Tests that accessing no longer valid call frames returns an error
+Paused on 'debugger;'
+resume
+restartFrame
+PASS, error message as expected
+evaluateOnFrame
+PASS, error message as expected
+setVariableValue
+PASS, error message as expected
diff --git a/src/v8/test/inspector/debugger/access-obsolete-frame.js b/src/v8/test/inspector/debugger/access-obsolete-frame.js
new file mode 100644
index 0000000..9d498e0
--- /dev/null
+++ b/src/v8/test/inspector/debugger/access-obsolete-frame.js
@@ -0,0 +1,69 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that accessing no longer valid call frames returns an error');
+
+contextGroup.addScript(`
+function testFunction()
+{
+  debugger;
+}
+//# sourceURL=foo.js`);
+
+Protocol.Debugger.enable();
+
+Protocol.Debugger.oncePaused().then(handleDebuggerPausedOne);
+
+Protocol.Runtime.evaluate({ "expression": "setTimeout(testFunction, 0)" });
+
+var obsoleteTopFrameId;
+
+function handleDebuggerPausedOne(messageObject)
+{
+  InspectorTest.log("Paused on 'debugger;'");
+
+  var topFrame = messageObject.params.callFrames[0];
+  obsoleteTopFrameId = topFrame.callFrameId;
+
+  Protocol.Debugger.resume().then(callbackResume);
+}
+
+function callbackResume(response)
+{
+  InspectorTest.log("resume");
+  InspectorTest.log("restartFrame");
+  Protocol.Debugger.restartFrame({ callFrameId: obsoleteTopFrameId }).then(callbackRestartFrame);
+}
+
+function callbackRestartFrame(response)
+{
+  logErrorResponse(response);
+  InspectorTest.log("evaluateOnFrame");
+  Protocol.Debugger.evaluateOnCallFrame({ callFrameId: obsoleteTopFrameId, expression: "0"}).then(callbackEvaluate);
+}
+
+function callbackEvaluate(response)
+{
+  logErrorResponse(response);
+  InspectorTest.log("setVariableValue");
+  Protocol.Debugger.setVariableValue({ callFrameId: obsoleteTopFrameId, scopeNumber: 0, variableName: "a", newValue: { value: 0 } }).then(callbackSetVariableValue);
+}
+
+function callbackSetVariableValue(response)
+{
+  logErrorResponse(response);
+  InspectorTest.completeTest();
+}
+
+function logErrorResponse(response)
+{
+  if (response.error) {
+    if (response.error.message.indexOf("Can only perform operation while paused.") !== -1) {
+      InspectorTest.log("PASS, error message as expected");
+      return;
+    }
+  }
+  InspectorTest.log("FAIL, unexpected error message");
+  InspectorTest.log(JSON.stringify(response));
+}
diff --git a/src/v8/test/inspector/debugger/asm-js-breakpoint-before-exec-expected.txt b/src/v8/test/inspector/debugger/asm-js-breakpoint-before-exec-expected.txt
new file mode 100644
index 0000000..ae15e5d
--- /dev/null
+++ b/src/v8/test/inspector/debugger/asm-js-breakpoint-before-exec-expected.txt
@@ -0,0 +1,69 @@
+This test runs asm.js which calls back to JS. Before executing (after the script is parsed) we set breakpoints in the asm.js code.
+
+Running test: enableDebugger
+
+Running test: addScript
+Script nr 1 parsed!
+First script; assuming testFunction.
+Flooding script with breakpoints for the lines 3 to 20...
+Setting breakpoint on line 3
+error: undefined
+Setting breakpoint on line 4
+error: undefined
+Setting breakpoint on line 5
+error: undefined
+Setting breakpoint on line 6
+error: undefined
+Setting breakpoint on line 7
+error: undefined
+Setting breakpoint on line 8
+error: undefined
+Setting breakpoint on line 9
+error: undefined
+Setting breakpoint on line 10
+error: undefined
+Setting breakpoint on line 11
+error: undefined
+Setting breakpoint on line 12
+error: undefined
+Setting breakpoint on line 13
+error: undefined
+Setting breakpoint on line 14
+error: undefined
+Setting breakpoint on line 15
+error: undefined
+Setting breakpoint on line 16
+error: undefined
+Setting breakpoint on line 17
+error: undefined
+Setting breakpoint on line 18
+error: undefined
+Setting breakpoint on line 19
+error: undefined
+
+Running test: runTestFunction
+Script nr 2 parsed!
+Paused #1
+  - [0] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":17,"columnNumber":2}
+  - [1] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
+Paused #2
+  - [0] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":18,"columnNumber":12}
+  - [1] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
+Paused #3
+  - [0] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":19,"columnNumber":2}
+  - [1] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
+Paused #4
+  - [0] {"functionName":"call_debugger","function_lineNumber":13,"function_columnNumber":24,"lineNumber":14,"columnNumber":4}
+  - [1] {"functionName":"callDebugger","lineNumber":5,"columnNumber":6}
+  - [2] {"functionName":"redirectFun","lineNumber":8,"columnNumber":6}
+  - [3] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":19,"columnNumber":2}
+  - [4] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
+Paused #5
+  - [0] {"functionName":"call_debugger","function_lineNumber":13,"function_columnNumber":24,"lineNumber":15,"columnNumber":2}
+  - [1] {"functionName":"callDebugger","lineNumber":5,"columnNumber":6}
+  - [2] {"functionName":"redirectFun","lineNumber":8,"columnNumber":6}
+  - [3] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":19,"columnNumber":2}
+  - [4] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
+
+Running test: finished
+Finished TestSuite.
diff --git a/src/v8/test/inspector/debugger/asm-js-breakpoint-before-exec.js b/src/v8/test/inspector/debugger/asm-js-breakpoint-before-exec.js
new file mode 100644
index 0000000..ec760ec
--- /dev/null
+++ b/src/v8/test/inspector/debugger/asm-js-breakpoint-before-exec.js
@@ -0,0 +1,128 @@
+// Copyright 2016 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.
+
+// Flags: --validate-asm --allow-natives-syntax
+
+let {session, contextGroup, Protocol} = InspectorTest.start(
+    'This test runs asm.js which calls back to JS. Before executing (after ' +
+    'the script is parsed) we set breakpoints in the asm.js code.');
+
+function testFunction() {
+  function generateAsmJs(stdlib, foreign, heap) {
+    'use asm';
+    var debugger_fun = foreign.call_debugger;
+    function callDebugger() {
+      debugger_fun();
+    }
+    function redirectFun() {
+      callDebugger();
+    }
+    return redirectFun;
+  }
+
+  function call_debugger() {
+    debugger;
+  }
+
+  %OptimizeFunctionOnNextCall(generateAsmJs);
+  var fun = generateAsmJs(this, {'call_debugger': call_debugger}, undefined);
+  fun();
+}
+
+Protocol.Debugger.onPaused(handleDebuggerPaused);
+Protocol.Debugger.onScriptParsed(handleScriptParsed);
+
+function printResultAndContinue(next, message) {
+  if (message.result && message.result.exceptionDetails)
+    InspectorTest.logMessage(message.result.exceptionDetails);
+  else if (message.error)
+    InspectorTest.logMessage(message.error);
+  else if (message.result && message.result.type !== undefined)
+    InspectorTest.logMessage(message.result);
+  next();
+}
+
+InspectorTest.runTestSuite([
+  function enableDebugger(next) {
+    Protocol.Debugger.enable().then(next);
+  },
+
+  function addScript(next) {
+    afterScriptParsedCallback = next;
+    contextGroup.addScript(testFunction.toString());
+  },
+
+  function runTestFunction(next) {
+    Protocol.Runtime.evaluate({'expression': 'testFunction()'})
+        .then(printResultAndContinue.bind(null, next));
+  },
+
+  function finished(next) {
+    InspectorTest.log('Finished TestSuite.');
+    next();
+  },
+]);
+
+function locationToString(callFrame) {
+  var res = {functionName: callFrame.functionName};
+  for (var attr in callFrame.functionLocation) {
+    if (attr == 'scriptId') continue;
+    res['function_' + attr] = callFrame.functionLocation[attr];
+  }
+  for (var attr in callFrame.location) {
+    if (attr == 'scriptId') continue;
+    res[attr] = callFrame.location[attr];
+  }
+  return JSON.stringify(res);
+}
+
+function logStackTrace(messageObject) {
+  var frames = messageObject.params.callFrames;
+  for (var i = 0; i < frames.length; ++i) {
+    InspectorTest.log('  - [' + i + '] ' + locationToString(frames[i]));
+  }
+}
+
+var numPaused = 0;
+
+function handleDebuggerPaused(messageObject)
+{
+  ++numPaused;
+  InspectorTest.log('Paused #' + numPaused);
+  logStackTrace(messageObject);
+  Protocol.Debugger.resume();
+}
+
+var numScripts = 0;
+
+function handleScriptParsed(messageObject)
+{
+  var scriptId = messageObject.params.scriptId;
+  ++numScripts;
+  InspectorTest.log('Script nr ' + numScripts + ' parsed!');
+  if (numScripts > 1) return;
+
+  var startLine = messageObject.params.startLine + 3;
+  var endLine = messageObject.params.endLine;
+  InspectorTest.log('First script; assuming testFunction.');
+  InspectorTest.log(
+      'Flooding script with breakpoints for the lines ' + startLine + ' to ' +
+      endLine + '...');
+  var currentLine = startLine;
+  function setNextBreakpoint(message) {
+    if (message) InspectorTest.logMessage('error: ' + message.error);
+    if (currentLine == endLine) {
+      afterScriptParsedCallback();
+      return;
+    }
+    var thisLine = currentLine;
+    currentLine += 1;
+    InspectorTest.log('Setting breakpoint on line ' + thisLine);
+    Protocol.Debugger
+        .setBreakpoint(
+            {'location': {'scriptId': scriptId, 'lineNumber': thisLine}})
+        .then(setNextBreakpoint);
+  }
+  setNextBreakpoint();
+}
diff --git a/src/v8/test/inspector/debugger/asm-js-breakpoint-during-exec-expected.txt b/src/v8/test/inspector/debugger/asm-js-breakpoint-during-exec-expected.txt
new file mode 100644
index 0000000..feb4a3b
--- /dev/null
+++ b/src/v8/test/inspector/debugger/asm-js-breakpoint-during-exec-expected.txt
@@ -0,0 +1,86 @@
+This test runs asm.js which calls back to JS. JS triggers a break, on pause we set breakpoints in the asm.js code.
+
+Running test: enableDebugger
+
+Running test: addScript
+Script nr 1 parsed!
+
+Running test: runTestFunction
+Script nr 2 parsed!
+Paused #1
+  - [0] {"functionName":"call_debugger","function_lineNumber":13,"function_columnNumber":24,"lineNumber":14,"columnNumber":4}
+  - [1] {"functionName":"callDebugger","lineNumber":5,"columnNumber":6}
+  - [2] {"functionName":"redirectFun","lineNumber":8,"columnNumber":6}
+  - [3] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":19,"columnNumber":2}
+  - [4] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
+First time paused, setting breakpoints!
+Flooding script with breakpoints for all lines (0 - 23)...
+Setting breakpoint on line 0
+error: undefined
+Setting breakpoint on line 1
+error: undefined
+Setting breakpoint on line 2
+error: undefined
+Setting breakpoint on line 3
+error: undefined
+Setting breakpoint on line 4
+error: undefined
+Setting breakpoint on line 5
+error: undefined
+Setting breakpoint on line 6
+error: undefined
+Setting breakpoint on line 7
+error: undefined
+Setting breakpoint on line 8
+error: undefined
+Setting breakpoint on line 9
+error: undefined
+Setting breakpoint on line 10
+error: undefined
+Setting breakpoint on line 11
+error: undefined
+Setting breakpoint on line 12
+error: undefined
+Setting breakpoint on line 13
+error: undefined
+Setting breakpoint on line 14
+error: undefined
+Setting breakpoint on line 15
+error: undefined
+Setting breakpoint on line 16
+error: undefined
+Setting breakpoint on line 17
+error: undefined
+Setting breakpoint on line 18
+error: undefined
+Setting breakpoint on line 19
+error: undefined
+Setting breakpoint on line 20
+error: undefined
+Setting breakpoint on line 21
+error: undefined
+Setting breakpoint on line 22
+error: undefined
+Script nr 3 parsed!
+Resuming...
+Paused #2
+  - [0] {"functionName":"call_debugger","function_lineNumber":13,"function_columnNumber":24,"lineNumber":15,"columnNumber":2}
+  - [1] {"functionName":"callDebugger","lineNumber":5,"columnNumber":6}
+  - [2] {"functionName":"redirectFun","lineNumber":8,"columnNumber":6}
+  - [3] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":19,"columnNumber":2}
+  - [4] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
+Script nr 4 parsed!
+Resuming...
+Paused #3
+  - [0] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":21,"columnNumber":17}
+  - [1] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
+Script nr 5 parsed!
+Resuming...
+Paused #4
+  - [0] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":22,"columnNumber":2}
+  - [1] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
+Script nr 6 parsed!
+Resuming...
+
+Running test: finished
+Finished TestSuite.
diff --git a/src/v8/test/inspector/debugger/asm-js-breakpoint-during-exec.js b/src/v8/test/inspector/debugger/asm-js-breakpoint-during-exec.js
new file mode 100644
index 0000000..af3ac51
--- /dev/null
+++ b/src/v8/test/inspector/debugger/asm-js-breakpoint-during-exec.js
@@ -0,0 +1,165 @@
+// Copyright 2016 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.
+
+// Flags: --validate-asm --allow-natives-syntax
+
+let {session, contextGroup, Protocol} = InspectorTest.start(
+    'This test runs asm.js which calls back to JS. JS triggers a break, on ' +
+    'pause we set breakpoints in the asm.js code.');
+
+function testFunction() {
+  function generateAsmJs(stdlib, foreign, heap) {
+    'use asm';
+    var debugger_fun = foreign.call_debugger;
+    function callDebugger() {
+      debugger_fun();
+    }
+    function redirectFun() {
+      callDebugger();
+    }
+    return redirectFun;
+  }
+
+  function call_debugger() {
+    debugger;
+  }
+
+  %OptimizeFunctionOnNextCall(generateAsmJs);
+  var fun = generateAsmJs(this, {'call_debugger': call_debugger}, undefined);
+  fun();
+
+  var finished = 'finished';
+  debugger;
+}
+
+Protocol.Debugger.onPaused(handleDebuggerPaused);
+Protocol.Debugger.onScriptParsed(handleScriptParsed);
+
+function printResultAndContinue(next, message) {
+  if (message.result && message.result.exceptionDetails)
+    InspectorTest.logMessage(message.result.exceptionDetails);
+  else if (message.error)
+    InspectorTest.logMessage(message.error);
+  else if (message.result && message.result.type !== undefined)
+    InspectorTest.logMessage(message.result);
+  if (next) next();
+}
+
+InspectorTest.runTestSuite([
+  function enableDebugger(next) {
+    Protocol.Debugger.enable().then(next);
+  },
+
+  function addScript(next) {
+    afterScriptParsedCallback = next;
+    contextGroup.addScript(testFunction.toString());
+  },
+
+  function runTestFunction(next) {
+    afterFinishedTestFunctionCallback = next;
+    Protocol.Runtime.evaluate({'expression': 'testFunction()'})
+        .then(printResultAndContinue.bind(null, null));
+  },
+
+  function finished(next) {
+    InspectorTest.log('Finished TestSuite.');
+    next();
+  },
+]);
+
+function locationToString(callFrame) {
+  var res = {functionName: callFrame.functionName};
+  for (var attr in callFrame.functionLocation) {
+    if (attr == 'scriptId') continue;
+    res['function_' + attr] = callFrame.functionLocation[attr];
+  }
+  for (var attr in callFrame.location) {
+    if (attr == 'scriptId') continue;
+    res[attr] = callFrame.location[attr];
+  }
+  return JSON.stringify(res);
+}
+
+function logStackTrace(messageObject) {
+  var frames = messageObject.params.callFrames;
+  for (var i = 0; i < frames.length; ++i) {
+    InspectorTest.log('  - [' + i + '] ' + locationToString(frames[i]));
+  }
+}
+
+var numPaused = 0;
+var parsedScriptParams;
+
+function handleDebuggerPaused(messageObject)
+{
+  ++numPaused;
+  InspectorTest.log('Paused #' + numPaused);
+  logStackTrace(messageObject);
+
+  function cont() {
+    var topFrameId = messageObject.params.callFrames[0].callFrameId;
+    Protocol.Debugger
+        .evaluateOnCallFrame({
+          callFrameId: topFrameId,
+          expression: 'typeof finished'
+        })
+        .then(callbackEvaluate);
+    function callbackEvaluate(message) {
+      var finished = message.result && message.result.result &&
+          message.result.result.value === 'string';
+
+      InspectorTest.log('Resuming...');
+      Protocol.Debugger.resume();
+
+      if (finished)
+        afterFinishedTestFunctionCallback();
+    }
+  }
+
+  if (numPaused > 1) {
+    cont();
+    return;
+  }
+
+  InspectorTest.log('First time paused, setting breakpoints!');
+
+  var startLine = parsedScriptParams.startLine;
+  var endLine = parsedScriptParams.endLine;
+  InspectorTest.log(
+      'Flooding script with breakpoints for all lines (' + startLine + ' - ' +
+      endLine + ')...');
+  var currentLine = startLine;
+  function setNextBreakpoint(message) {
+    if (message) InspectorTest.logMessage('error: ' + message.error);
+    if (currentLine == endLine) {
+      cont();
+      return;
+    }
+    var thisLine = currentLine;
+    currentLine += 1;
+    InspectorTest.log('Setting breakpoint on line ' + thisLine);
+    Protocol.Debugger
+        .setBreakpoint({
+          'location': {
+            'scriptId': parsedScriptParams.scriptId,
+            'lineNumber': thisLine
+          }
+        })
+        .then(setNextBreakpoint);
+  }
+  setNextBreakpoint();
+}
+
+var numScripts = 0;
+
+function handleScriptParsed(messageObject)
+{
+  var scriptId = messageObject.params.scriptId;
+  ++numScripts;
+  InspectorTest.log('Script nr ' + numScripts + ' parsed!');
+  if (numScripts == 1) {
+    parsedScriptParams = JSON.parse(JSON.stringify(messageObject.params));
+    afterScriptParsedCallback();
+  }
+}
diff --git a/src/v8/test/inspector/debugger/asm-js-stack-expected.txt b/src/v8/test/inspector/debugger/asm-js-stack-expected.txt
new file mode 100644
index 0000000..e028f2a
--- /dev/null
+++ b/src/v8/test/inspector/debugger/asm-js-stack-expected.txt
@@ -0,0 +1,18 @@
+Tests that asm-js scripts produce correct stack
+Paused on 'debugger;'
+Number of frames: 5
+  - [0] {"functionName":"call_debugger","function_lineNumber":13,"function_columnNumber":24,"lineNumber":14,"columnNumber":4}
+  - [1] {"functionName":"callDebugger","lineNumber":5,"columnNumber":6}
+  - [2] {"functionName":"redirectFun","lineNumber":8,"columnNumber":6}
+  - [3] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":18,"columnNumber":2}
+  - [4] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
+Getting v8-generated stack trace...
+Result of evaluate (string):
+Error: getting stack trace
+    -- skipped --
+    at call_debugger (<anonymous>:15:5)
+    at callDebugger (<anonymous>:6:7)
+    at redirectFun (<anonymous>:9:7)
+    at testFunction (<anonymous>:19:3)
+    at <anonymous>:1:1
+Finished!
diff --git a/src/v8/test/inspector/debugger/asm-js-stack.js b/src/v8/test/inspector/debugger/asm-js-stack.js
new file mode 100644
index 0000000..916ac5f
--- /dev/null
+++ b/src/v8/test/inspector/debugger/asm-js-stack.js
@@ -0,0 +1,81 @@
+// Copyright 2016 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.
+
+// Flags: --validate-asm
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that asm-js scripts produce correct stack');
+
+function testFunction() {
+  function generateAsmJs(stdlib, foreign, heap) {
+    'use asm';
+    var debugger_fun = foreign.call_debugger;
+    function callDebugger() {
+      debugger_fun();
+    }
+    function redirectFun() {
+      callDebugger();
+    }
+    return redirectFun;
+  }
+
+  function call_debugger() {
+    debugger;
+  }
+
+  var fun = generateAsmJs(this, {'call_debugger': call_debugger}, undefined);
+  fun();
+}
+
+contextGroup.addScript(testFunction.toString());
+
+Protocol.Debugger.enable();
+Protocol.Debugger.oncePaused().then(handleDebuggerPaused);
+Protocol.Runtime.evaluate({'expression': 'testFunction()'});
+
+function locationToString(callFrame) {
+  var res = {functionName: callFrame.functionName};
+  for (var attr in callFrame.functionLocation) {
+    if (attr == 'scriptId') continue;
+    res['function_'+attr] = callFrame.functionLocation[attr];
+  }
+  for (var attr in callFrame.location) {
+    if (attr == 'scriptId') continue;
+    res[attr] = callFrame.location[attr];
+  }
+  return JSON.stringify(res);
+}
+
+function logStackTrace(messageObject) {
+  var frames = messageObject.params.callFrames;
+  InspectorTest.log('Number of frames: ' + frames.length);
+  for (var i = 0; i < frames.length; ++i) {
+    InspectorTest.log('  - [' + i + '] ' + locationToString(frames[i]));
+  }
+}
+
+function handleDebuggerPaused(messageObject)
+{
+  InspectorTest.log('Paused on \'debugger;\'');
+  logStackTrace(messageObject);
+  InspectorTest.log('Getting v8-generated stack trace...');
+  var topFrameId = messageObject.params.callFrames[0].callFrameId;
+  Protocol.Debugger
+      .evaluateOnCallFrame({
+        callFrameId: topFrameId,
+        expression: '(new Error("getting stack trace")).stack'
+      })
+      .then(callbackEvaluate);
+}
+
+function callbackEvaluate(response)
+{
+  InspectorTest.log(
+      'Result of evaluate (' + response.result.result.type + '):');
+  var result_lines = response.result.result.value.split("\n");
+  // Skip the second line, containing the 'evaluate' position.
+  result_lines[1] = "    -- skipped --";
+  InspectorTest.log(result_lines.join('\n'));
+  InspectorTest.log('Finished!');
+  InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/debugger/async-console-count-doesnt-crash-expected.txt b/src/v8/test/inspector/debugger/async-console-count-doesnt-crash-expected.txt
new file mode 100644
index 0000000..aaaf9eb
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-console-count-doesnt-crash-expected.txt
@@ -0,0 +1 @@
+setTimeout(console.count, 0) doesn't crash with enabled async stacks.
diff --git a/src/v8/test/inspector/debugger/async-console-count-doesnt-crash.js b/src/v8/test/inspector/debugger/async-console-count-doesnt-crash.js
new file mode 100644
index 0000000..14f09b3
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-console-count-doesnt-crash.js
@@ -0,0 +1,10 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("setTimeout(console.count, 0) doesn't crash with enabled async stacks.")
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 1 });
+Protocol.Runtime.evaluate({ expression: "setTimeout(console.count, 0)" });
+InspectorTest.waitForPendingTasks().then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/async-for-await-of-promise-stack-expected.txt b/src/v8/test/inspector/debugger/async-for-await-of-promise-stack-expected.txt
new file mode 100644
index 0000000..0cfa3c4
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-for-await-of-promise-stack-expected.txt
@@ -0,0 +1,58 @@
+Checks that async chains for for-await-of are correct.
+
+Running test: testBasic
+Debugger (test.js:12:2)
+Basic (test.js:50:4)
+-- async function --
+Basic (test.js:48:20)
+(anonymous) (testBasic.js:0:0)
+
+
+Running test: testUncaughtReject
+Debugger (test.js:12:2)
+-- async function --
+UncaughtReject (test.js:54:29)
+(anonymous) (testUncaughtReject.js:0:0)
+
+
+Running test: testUncaughtThrow
+Debugger (test.js:12:2)
+-- async function --
+UncaughtThrow (test.js:63:28)
+(anonymous) (testUncaughtThrow.js:0:0)
+
+
+Running test: testCaughtReject
+Debugger (test.js:12:2)
+CaughtReject (test.js:78:4)
+-- async function --
+CaughtReject (test.js:72:27)
+(anonymous) (testCaughtReject.js:0:0)
+
+
+Running test: testCaughtThrow
+Debugger (test.js:12:2)
+CaughtThrow (test.js:88:4)
+-- async function --
+CaughtThrow (test.js:82:26)
+(anonymous) (testCaughtThrow.js:0:0)
+
+
+Running test: testUncaughtRejectOnBreak
+
+Running test: testUncaughtThrowOnBreak
+Debugger (test.js:12:2)
+-- async function --
+UncaughtThrowOnBreak (test.js:101:35)
+(anonymous) (testUncaughtThrowOnBreak.js:0:0)
+
+
+Running test: testCaughtRejectOnBreak
+
+Running test: testCaughtThrowOnBreak
+Debugger (test.js:12:2)
+CaughtThrowOnBreak (test.js:126:4)
+-- async function --
+CaughtThrowOnBreak (test.js:120:33)
+(anonymous) (testCaughtThrowOnBreak.js:0:0)
+
diff --git a/src/v8/test/inspector/debugger/async-for-await-of-promise-stack.js b/src/v8/test/inspector/debugger/async-for-await-of-promise-stack.js
new file mode 100644
index 0000000..6a2f4ce
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-for-await-of-promise-stack.js
@@ -0,0 +1,164 @@
+// Copyright 2016 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.
+
+// Flags: --harmony-async-iteration
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that async chains for for-await-of are correct.');
+
+contextGroup.addScript(`
+
+function Debugger(value) {
+  debugger;
+}
+
+function Reject(reason) {
+  var reject;
+  var promise = new Promise(function(resolvefn, rejectfn) {
+    reject = rejectfn;
+  });
+  setTimeout(reject.bind(undefined, reason), 0);
+  return promise;
+}
+
+function Throw(reason) {
+  return {
+    get then() { throw reason; }
+  };
+}
+
+function ThrowOnReturn(items) {
+  var it = items[Symbol.iterator]();
+  return {
+    [Symbol.iterator]() { return this; },
+    next(v) { return it.next(v); },
+    return(v) { throw new Error("boop"); }
+  };
+}
+
+function RejectOnReturn(items) {
+  var it = items[Symbol.iterator]();
+  return {
+    [Symbol.iterator]() { return this; },
+    next(v) { return it.next(v); },
+    return(v) { return Reject(new Error("boop")); }
+  };
+}
+
+async function Basic() {
+  for await (let x of ["a"]) {
+    Debugger();
+  }
+}
+// TODO(kozyatinskiy): this stack trace is suspicious.
+async function UncaughtReject() {
+  async function loop() {
+    for await (let x of [Reject(new Error("boop"))]) {
+      Debugger();
+    }
+  }
+  return loop().catch(Debugger);
+}
+// TODO(kozyatinskiy): this stack trace is suspicious.
+async function UncaughtThrow() {
+  async function loop() {
+    for await (let x of [Throw(new Error("boop"))]) {
+      Debugger();
+    }
+  }
+  return loop().catch(Debugger);
+}
+
+async function CaughtReject() {
+  try {
+    for await (let x of [Reject(new Error("boop"))]) {
+      Debugger(x);
+    }
+  } catch (e) {
+    Debugger(e);
+  }
+}
+
+async function CaughtThrow() {
+  try {
+    for await (let x of [Throw(new Error("boop"))]) {
+      Debugger(x);
+    }
+  } catch (e) {
+    Debugger(e);
+  }
+}
+// TODO(kozyatinskiy): this stack trace is suspicious.
+async function UncaughtRejectOnBreak() {
+  async function loop() {
+    for await (let x of RejectOnReturn(["0", "1"])) {
+      break;
+    }
+  }
+  return loop().catch(Debugger);
+}
+// TODO(kozyatinskiy): this stack trace is suspicious.
+async function UncaughtThrowOnBreak() {
+  async function loop() {
+    for await (let x of ThrowOnReturn(["0", "1"])) {
+      break;
+    }
+  }
+  return loop().catch(Debugger);
+}
+// TODO(kozyatinskiy): this stack trace is suspicious.
+async function CaughtRejectOnBreak() {
+  try {
+    for await (let x of RejectOnReturn(["0", "1"])) {
+      break;
+    }
+  } catch (e) {
+    Debugger(e);
+  }
+}
+
+async function CaughtThrowOnBreak() {
+  try {
+    for await (let x of ThrowOnReturn(["0", "1"])) {
+      break;
+    }
+  } catch (e) {
+    Debugger(e);
+  }
+}
+//# sourceURL=test.js`, 9, 26);
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  session.logCallFrames(message.params.callFrames);
+  session.logAsyncStackTrace(message.params.asyncStackTrace);
+  InspectorTest.log('');
+  Protocol.Debugger.resume();
+});
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
+var testList = [
+  'Basic',
+  'UncaughtReject',
+  'UncaughtThrow',
+  'CaughtReject',
+  'CaughtThrow',
+  'UncaughtRejectOnBreak',
+  'UncaughtThrowOnBreak',
+  'CaughtRejectOnBreak',
+  'CaughtThrowOnBreak',
+]
+InspectorTest.runTestSuite(testList.map(name => {
+  return eval(`
+  (function test${capitalize(name)}(next) {
+    Protocol.Runtime.evaluate({ expression: \`${name}()
+//# sourceURL=test${capitalize(name)}.js\`, awaitPromise: true})
+      .then(next);
+  })
+  `);
+}));
+
+function capitalize(string) {
+  return string.charAt(0).toUpperCase() + string.slice(1);
+}
diff --git a/src/v8/test/inspector/debugger/async-instrumentation-expected.txt b/src/v8/test/inspector/debugger/async-instrumentation-expected.txt
new file mode 100644
index 0000000..3b9f58a
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-instrumentation-expected.txt
@@ -0,0 +1,43 @@
+Checks async instrumentation enabled in the middle.
+
+Running test: beforeAsyncTaskScheduled
+test (test.js:16:2)
+(anonymous) (expr1.js:0:0)
+
+test (test.js:21:2)
+(anonymous) (expr1.js:0:0)
+
+foo (test.js:10:2)
+-- Promise.resolve --
+test (test.js:19:14)
+(anonymous) (expr1.js:0:0)
+
+foo (test.js:12:2)
+-- Promise.resolve --
+test (test.js:19:14)
+(anonymous) (expr1.js:0:0)
+
+
+Running test: afterAsyncTaskScheduled
+test (test.js:16:2)
+(anonymous) (expr1.js:0:0)
+
+test (test.js:21:2)
+(anonymous) (expr1.js:0:0)
+
+foo (test.js:10:2)
+
+foo (test.js:12:2)
+
+
+Running test: afterAsyncTaskStarted
+test (test.js:16:2)
+(anonymous) (expr1.js:0:0)
+
+test (test.js:21:2)
+(anonymous) (expr1.js:0:0)
+
+foo (test.js:10:2)
+
+foo (test.js:12:2)
+
diff --git a/src/v8/test/inspector/debugger/async-instrumentation.js b/src/v8/test/inspector/debugger/async-instrumentation.js
new file mode 100644
index 0000000..6de2ce7
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-instrumentation.js
@@ -0,0 +1,68 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks async instrumentation enabled in the middle.');
+
+contextGroup.addScript(`
+function foo() {
+  // asyncTaskStarted
+  debugger;
+  // asyncTaskFinished
+  debugger;
+}
+
+function test() {
+  debugger;
+  var resolve1;
+  var p1 = new Promise(resolve => resolve1 = resolve);
+  var p2 = p1.then(foo);
+  resolve1(); // asyncTaskScheduled
+  debugger;
+  return p2;
+}
+
+//# sourceURL=test.js`, 7, 26);
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  if (enableOnPause-- === 0)
+    Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
+  session.logCallFrames(message.params.callFrames);
+  var asyncStackTrace = message.params.asyncStackTrace;
+  while (asyncStackTrace) {
+    InspectorTest.log(`-- ${asyncStackTrace.description} --`);
+    session.logCallFrames(asyncStackTrace.callFrames);
+    asyncStackTrace = asyncStackTrace.parent;
+  }
+  InspectorTest.log('');
+  Protocol.Debugger.resume();
+});
+
+Protocol.Debugger.enable();
+var enableOnPause = 0;
+InspectorTest.runTestSuite([
+  function beforeAsyncTaskScheduled(next) {
+    enableOnPause = 0;
+    Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr1.js',
+        awaitPromise: true })
+      .then(() => Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 0 }))
+      .then(next);
+  },
+
+  function afterAsyncTaskScheduled(next) {
+    enableOnPause = 2;
+    Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr1.js',
+        awaitPromise: true })
+      .then(() => Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 0 }))
+      .then(next);
+  },
+
+  function afterAsyncTaskStarted(next) {
+    enableOnPause = 3;
+    Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr1.js',
+        awaitPromise: true })
+      .then(() => Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 0 }))
+      .then(next);
+  }
+]);
diff --git a/src/v8/test/inspector/debugger/async-promise-late-then-expected.txt b/src/v8/test/inspector/debugger/async-promise-late-then-expected.txt
new file mode 100644
index 0000000..dfdf81f
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-promise-late-then-expected.txt
@@ -0,0 +1,16 @@
+Checks async stack for late .then handlers with gc
+foo1 (test.js:11:2)
+-- Promise.resolve --
+test (test.js:18:14)
+(anonymous) (expr.js:0:0)
+
+foo1 (test.js:11:2)
+-- Promise.resolve --
+test (test.js:22:14)
+(anonymous) (expr.js:0:0)
+
+foo1 (test.js:11:2)
+-- Promise.resolve --
+test (test.js:24:14)
+(anonymous) (expr.js:0:0)
+
diff --git a/src/v8/test/inspector/debugger/async-promise-late-then.js b/src/v8/test/inspector/debugger/async-promise-late-then.js
new file mode 100644
index 0000000..cad3c7e
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-promise-late-then.js
@@ -0,0 +1,48 @@
+// Copyright 2016 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.
+// Flags: --expose-gc
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks async stack for late .then handlers with gc');
+
+contextGroup.addScript(`
+function foo1() {
+  gc();
+  debugger;
+}
+
+function test() {
+  var resolve1;
+  var p1 = new Promise(resolve => resolve1 = resolve);
+  gc();
+  var p2 = p1.then(foo1);
+  gc();
+  resolve1();
+  gc();
+  var p3 = p1.then(foo1);
+  gc();
+  var p4 = p1.then(foo1);
+  gc();
+  return Promise.all([p2,p3,p4]);
+}
+//# sourceURL=test.js`, 8, 26);
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  session.logCallFrames(message.params.callFrames);
+  var asyncStackTrace = message.params.asyncStackTrace;
+  while (asyncStackTrace) {
+    InspectorTest.log(`-- ${asyncStackTrace.description} --`);
+    session.logCallFrames(asyncStackTrace.callFrames);
+    asyncStackTrace = asyncStackTrace.parent;
+  }
+  InspectorTest.log('');
+  Protocol.Debugger.resume();
+});
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
+Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr.js',
+    awaitPromise: true })
+  .then(() => Protocol.Runtime.evaluate({ expression: 'gc()'}))
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/async-set-timeout-expected.txt b/src/v8/test/inspector/debugger/async-set-timeout-expected.txt
new file mode 100644
index 0000000..80cbb1f
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-set-timeout-expected.txt
@@ -0,0 +1,11 @@
+Checks that async stack contains setTimeout
+inner1 (test.js:11:4)
+foo1 (test.js:14:2)
+-- setTimeout --
+inner2 (test.js:18:4)
+foo2 (test.js:20:2)
+-- setTimeout --
+inner3 (test.js:25:4)
+foo3 (test.js:27:2)
+(anonymous) (expr.js:0:0)
+
diff --git a/src/v8/test/inspector/debugger/async-set-timeout.js b/src/v8/test/inspector/debugger/async-set-timeout.js
new file mode 100644
index 0000000..30096b6
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-set-timeout.js
@@ -0,0 +1,48 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that async stack contains setTimeout');
+
+contextGroup.addScript(`
+var resolveCallback;
+function foo1() {
+  function inner1() {
+    debugger;
+    resolveCallback();
+  }
+  inner1();
+}
+function foo2() {
+  function inner2() {
+    setTimeout(foo1, 0);
+  }
+  inner2();
+}
+function foo3() {
+  var promise = new Promise(resolve => resolveCallback = resolve);
+  function inner3() {
+    setTimeout(foo2, 0);
+  }
+  inner3();
+  return promise;
+}
+//# sourceURL=test.js`, 7, 26);
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  session.logCallFrames(message.params.callFrames);
+  var asyncStackTrace = message.params.asyncStackTrace;
+  while (asyncStackTrace) {
+    InspectorTest.log(`-- ${asyncStackTrace.description} --`);
+    session.logCallFrames(asyncStackTrace.callFrames);
+    asyncStackTrace = asyncStackTrace.parent;
+  }
+  InspectorTest.log('');
+  Protocol.Debugger.resume();
+});
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
+Protocol.Runtime.evaluate({ expression: "foo3()//# sourceURL=expr.js", awaitPromise: true })
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/async-stack-await-expected.txt b/src/v8/test/inspector/debugger/async-stack-await-expected.txt
new file mode 100644
index 0000000..4ebcefa
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-stack-await-expected.txt
@@ -0,0 +1,42 @@
+Checks that async stacks works for async/await
+foo2 (test.js:15:2)
+-- async function --
+foo2 (test.js:13:19)
+test (test.js:24:8)
+(anonymous) (expr.js:0:0)
+
+foo2 (test.js:17:2)
+-- async function --
+foo2 (test.js:13:19)
+test (test.js:24:8)
+(anonymous) (expr.js:0:0)
+
+foo1 (test.js:9:2)
+foo2 (test.js:18:8)
+-- async function --
+foo2 (test.js:13:19)
+test (test.js:24:8)
+(anonymous) (expr.js:0:0)
+
+foo1 (test.js:9:2)
+-- Promise.resolve --
+foo2 (test.js:19:43)
+-- async function --
+foo2 (test.js:13:19)
+test (test.js:24:8)
+(anonymous) (expr.js:0:0)
+
+foo2 (test.js:20:2)
+-- async function --
+foo2 (test.js:13:19)
+test (test.js:24:8)
+(anonymous) (expr.js:0:0)
+
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
diff --git a/src/v8/test/inspector/debugger/async-stack-await.js b/src/v8/test/inspector/debugger/async-stack-await.js
new file mode 100644
index 0000000..8f4b162
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-stack-await.js
@@ -0,0 +1,41 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that async stacks works for async/await');
+
+contextGroup.addScript(`
+async function foo1() {
+  debugger;
+  return Promise.resolve();
+}
+
+async function foo2() {
+  await Promise.resolve();
+  debugger;
+  await Promise.resolve();
+  debugger;
+  await foo1();
+  await Promise.all([ Promise.resolve() ]).then(foo1);
+  debugger;
+}
+
+async function test() {
+  await foo2();
+}
+//# sourceURL=test.js`, 7, 26);
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  session.logCallFrames(message.params.callFrames);
+  session.logAsyncStackTrace(message.params.asyncStackTrace);
+  InspectorTest.log('');
+  Protocol.Debugger.resume();
+});
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
+Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr.js',
+    awaitPromise: true })
+  .then(InspectorTest.logMessage)
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/async-stack-created-frame-expected.txt b/src/v8/test/inspector/debugger/async-stack-created-frame-expected.txt
new file mode 100644
index 0000000..f5197a1
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-stack-created-frame-expected.txt
@@ -0,0 +1,91 @@
+Checks created frame for async call chain
+
+Running test: testPromise
+foo1 (test.js:10:2)
+-- Promise.resolve --
+promise (test.js:20:14)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testPromiseThen
+foo1 (test.js:10:2)
+-- Promise.resolve --
+promiseThen (test.js:28:14)
+(anonymous) (expr.js:0:0)
+
+foo2 (test.js:14:2)
+-- Promise.resolve --
+promiseThen (test.js:29:14)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testPromiseThenThen
+foo1 (test.js:10:2)
+-- Promise.resolve --
+promiseThenThen (test.js:37:14)
+(anonymous) (expr.js:0:0)
+
+foo1 (test.js:10:2)
+-- Promise.resolve --
+promiseThenThen (test.js:38:14)
+(anonymous) (expr.js:0:0)
+
+foo2 (test.js:14:2)
+-- Promise.resolve --
+promiseThenThen (test.js:37:25)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testPromiseResolve
+foo1 (test.js:10:2)
+-- Promise.resolve --
+promiseResolve (test.js:44:27)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testPromiseReject
+foo1 (test.js:10:2)
+-- Promise.reject --
+promiseReject (test.js:48:31)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testPromiseAll
+foo1 (test.js:10:2)
+-- Promise.resolve --
+promiseAll (test.js:52:44)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testPromiseRace
+foo1 (test.js:10:2)
+-- Promise.resolve --
+promiseRace (test.js:56:45)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testThenableJob1
+foo1 (test.js:10:2)
+-- Promise.resolve --
+thenableJob1 (test.js:60:72)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testThenableJob2
+foo1 (test.js:10:2)
+-- Promise.resolve --
+thenableJob2 (test.js:64:57)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testSetTimeouts
+foo1 (test.js:10:2)
+setTimeout (test.js:72:25)
+-- setTimeout --
+setTimeout (test.js:72:6)
+-- setTimeout --
+setTimeout (test.js:71:4)
+-- setTimeout --
+setTimeouts (test.js:70:2)
+(anonymous) (expr.js:0:0)
+
diff --git a/src/v8/test/inspector/debugger/async-stack-created-frame.js b/src/v8/test/inspector/debugger/async-stack-created-frame.js
new file mode 100644
index 0000000..0f2c7a1
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-stack-created-frame.js
@@ -0,0 +1,179 @@
+// Copyright 2017 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.
+
+// TODO(kozyatinskiy): fix this test.
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks created frame for async call chain');
+
+contextGroup.addScript(
+    `
+function foo1() {
+  debugger;
+}
+
+function foo2() {
+  debugger;
+}
+
+function promise() {
+  var resolve;
+  var p1 = new Promise(r => resolve = r);
+  var p2 = p1.then(foo1);
+  resolve();
+  return p2;
+}
+
+function promiseThen() {
+  var resolve;
+  var p1 = new Promise(r => resolve = r);
+  var p2 = p1.then(foo1);
+  var p3 = p2.then(foo2);
+  resolve();
+  return p3;
+}
+
+function promiseThenThen() {
+  var resolve;
+  var p1 = new Promise(r => resolve = r);
+  var p2 = p1.then(foo1).then(foo2);
+  var p3 = p1.then(foo1);
+  resolve();
+  return p2;
+}
+
+function promiseResolve() {
+  return Promise.resolve().then(foo1);
+}
+
+function promiseReject() {
+  return Promise.reject().catch(foo1);
+}
+
+function promiseAll() {
+  return Promise.all([ Promise.resolve() ]).then(foo1);
+}
+
+function promiseRace() {
+  return Promise.race([ Promise.resolve() ]).then(foo1);
+}
+
+function thenableJob1() {
+  return Promise.resolve().then(() => Promise.resolve().then(() => 42)).then(foo1);
+}
+
+function thenableJob2() {
+  return Promise.resolve().then(() => Promise.resolve()).then(foo1);
+}
+
+function setTimeouts() {
+  var resolve;
+  var p = new Promise(r => resolve = r);
+  setTimeout(() =>
+    setTimeout(() =>
+      setTimeout(() => { foo1(); resolve(); }, 0), 0), 0);
+  return p;
+}
+
+//# sourceURL=test.js`,
+    8, 4);
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  session.logCallFrames(message.params.callFrames);
+  session.logAsyncStackTrace(message.params.asyncStackTrace);
+  InspectorTest.log('');
+  Protocol.Debugger.resume();
+});
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
+
+InspectorTest.runTestSuite([
+  function testPromise(next) {
+    Protocol.Runtime
+        .evaluate(
+            {expression: 'promise()//# sourceURL=expr.js', awaitPromise: true})
+        .then(next);
+  },
+
+  function testPromiseThen(next) {
+    Protocol.Runtime
+        .evaluate({
+          expression: 'promiseThen()//# sourceURL=expr.js',
+          awaitPromise: true
+        })
+        .then(next);
+  },
+
+  function testPromiseThenThen(next) {
+    Protocol.Runtime
+        .evaluate({
+          expression: 'promiseThenThen()//# sourceURL=expr.js',
+          awaitPromise: true
+        })
+        .then(next);
+  },
+
+  function testPromiseResolve(next) {
+    Protocol.Runtime
+        .evaluate({
+          expression: 'promiseResolve()//# sourceURL=expr.js',
+          awaitPromise: true
+        })
+        .then(next);
+  },
+
+  function testPromiseReject(next) {
+    Protocol.Runtime
+        .evaluate({
+          expression: 'promiseReject()//# sourceURL=expr.js',
+          awaitPromise: true
+        })
+        .then(next);
+  },
+
+  function testPromiseAll(next) {
+    Protocol.Runtime
+        .evaluate({
+          expression: 'promiseAll()//# sourceURL=expr.js',
+          awaitPromise: true
+        })
+        .then(next);
+  },
+
+  function testPromiseRace(next) {
+    Protocol.Runtime
+        .evaluate({
+          expression: 'promiseRace()//# sourceURL=expr.js',
+          awaitPromise: true
+        })
+        .then(next);
+  },
+
+  function testThenableJob1(next) {
+    Protocol.Runtime
+        .evaluate({
+          expression: 'thenableJob1()//# sourceURL=expr.js',
+          awaitPromise: true
+        })
+        .then(next);
+  },
+
+  function testThenableJob2(next) {
+    Protocol.Runtime
+        .evaluate({
+          expression: 'thenableJob2()//# sourceURL=expr.js',
+          awaitPromise: true
+        })
+        .then(next);
+  },
+
+  function testSetTimeouts(next) {
+    Protocol.Runtime
+        .evaluate({
+          expression: 'setTimeouts()//# sourceURL=expr.js',
+          awaitPromise: true
+        })
+        .then(next);
+  }
+]);
diff --git a/src/v8/test/inspector/debugger/async-stack-for-promise-expected.txt b/src/v8/test/inspector/debugger/async-stack-for-promise-expected.txt
new file mode 100644
index 0000000..8164084
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-stack-for-promise-expected.txt
@@ -0,0 +1,119 @@
+Checks that async chains for promises are correct.
+
+Running test: testPromise
+foo1 (test.js:9:2)
+-- Promise.resolve --
+promise (test.js:19:14)
+(anonymous) (testPromise.js:0:0)
+
+
+Running test: testPromiseResolvedBySetTimeout
+foo1 (test.js:9:2)
+-- Promise.resolve --
+promiseResolvedBySetTimeout (test.js:27:14)
+(anonymous) (testPromiseResolvedBySetTimeout.js:0:0)
+
+
+Running test: testPromiseAll
+foo1 (test.js:9:2)
+-- Promise.resolve --
+promiseAll (test.js:37:35)
+(anonymous) (testPromiseAll.js:0:0)
+
+
+Running test: testPromiseAllReverseOrder
+foo1 (test.js:9:2)
+-- Promise.resolve --
+promiseAllReverseOrder (test.js:48:35)
+(anonymous) (testPromiseAllReverseOrder.js:0:0)
+
+
+Running test: testPromiseRace
+foo1 (test.js:9:2)
+-- Promise.resolve --
+promiseRace (test.js:59:36)
+(anonymous) (testPromiseRace.js:0:0)
+
+
+Running test: testTwoChainedCallbacks
+foo1 (test.js:9:2)
+-- Promise.resolve --
+twoChainedCallbacks (test.js:68:14)
+(anonymous) (testTwoChainedCallbacks.js:0:0)
+
+foo2 (test.js:13:2)
+-- Promise.resolve --
+twoChainedCallbacks (test.js:68:25)
+(anonymous) (testTwoChainedCallbacks.js:0:0)
+
+
+Running test: testPromiseResolve
+foo1 (test.js:9:2)
+-- Promise.resolve --
+promiseResolve (test.js:74:27)
+(anonymous) (testPromiseResolve.js:0:0)
+
+foo2 (test.js:13:2)
+-- Promise.resolve --
+promiseResolve (test.js:74:38)
+(anonymous) (testPromiseResolve.js:0:0)
+
+
+Running test: testThenableJobResolvedInSetTimeout
+foo1 (test.js:9:2)
+-- Promise.resolve --
+thenableJobResolvedInSetTimeout (test.js:86:40)
+(anonymous) (testThenableJobResolvedInSetTimeout.js:0:0)
+
+
+Running test: testThenableJobResolvedInSetTimeoutWithStack
+foo1 (test.js:9:2)
+-- Promise.resolve --
+thenableJobResolvedInSetTimeoutWithStack (test.js:104:40)
+(anonymous) (testThenableJobResolvedInSetTimeoutWithStack.js:0:0)
+
+
+Running test: testThenableJobResolvedByPromise
+foo1 (test.js:9:2)
+-- Promise.resolve --
+thenableJobResolvedByPromise (test.js:118:40)
+(anonymous) (testThenableJobResolvedByPromise.js:0:0)
+
+
+Running test: testThenableJobResolvedByPromiseWithStack
+foo1 (test.js:9:2)
+-- Promise.resolve --
+thenableJobResolvedByPromiseWithStack (test.js:136:40)
+(anonymous) (testThenableJobResolvedByPromiseWithStack.js:0:0)
+
+
+Running test: testLateThenCallback
+foo1 (test.js:9:2)
+-- Promise.resolve --
+lateThenCallback (test.js:145:12)
+(anonymous) (testLateThenCallback.js:0:0)
+
+
+Running test: testComplex
+inner1 (test.js:154:6)
+foo1 (test.js:156:4)
+-- Promise.resolve --
+complex (test.js:202:5)
+(anonymous) (testComplex.js:0:0)
+
+p.then (test.js:207:8)
+-- Promise.resolve --
+p.then (test.js:206:8)
+-- Promise.resolve --
+setTimeout (test.js:205:6)
+-- setTimeout --
+complex (test.js:204:2)
+(anonymous) (testComplex.js:0:0)
+
+
+Running test: testReject
+foo1 (test.js:9:2)
+-- Promise.reject --
+reject (test.js:217:31)
+(anonymous) (testReject.js:0:0)
+
diff --git a/src/v8/test/inspector/debugger/async-stack-for-promise.js b/src/v8/test/inspector/debugger/async-stack-for-promise.js
new file mode 100644
index 0000000..198c971
--- /dev/null
+++ b/src/v8/test/inspector/debugger/async-stack-for-promise.js
@@ -0,0 +1,260 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that async chains for promises are correct.');
+
+contextGroup.addScript(`
+function foo1() {
+  debugger;
+}
+
+function foo2() {
+  debugger;
+}
+
+function promise() {
+  var resolve;
+  var p1 = new Promise(r => resolve = r);
+  var p2 = p1.then(foo1);
+  resolve();
+  return p2;
+}
+
+function promiseResolvedBySetTimeout() {
+  var resolve;
+  var p1 = new Promise(r => resolve = r);
+  var p2 = p1.then(foo1);
+  setTimeout(resolve, 0);
+  return p2;
+}
+
+function promiseAll() {
+  var resolve1;
+  var resolve2;
+  var p1 = new Promise(resolve => resolve1 = resolve);
+  var p2 = new Promise(resolve => resolve2 = resolve);
+  var p3 = Promise.all([ p1, p2 ]).then(foo1);
+  resolve1();
+  resolve2();
+  return p3;
+}
+
+function promiseAllReverseOrder() {
+  var resolve1;
+  var resolve2;
+  var p1 = new Promise(resolve => resolve1 = resolve);
+  var p2 = new Promise(resolve => resolve2 = resolve);
+  var p3 = Promise.all([ p1, p2 ]).then(foo1);
+  resolve2();
+  resolve1();
+  return p3;
+}
+
+function promiseRace() {
+  var resolve1;
+  var resolve2;
+  var p1 = new Promise(resolve => resolve1 = resolve);
+  var p2 = new Promise(resolve => resolve2 = resolve);
+  var p3 = Promise.race([ p1, p2 ]).then(foo1);
+  resolve1();
+  resolve2();
+  return p3;
+}
+
+function twoChainedCallbacks() {
+  var resolve1;
+  var p1 = new Promise(resolve => resolve1 = resolve);
+  var p2 = p1.then(foo1).then(foo2);
+  resolve1();
+  return p2;
+}
+
+function promiseResolve() {
+  return Promise.resolve().then(foo1).then(foo2);
+}
+
+function thenableJobResolvedInSetTimeout() {
+  function thenableJob() {
+    var resolve2;
+    var p2 = new Promise(resolve => resolve2 = resolve);
+    setTimeout(resolve2, 0);
+    return p2;
+  }
+  var resolve1;
+  var p1 = new Promise(resolve => resolve1 = resolve);
+  var p3 = p1.then(() => thenableJob()).then(foo1);
+  resolve1();
+  return p3;
+}
+
+function thenableJobResolvedInSetTimeoutWithStack() {
+  function thenableJob() {
+    function inner() {
+      resolve2();
+    }
+
+    var resolve2;
+    var p2 = new Promise(resolve => resolve2 = resolve);
+    setTimeout(inner, 0);
+    return p2;
+  }
+  var resolve1;
+  var p1 = new Promise(resolve => resolve1 = resolve);
+  var p3 = p1.then(() => thenableJob()).then(foo1);
+  resolve1();
+  return p3;
+}
+
+function thenableJobResolvedByPromise() {
+  function thenableJob() {
+    var resolve2;
+    var p2 = new Promise(resolve => resolve2 = resolve);
+    Promise.resolve().then(resolve2);
+    return p2;
+  }
+  var resolve1;
+  var p1 = new Promise(resolve => resolve1 = resolve);
+  var p3 = p1.then(() => thenableJob()).then(foo1);
+  resolve1();
+  return p3;
+}
+
+function thenableJobResolvedByPromiseWithStack() {
+  function thenableJob() {
+    function inner() {
+      resolve2();
+    }
+
+    var resolve2;
+    var p2 = new Promise(resolve => resolve2 = resolve);
+    Promise.resolve().then(inner);
+    return p2;
+  }
+  var resolve1;
+  var p1 = new Promise(resolve => resolve1 = resolve);
+  var p3 = p1.then(() => thenableJob()).then(foo1);
+  resolve1();
+  return p3;
+}
+
+function lateThenCallback() {
+  var resolve1;
+  var p1 = new Promise(resolve => resolve1 = resolve);
+  resolve1();
+  return p1.then(foo1);
+}
+
+function complex() {
+  var testResolve;
+  var testPromise = new Promise(resolve => testResolve = resolve);
+
+  function foo1() {
+    function inner1() {
+      debugger;
+    }
+    inner1();
+  }
+
+  function foo2() {
+    var resolve20;
+    function inner2() {
+      resolve20();
+    }
+    var p20 = new Promise(resolve => resolve20 = resolve);
+    Promise.resolve().then(inner2);
+    return p20;
+  }
+
+  function foo3() {
+    var resolve17;
+    function inner3() {
+      resolve17();
+    }
+    var p17 = new Promise(resolve => resolve17 = resolve);
+    setTimeout(inner3, 0);
+    return p17;
+  }
+
+  function foo4() {
+    function inner4() {
+      return;
+    }
+    return inner4();
+  }
+
+  function foo5() {
+    return Promise.all([ Promise.resolve(), Promise.resolve() ])
+      .then(() => 42);
+  }
+
+  function foo6() {
+    return Promise.race([ Promise.resolve(), Promise.resolve()])
+      .then(() => 42);
+  }
+
+  var p = Promise.resolve()
+    .then(foo6)
+    .then(foo5)
+    .then(foo4)
+    .then(foo3)
+    .then(foo2)
+    .then(foo1);
+
+  setTimeout(() => {
+    p.then(() => {
+      p.then(() => {
+        debugger;
+        testResolve();
+      })
+    })
+  }, 0)
+
+  return testPromise;
+}
+
+function reject() {
+  return Promise.reject().catch(foo1);
+}
+
+//# sourceURL=test.js`, 7, 26);
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  session.logCallFrames(message.params.callFrames);
+  session.logAsyncStackTrace(message.params.asyncStackTrace);
+  InspectorTest.log('');
+  Protocol.Debugger.resume();
+});
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
+var testList = [
+  'promise',
+  'promiseResolvedBySetTimeout',
+  'promiseAll',
+  'promiseAllReverseOrder',
+  'promiseRace',
+  'twoChainedCallbacks',
+  'promiseResolve',
+  'thenableJobResolvedInSetTimeout',
+  'thenableJobResolvedInSetTimeoutWithStack',
+  'thenableJobResolvedByPromise',
+  'thenableJobResolvedByPromiseWithStack',
+  'lateThenCallback',
+  'complex',
+  'reject',
+]
+InspectorTest.runTestSuite(testList.map(name => {
+  return eval(`
+  (function test${capitalize(name)}(next) {
+    Protocol.Runtime.evaluate({ expression: \`${name}()
+//# sourceURL=test${capitalize(name)}.js\`, awaitPromise: true})
+      .then(next);
+  })
+  `);
+}));
+
+function capitalize(string) {
+  return string.charAt(0).toUpperCase() + string.slice(1);
+}
diff --git a/src/v8/test/inspector/debugger/break-location-function-calls-expected.txt b/src/v8/test/inspector/debugger/break-location-function-calls-expected.txt
new file mode 100644
index 0000000..23e30a4
--- /dev/null
+++ b/src/v8/test/inspector/debugger/break-location-function-calls-expected.txt
@@ -0,0 +1,219 @@
+Break locations around function calls
+
+Running test: testFunctionCallAsArgument
+Break locations in expression:
+function test() {
+|C|foo2(|C|foo1())
+}
+
+Breakpoint at:
+function test() {
+#foo2(foo1())
+}
+
+Break at:
+function test() {
+#foo2(foo1())
+}
+
+Debugger.stepInto called
+
+function foo1() {#}
+function foo2() {}
+
+Breakpoint at:
+function test() {
+foo2(#foo1())
+}
+
+Break at:
+function test() {
+foo2(#foo1())
+}
+
+Debugger.stepInto called
+
+function foo1() {#}
+function foo2() {}
+
+Breakpoint at expression line.
+function test() {
+#foo2(foo1())
+}
+
+Debugger.stepInto called
+
+function foo1() {#}
+function foo2() {}
+
+
+Running test: testFunctionCallAsArgument
+Break locations in expression:
+function test() {
+|C|foo2(|C|foo1());
+}
+
+Breakpoint at:
+function test() {
+#foo2(foo1());
+}
+
+Break at:
+function test() {
+#foo2(foo1());
+}
+
+Debugger.stepInto called
+
+function foo1() {#}
+function foo2() {}
+
+Breakpoint at:
+function test() {
+foo2(#foo1());
+}
+
+Break at:
+function test() {
+foo2(#foo1());
+}
+
+Debugger.stepInto called
+
+function foo1() {#}
+function foo2() {}
+
+Breakpoint at expression line.
+function test() {
+#foo2(foo1());
+}
+
+Debugger.stepInto called
+
+function foo1() {#}
+function foo2() {}
+
+
+Running test: testFunctionCallAsArguments
+Break locations in expression:
+function test() {
+|C|foo3(|C|foo1(), |C|foo2());
+}
+
+Breakpoint at:
+function test() {
+#foo3(foo1(), foo2());
+}
+
+Break at:
+function test() {
+#foo3(foo1(), foo2());
+}
+
+Debugger.stepInto called
+
+function foo1() {#}
+function foo2() {}
+
+Breakpoint at:
+function test() {
+foo3(#foo1(), foo2());
+}
+
+Break at:
+function test() {
+foo3(#foo1(), foo2());
+}
+
+Debugger.stepInto called
+
+function foo1() {#}
+function foo2() {}
+
+Breakpoint at:
+function test() {
+foo3(foo1(), #foo2());
+}
+
+Break at:
+function test() {
+foo3(foo1(), #foo2());
+}
+
+Debugger.stepInto called
+function foo1() {}
+function foo2() {#}
+function foo3() {}
+
+Breakpoint at expression line.
+function test() {
+#foo3(foo1(), foo2());
+}
+
+Debugger.stepInto called
+
+function foo1() {#}
+function foo2() {}
+
+
+Running test: testFunctionCallInBinaryExpression
+Break locations in expression:
+function test() {
+|C|foo3(|C|foo1() + |C|foo2());
+}
+
+Breakpoint at:
+function test() {
+#foo3(foo1() + foo2());
+}
+
+Break at:
+function test() {
+#foo3(foo1() + foo2());
+}
+
+Debugger.stepInto called
+
+function foo1() {#}
+function foo2() {}
+
+Breakpoint at:
+function test() {
+foo3(#foo1() + foo2());
+}
+
+Break at:
+function test() {
+foo3(#foo1() + foo2());
+}
+
+Debugger.stepInto called
+
+function foo1() {#}
+function foo2() {}
+
+Breakpoint at:
+function test() {
+foo3(foo1() + #foo2());
+}
+
+Break at:
+function test() {
+foo3(foo1() + #foo2());
+}
+
+Debugger.stepInto called
+function foo1() {}
+function foo2() {#}
+function foo3() {}
+
+Breakpoint at expression line.
+function test() {
+#foo3(foo1() + foo2());
+}
+
+Debugger.stepInto called
+
+function foo1() {#}
+function foo2() {}
+
diff --git a/src/v8/test/inspector/debugger/break-location-function-calls.js b/src/v8/test/inspector/debugger/break-location-function-calls.js
new file mode 100644
index 0000000..c32eaff
--- /dev/null
+++ b/src/v8/test/inspector/debugger/break-location-function-calls.js
@@ -0,0 +1,82 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+    InspectorTest.start('Break locations around function calls');
+
+contextGroup.addScript(`
+function foo1() {}
+function foo2() {}
+function foo3() {}
+//# sourceURL=test.js`);
+
+InspectorTest.logProtocolCommandCalls('Debugger.stepInto');
+session.setupScriptMap();
+InspectorTest.runAsyncTestSuite([
+  async function testFunctionCallAsArgument() {
+    await testExpression('foo2(foo1())');
+  },
+
+  async function testFunctionCallAsArgument() {
+    await testExpression('foo2(foo1());');
+  },
+
+  async function testFunctionCallAsArguments() {
+    await testExpression('foo3(foo1(), foo2());');
+  },
+
+  async function testFunctionCallInBinaryExpression() {
+    await testExpression('foo3(foo1() + foo2());');
+  },
+]);
+
+async function logPauseLocation() {
+  let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+  session.logSourceLocation(callFrames[0].location);
+}
+
+async function testExpression(expression) {
+  await Protocol.Debugger.enable();
+  let wrapper = `function test() {
+${expression}
+}
+//# sourceURL=test-function.js`;
+  Protocol.Runtime.evaluate({expression: wrapper});
+  let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
+  let {result:{locations}} = await Protocol.Debugger.getPossibleBreakpoints({
+    start: {lineNumber: 0, columnNumber : 0, scriptId}});
+  locations = locations.filter(location => location.lineNumber === 1);
+  InspectorTest.log('Break locations in expression:');
+  await session.logBreakLocations(locations);
+
+  for (let location of locations) {
+    InspectorTest.log('Breakpoint at:');
+    await session.logSourceLocation(location);
+    let {result:{breakpointId}} = await Protocol.Debugger.setBreakpoint({
+      location});
+    let evaluate = Protocol.Runtime.evaluate({
+      expression: 'test();\n//# sourceURL=expr.js'});
+    InspectorTest.log('Break at:');
+    await logPauseLocation();
+    Protocol.Debugger.stepInto();
+    await logPauseLocation();
+    await Protocol.Debugger.removeBreakpoint({breakpointId});
+    Protocol.Debugger.resume();
+    await evaluate;
+  }
+
+  InspectorTest.log('Breakpoint at expression line.')
+  let {result:{breakpointId}} = await Protocol.Debugger.setBreakpointByUrl({
+    lineNumber: 1, url: 'test-function.js'});
+  let evaluate = Protocol.Runtime.evaluate({
+    expression: 'test();\n//# sourceURL=expr.js'});
+  await logPauseLocation();
+  Protocol.Debugger.stepInto();
+  await logPauseLocation();
+  await Protocol.Debugger.removeBreakpoint({breakpointId});
+  Protocol.Debugger.resume();
+  await evaluate;
+
+  await Protocol.Debugger.disable();
+}
diff --git a/src/v8/test/inspector/debugger/break-locations-await-expected.txt b/src/v8/test/inspector/debugger/break-locations-await-expected.txt
new file mode 100644
index 0000000..1bf0317
--- /dev/null
+++ b/src/v8/test/inspector/debugger/break-locations-await-expected.txt
@@ -0,0 +1,361 @@
+Tests breakable locations in await expression.
+
+Running test: testBreakLocations
+
+function testFunction() {
+  async function f1() {
+    for (let x = |_|0; x |_|< 1; ++|_|x) |_|await x;
+    |_|return await Promise.|C|resolve(2);
+  |R|}
+
+  async function f2() {
+    let r = |_|await |C|f1() + await |C|f1();
+    |_|await |C|f1();
+    |_|await |C|f1().|C|then(x => x |_|* 2|R|);
+    |_|await [1].|C|map(x => Promise.|C|resolve(x)|R|)[0];
+    |_|await Promise.|C|resolve().|C|then(x => x |_|* 2|R|);
+    let p = |_|Promise.|C|resolve(42);
+    |_|await p;
+    |_|return r;
+  |R|}
+
+  return |C|f2();|R|
+}
+
+
+Running test: testStepInto
+(anonymous) (expr.js:0:0)
+
+
+testFunction (test.js:18:9)
+(anonymous) (expr.js:0:0)
+
+  return #f2();
+}
+
+f2 (test.js:8:12)
+testFunction (test.js:18:9)
+(anonymous) (expr.js:0:0)
+  async function f2() {
+    let r = #await f1() + await f1();
+    await f1();
+
+f1 (test.js:3:17)
+f2 (test.js:8:18)
+testFunction (test.js:18:9)
+(anonymous) (expr.js:0:0)
+  async function f1() {
+    for (let x = #0; x < 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:22)
+f2 (test.js:8:18)
+testFunction (test.js:18:9)
+(anonymous) (expr.js:0:0)
+  async function f1() {
+    for (let x = 0; x #< 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:32)
+f2 (test.js:8:18)
+testFunction (test.js:18:9)
+(anonymous) (expr.js:0:0)
+  async function f1() {
+    for (let x = 0; x < 1; ++x) #await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:29)
+  async function f1() {
+    for (let x = 0; x < 1; ++#x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:22)
+  async function f1() {
+    for (let x = 0; x #< 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:4:4)
+    for (let x = 0; x < 1; ++x) await x;
+    #return await Promise.resolve(2);
+  }
+
+f1 (test.js:5:2)
+    return await Promise.resolve(2);
+  #}
+
+
+f2 (test.js:8:31)
+  async function f2() {
+    let r = await f1() + await #f1();
+    await f1();
+
+f1 (test.js:3:17)
+f2 (test.js:8:31)
+  async function f1() {
+    for (let x = #0; x < 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:22)
+f2 (test.js:8:31)
+  async function f1() {
+    for (let x = 0; x #< 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:32)
+f2 (test.js:8:31)
+  async function f1() {
+    for (let x = 0; x < 1; ++x) #await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:29)
+  async function f1() {
+    for (let x = 0; x < 1; ++#x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:22)
+  async function f1() {
+    for (let x = 0; x #< 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:4:4)
+    for (let x = 0; x < 1; ++x) await x;
+    #return await Promise.resolve(2);
+  }
+
+f1 (test.js:5:2)
+    return await Promise.resolve(2);
+  #}
+
+
+f2 (test.js:9:4)
+    let r = await f1() + await f1();
+    #await f1();
+    await f1().then(x => x * 2);
+
+f1 (test.js:3:17)
+f2 (test.js:9:10)
+  async function f1() {
+    for (let x = #0; x < 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:22)
+f2 (test.js:9:10)
+  async function f1() {
+    for (let x = 0; x #< 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:32)
+f2 (test.js:9:10)
+  async function f1() {
+    for (let x = 0; x < 1; ++x) #await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:29)
+  async function f1() {
+    for (let x = 0; x < 1; ++#x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:22)
+  async function f1() {
+    for (let x = 0; x #< 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:4:4)
+    for (let x = 0; x < 1; ++x) await x;
+    #return await Promise.resolve(2);
+  }
+
+f1 (test.js:5:2)
+    return await Promise.resolve(2);
+  #}
+
+
+f2 (test.js:10:4)
+    await f1();
+    #await f1().then(x => x * 2);
+    await [1].map(x => Promise.resolve(x))[0];
+
+f1 (test.js:3:17)
+f2 (test.js:10:10)
+  async function f1() {
+    for (let x = #0; x < 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:22)
+f2 (test.js:10:10)
+  async function f1() {
+    for (let x = 0; x #< 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:32)
+f2 (test.js:10:10)
+  async function f1() {
+    for (let x = 0; x < 1; ++x) #await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:29)
+  async function f1() {
+    for (let x = 0; x < 1; ++#x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:22)
+  async function f1() {
+    for (let x = 0; x #< 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:4:4)
+    for (let x = 0; x < 1; ++x) await x;
+    #return await Promise.resolve(2);
+  }
+
+f1 (test.js:5:2)
+    return await Promise.resolve(2);
+  #}
+
+
+f1.then.x (test.js:10:27)
+    await f1();
+    await f1().then(x => x #* 2);
+    await [1].map(x => Promise.resolve(x))[0];
+
+f1.then.x (test.js:10:30)
+    await f1();
+    await f1().then(x => x * 2#);
+    await [1].map(x => Promise.resolve(x))[0];
+
+f2 (test.js:11:4)
+    await f1().then(x => x * 2);
+    #await [1].map(x => Promise.resolve(x))[0];
+    await Promise.resolve().then(x => x * 2);
+
+map.x (test.js:11:31)
+f2 (test.js:11:14)
+    await f1().then(x => x * 2);
+    await [1].map(x => Promise.#resolve(x))[0];
+    await Promise.resolve().then(x => x * 2);
+
+map.x (test.js:11:41)
+f2 (test.js:11:14)
+    await f1().then(x => x * 2);
+    await [1].map(x => Promise.resolve(x)#)[0];
+    await Promise.resolve().then(x => x * 2);
+
+f2 (test.js:12:4)
+    await [1].map(x => Promise.resolve(x))[0];
+    #await Promise.resolve().then(x => x * 2);
+    let p = Promise.resolve(42);
+
+f2 (test.js:13:12)
+    await Promise.resolve().then(x => x * 2);
+    let p = #Promise.resolve(42);
+    await p;
+
+f2 (test.js:14:4)
+    let p = Promise.resolve(42);
+    #await p;
+    return r;
+
+f2 (test.js:15:4)
+    await p;
+    #return r;
+  }
+
+f2 (test.js:16:2)
+    return r;
+  #}
+
+
+
+Running test: testStepOver
+f2 (test.js:8:12)
+testFunction (test.js:18:9)
+(anonymous) (expr.js:0:0)
+  async function f2() {
+    let r = #await f1() + await f1();
+    await f1();
+
+f2 (test.js:8:31)
+  async function f2() {
+    let r = await f1() + await #f1();
+    await f1();
+
+f2 (test.js:9:4)
+    let r = await f1() + await f1();
+    #await f1();
+    await f1().then(x => x * 2);
+
+f2 (test.js:10:4)
+    await f1();
+    #await f1().then(x => x * 2);
+    await [1].map(x => Promise.resolve(x))[0];
+
+f2 (test.js:11:4)
+    await f1().then(x => x * 2);
+    #await [1].map(x => Promise.resolve(x))[0];
+    await Promise.resolve().then(x => x * 2);
+
+f2 (test.js:12:4)
+    await [1].map(x => Promise.resolve(x))[0];
+    #await Promise.resolve().then(x => x * 2);
+    let p = Promise.resolve(42);
+
+f2 (test.js:13:12)
+    await Promise.resolve().then(x => x * 2);
+    let p = #Promise.resolve(42);
+    await p;
+
+f2 (test.js:14:4)
+    let p = Promise.resolve(42);
+    #await p;
+    return r;
+
+f2 (test.js:15:4)
+    await p;
+    #return r;
+  }
+
+f2 (test.js:16:2)
+    return r;
+  #}
+
+
+
+Running test: testStepIntoAfterBreakpoint
+f2 (test.js:9:4)
+    let r = await f1() + await f1();
+    #await f1();
+    await f1().then(x => x * 2);
+
+f1 (test.js:3:17)
+f2 (test.js:9:10)
+  async function f1() {
+    for (let x = #0; x < 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:22)
+f2 (test.js:9:10)
+  async function f1() {
+    for (let x = 0; x #< 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:32)
+f2 (test.js:9:10)
+  async function f1() {
+    for (let x = 0; x < 1; ++x) #await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:29)
+  async function f1() {
+    for (let x = 0; x < 1; ++#x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:3:22)
+  async function f1() {
+    for (let x = 0; x #< 1; ++x) await x;
+    return await Promise.resolve(2);
+
+f1 (test.js:4:4)
+    for (let x = 0; x < 1; ++x) await x;
+    #return await Promise.resolve(2);
+  }
+
diff --git a/src/v8/test/inspector/debugger/break-locations-await.js b/src/v8/test/inspector/debugger/break-locations-await.js
new file mode 100644
index 0000000..665ab83
--- /dev/null
+++ b/src/v8/test/inspector/debugger/break-locations-await.js
@@ -0,0 +1,126 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+  InspectorTest.start('Tests breakable locations in await expression.');
+
+let source = `
+function testFunction() {
+  async function f1() {
+    for (let x = 0; x < 1; ++x) await x;
+    return await Promise.resolve(2);
+  }
+
+  async function f2() {
+    let r = await f1() + await f1();
+    await f1();
+    await f1().then(x => x * 2);
+    await [1].map(x => Promise.resolve(x))[0];
+    await Promise.resolve().then(x => x * 2);
+    let p = Promise.resolve(42);
+    await p;
+    return r;
+  }
+
+  return f2();
+}
+//# sourceURL=test.js`;
+
+contextGroup.addScript(source);
+session.setupScriptMap();
+
+InspectorTest.runAsyncTestSuite([
+  async function testBreakLocations() {
+    Protocol.Debugger.enable();
+    let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
+    let {result:{locations}} = await Protocol.Debugger.getPossibleBreakpoints({
+      start: {lineNumber: 0, columnNumber : 0, scriptId}});
+    dumpAllLocations(locations);
+  },
+
+  async function testStepInto() {
+    Protocol.Debugger.pause();
+    let fin = Protocol.Runtime.evaluate({
+      expression: 'testFunction()//# sourceURL=expr.js', awaitPromise: true}).then(() => false);
+    let result;
+    while (result = await Promise.race([fin, Protocol.Debugger.oncePaused()])) {
+      let {params:{callFrames}} = result;
+      session.logCallFrames(callFrames);
+      session.logSourceLocation(callFrames[0].location);
+      Protocol.Debugger.stepInto();
+    }
+    Protocol.Runtime.evaluate({expression: '42'});
+    await Protocol.Debugger.oncePaused();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testStepOver() {
+    Protocol.Debugger.pause();
+    let fin = Protocol.Runtime.evaluate({
+      expression: 'testFunction()//# sourceURL=expr.js', awaitPromise: true}).then(() => false);
+    Protocol.Debugger.stepInto();
+    await Protocol.Debugger.oncePaused();
+    Protocol.Debugger.stepInto();
+    await Protocol.Debugger.oncePaused();
+
+    let result;
+    while (result = await Promise.race([fin, Protocol.Debugger.oncePaused()])) {
+      let {params:{callFrames}} = result;
+      session.logCallFrames(callFrames);
+      session.logSourceLocation(callFrames[0].location);
+      Protocol.Debugger.stepOver();
+    }
+    Protocol.Runtime.evaluate({expression: '42'});
+    await Protocol.Debugger.oncePaused();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testStepIntoAfterBreakpoint() {
+    Protocol.Debugger.setBreakpointByUrl({lineNumber: 9, url: 'test.js'});
+    Protocol.Runtime.evaluate({
+      expression: 'testFunction()//# sourceURL=expr.js'});
+    await awaitPausedAndDump();
+    Protocol.Debugger.stepInto();
+    await awaitPausedAndDump();
+    Protocol.Debugger.stepInto();
+    await awaitPausedAndDump();
+    Protocol.Debugger.stepInto();
+    await awaitPausedAndDump();
+    Protocol.Debugger.stepInto();
+    await awaitPausedAndDump();
+    Protocol.Debugger.stepInto();
+    await awaitPausedAndDump();
+    Protocol.Debugger.stepInto();
+    await awaitPausedAndDump();
+    await Protocol.Debugger.resume();
+
+    async function awaitPausedAndDump() {
+      let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+      session.logCallFrames(callFrames);
+      session.logSourceLocation(callFrames[0].location);
+    }
+  }
+]);
+
+function dumpAllLocations(locations) {
+  var lines = source.split('\n');
+  var locations = locations.sort((loc1, loc2) => {
+    if (loc2.lineNumber !== loc1.lineNumber) return loc2.lineNumber - loc1.lineNumber;
+    return loc2.columnNumber - loc1.columnNumber;
+  });
+  for (var location of locations) {
+    var line = lines[location.lineNumber];
+    line = line.slice(0, location.columnNumber) + locationMark(location.type) + line.slice(location.columnNumber);
+    lines[location.lineNumber] = line;
+  }
+  lines = lines.filter(line => line.indexOf('//# sourceURL=') === -1);
+  InspectorTest.log(lines.join('\n') + '\n');
+}
+
+function locationMark(type) {
+  if (type === 'return') return '|R|';
+  if (type === 'call') return '|C|';
+  if (type === 'debuggerStatement') return '|D|';
+  return '|_|';
+}
diff --git a/src/v8/test/inspector/debugger/break-locations-var-init-expected.txt b/src/v8/test/inspector/debugger/break-locations-var-init-expected.txt
new file mode 100644
index 0000000..2242088
--- /dev/null
+++ b/src/v8/test/inspector/debugger/break-locations-var-init-expected.txt
@@ -0,0 +1,170 @@
+Tests breakable locations in variable initializations.
+
+Running test: testBreakLocations
+
+Running test: testStepInto
+
+function testFunction() {
+  var obj1 = |_|{a : 1};
+  var arr1 = |_|[1];
+  var promise = |_|Promise.|C|resolve(1).|C|then(x => x |_|* 2|R|).|C|then(x => x |_|/ 2|R|);
+  |_|Promise.|C|resolve(1).|C|then(x => x |_|* 2|R|).|C|then(x => x |_|/ 2|R|);
+  |_|promise = Promise.|C|resolve(1).|C|then(x => x |_|* 2|R|).|C|then(x => x |_|/ 2|R|);
+  var a = |_|1;
+  const x = |_|(a = 20);
+  var y = |_|(a = 100);
+  var z = |_|x + (a = 1) + (a = 2) + (a = 3) + |C|f();
+  function f() {
+    for (let { x, y } = |_|{ x: 0, y: 1 }; y |_|> 0; --|_|y) { let z = |_|x + y; }
+  |R|}
+  var b = obj1.|_|a;
+  |_|(async function asyncF() {
+    let r = |_|await Promise.|C|resolve(42);
+    |_|return r;
+  |R|})|C|();
+  |_|return promise;|R|
+}
+
+(anonymous) (expr.js:0:0)
+
+
+testFunction (test.js:2:13)
+(anonymous) (expr.js:0:0)
+function testFunction() {
+  var obj1 = #{a : 1};
+  var arr1 = [1];
+
+testFunction (test.js:3:13)
+(anonymous) (expr.js:0:0)
+  var obj1 = {a : 1};
+  var arr1 = #[1];
+  var promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
+
+testFunction (test.js:4:16)
+(anonymous) (expr.js:0:0)
+  var arr1 = [1];
+  var promise = #Promise.resolve(1).then(x => x * 2).then(x => x / 2);
+  Promise.resolve(1).then(x => x * 2).then(x => x / 2);
+
+testFunction (test.js:5:2)
+(anonymous) (expr.js:0:0)
+  var promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
+  #Promise.resolve(1).then(x => x * 2).then(x => x / 2);
+  promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
+
+testFunction (test.js:6:2)
+(anonymous) (expr.js:0:0)
+  Promise.resolve(1).then(x => x * 2).then(x => x / 2);
+  #promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
+  var a = 1;
+
+testFunction (test.js:7:10)
+(anonymous) (expr.js:0:0)
+  promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
+  var a = #1;
+  const x = (a = 20);
+
+testFunction (test.js:8:12)
+(anonymous) (expr.js:0:0)
+  var a = 1;
+  const x = #(a = 20);
+  var y = (a = 100);
+
+testFunction (test.js:9:10)
+(anonymous) (expr.js:0:0)
+  const x = (a = 20);
+  var y = #(a = 100);
+  var z = x + (a = 1) + (a = 2) + (a = 3) + f();
+
+testFunction (test.js:10:10)
+(anonymous) (expr.js:0:0)
+  var y = (a = 100);
+  var z = #x + (a = 1) + (a = 2) + (a = 3) + f();
+  function f() {
+
+f (test.js:12:24)
+testFunction (test.js:10:44)
+(anonymous) (expr.js:0:0)
+  function f() {
+    for (let { x, y } = #{ x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
+  }
+
+f (test.js:12:42)
+testFunction (test.js:10:44)
+(anonymous) (expr.js:0:0)
+  function f() {
+    for (let { x, y } = { x: 0, y: 1 }; y #> 0; --y) { let z = x + y; }
+  }
+
+f (test.js:12:62)
+testFunction (test.js:10:44)
+(anonymous) (expr.js:0:0)
+  function f() {
+    for (let { x, y } = { x: 0, y: 1 }; y > 0; --y) { let z = #x + y; }
+  }
+
+f (test.js:12:49)
+testFunction (test.js:10:44)
+(anonymous) (expr.js:0:0)
+  function f() {
+    for (let { x, y } = { x: 0, y: 1 }; y > 0; --#y) { let z = x + y; }
+  }
+
+f (test.js:12:42)
+testFunction (test.js:10:44)
+(anonymous) (expr.js:0:0)
+  function f() {
+    for (let { x, y } = { x: 0, y: 1 }; y #> 0; --y) { let z = x + y; }
+  }
+
+f (test.js:13:2)
+testFunction (test.js:10:44)
+(anonymous) (expr.js:0:0)
+    for (let { x, y } = { x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
+  #}
+  var b = obj1.a;
+
+testFunction (test.js:14:15)
+(anonymous) (expr.js:0:0)
+  }
+  var b = obj1.#a;
+  (async function asyncF() {
+
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+  var b = obj1.a;
+  #(async function asyncF() {
+    let r = await Promise.resolve(42);
+
+asyncF (test.js:16:12)
+testFunction (test.js:18:4)
+(anonymous) (expr.js:0:0)
+  (async function asyncF() {
+    let r = #await Promise.resolve(42);
+    return r;
+
+asyncF (test.js:17:4)
+    let r = await Promise.resolve(42);
+    #return r;
+  })();
+
+asyncF (test.js:18:2)
+    return r;
+  #})();
+  return promise;
+
+
+Running test: testStepIntoAfterBreakpoint
+testFunction (test.js:10:10)
+(anonymous) (expr.js:0:0)
+  var y = (a = 100);
+  var z = #x + (a = 1) + (a = 2) + (a = 3) + f();
+  function f() {
+
+f (test.js:12:24)
+testFunction (test.js:10:44)
+(anonymous) (expr.js:0:0)
+  function f() {
+    for (let { x, y } = #{ x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
+  }
+
diff --git a/src/v8/test/inspector/debugger/break-locations-var-init.js b/src/v8/test/inspector/debugger/break-locations-var-init.js
new file mode 100644
index 0000000..291de8f
--- /dev/null
+++ b/src/v8/test/inspector/debugger/break-locations-var-init.js
@@ -0,0 +1,74 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+  InspectorTest.start('Tests breakable locations in variable initializations.');
+
+let source = `
+function testFunction() {
+  var obj1 = {a : 1};
+  var arr1 = [1];
+  var promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
+  Promise.resolve(1).then(x => x * 2).then(x => x / 2);
+  promise = Promise.resolve(1).then(x => x * 2).then(x => x / 2);
+  var a = 1;
+  const x = (a = 20);
+  var y = (a = 100);
+  var z = x + (a = 1) + (a = 2) + (a = 3) + f();
+  function f() {
+    for (let { x, y } = { x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
+  }
+  var b = obj1.a;
+  (async function asyncF() {
+    let r = await Promise.resolve(42);
+    return r;
+  })();
+  return promise;
+}
+//# sourceURL=test.js`;
+
+contextGroup.addScript(source);
+session.setupScriptMap();
+
+InspectorTest.runAsyncTestSuite([
+  async function testBreakLocations() {
+    Protocol.Debugger.enable();
+    let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
+    let {result:{locations}} = await Protocol.Debugger.getPossibleBreakpoints({
+      start: {lineNumber: 0, columnNumber : 0, scriptId}});
+    session.logBreakLocations(locations);
+  },
+
+  async function testStepInto() {
+    Protocol.Debugger.pause();
+    let fin = Protocol.Runtime.evaluate({
+      expression: 'testFunction()//# sourceURL=expr.js', awaitPromise: true}).then(() => false);
+    let result;
+    while (result = await Promise.race([fin, Protocol.Debugger.oncePaused()])) {
+      let {params:{callFrames}} = result;
+      session.logCallFrames(callFrames);
+      session.logSourceLocation(callFrames[0].location);
+      Protocol.Debugger.stepInto();
+    }
+    Protocol.Runtime.evaluate({expression: '42'});
+    await Protocol.Debugger.oncePaused();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testStepIntoAfterBreakpoint() {
+    Protocol.Debugger.setBreakpointByUrl({lineNumber: 10, url: 'test.js'});
+    Protocol.Runtime.evaluate({
+      expression: 'testFunction()//# sourceURL=expr.js'});
+    await awaitPausedAndDump();
+    Protocol.Debugger.stepInto();
+    await awaitPausedAndDump();
+    await Protocol.Debugger.resume();
+
+    async function awaitPausedAndDump() {
+      let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+      session.logCallFrames(callFrames);
+      session.logSourceLocation(callFrames[0].location);
+    }
+  }
+]);
diff --git a/src/v8/test/inspector/debugger/break-on-exception-expected.txt b/src/v8/test/inspector/debugger/break-on-exception-expected.txt
new file mode 100644
index 0000000..f4d70f0
--- /dev/null
+++ b/src/v8/test/inspector/debugger/break-on-exception-expected.txt
@@ -0,0 +1,12 @@
+Check that inspector correctly change break on exception state.
+
+Running test: noBreakOnExceptionAfterEnabled
+
+Running test: breakOnUncaughtException
+paused in throwUncaughtException
+
+Running test: breakOnCaughtException
+paused in throwUncaughtException
+paused in throwCaughtException
+
+Running test: noBreakInEvaluateInSilentMode
diff --git a/src/v8/test/inspector/debugger/break-on-exception.js b/src/v8/test/inspector/debugger/break-on-exception.js
new file mode 100644
index 0000000..6f47ec8
--- /dev/null
+++ b/src/v8/test/inspector/debugger/break-on-exception.js
@@ -0,0 +1,71 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Check that inspector correctly change break on exception state.");
+
+contextGroup.addScript(`
+function scheduleUncaughtException()
+{
+  setTimeout(throwUncaughtException, 0);
+}
+function throwUncaughtException()
+{
+  throw new Error();
+}
+function throwCaughtException()
+{
+  throw new Error();
+}`);
+
+Protocol.Debugger.onPaused(message => {
+  InspectorTest.log("paused in " + message.params.callFrames[0].functionName);
+  Protocol.Debugger.resume();
+});
+
+Protocol.Runtime.enable();
+
+InspectorTest.runTestSuite([
+  function noBreakOnExceptionAfterEnabled(next)
+  {
+    Protocol.Debugger.enable();
+    Protocol.Debugger.setPauseOnExceptions({ state: "all" });
+    Protocol.Debugger.disable();
+    Protocol.Debugger.enable();
+    Protocol.Runtime.evaluate({ expression: "scheduleUncaughtException()" })
+      .then(() => Protocol.Runtime.evaluate({ expression: "throwCaughtException()" }))
+      .then(() => Protocol.Debugger.disable())
+      .then(next);
+  },
+
+  function breakOnUncaughtException(next)
+  {
+    Protocol.Debugger.enable();
+    Protocol.Debugger.setPauseOnExceptions({ state: "uncaught" });
+    Protocol.Runtime.evaluate({ expression: "scheduleUncaughtException()" })
+      .then(() => Protocol.Runtime.onceExceptionThrown())
+      .then(() => Protocol.Runtime.evaluate({ expression: "throwCaughtException()" }))
+      .then(() => Protocol.Debugger.disable())
+      .then(next);
+  },
+
+  function breakOnCaughtException(next)
+  {
+    Protocol.Debugger.enable();
+    Protocol.Debugger.setPauseOnExceptions({ state: "all" });
+    Protocol.Runtime.evaluate({ expression: "scheduleUncaughtException()" })
+      .then(() => Protocol.Runtime.onceExceptionThrown())
+      .then(() => Protocol.Runtime.evaluate({ expression: "throwCaughtException()" }))
+      .then(() => Protocol.Debugger.disable())
+      .then(next);
+  },
+
+  function noBreakInEvaluateInSilentMode(next)
+  {
+    Protocol.Debugger.enable();
+    Protocol.Debugger.setPauseOnExceptions({ state: "all" })
+      .then(() => Protocol.Runtime.evaluate({ expression: "throwCaughtException()", silent: true }))
+      .then(() => Protocol.Debugger.disable())
+      .then(next);
+  }
+]);
diff --git a/src/v8/test/inspector/debugger/call-frame-function-location-expected.txt b/src/v8/test/inspector/debugger/call-frame-function-location-expected.txt
new file mode 100644
index 0000000..211352c
--- /dev/null
+++ b/src/v8/test/inspector/debugger/call-frame-function-location-expected.txt
@@ -0,0 +1,4 @@
+Tests that function location in call frames is correct
+Paused on 'debugger;'
+Top frame location: {"scriptId":"42","lineNumber":3,"columnNumber":4}
+Top frame functionLocation: {"scriptId":"42","lineNumber":0,"columnNumber":21}
diff --git a/src/v8/test/inspector/debugger/call-frame-function-location.js b/src/v8/test/inspector/debugger/call-frame-function-location.js
new file mode 100644
index 0000000..4775b30
--- /dev/null
+++ b/src/v8/test/inspector/debugger/call-frame-function-location.js
@@ -0,0 +1,27 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that function location in call frames is correct');
+
+contextGroup.addScript(
+`function testFunction()
+{
+    var a = 2;
+    debugger;
+}`);
+
+Protocol.Debugger.enable();
+Protocol.Debugger.oncePaused().then(handleDebuggerPaused);
+Protocol.Runtime.evaluate({ "expression": "setTimeout(testFunction, 0)" });
+
+function handleDebuggerPaused(messageObject)
+{
+  InspectorTest.log("Paused on 'debugger;'");
+  var topFrame = messageObject.params.callFrames[0];
+  topFrame.location.scriptId = "42";
+  topFrame.functionLocation.scriptId = "42";
+  InspectorTest.log("Top frame location: " + JSON.stringify(topFrame.location));
+  InspectorTest.log("Top frame functionLocation: " + JSON.stringify(topFrame.functionLocation));
+  InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/debugger/call-frame-url-expected.txt b/src/v8/test/inspector/debugger/call-frame-url-expected.txt
new file mode 100644
index 0000000..b27b40d
--- /dev/null
+++ b/src/v8/test/inspector/debugger/call-frame-url-expected.txt
@@ -0,0 +1,15 @@
+Tests url in Debugger.CallFrame.
+[
+    [0] : {
+        url : 
+    }
+    [1] : {
+        url : source-url.js
+    }
+    [2] : {
+        url : test.js
+    }
+    [3] : {
+        url : expr.js
+    }
+]
diff --git a/src/v8/test/inspector/debugger/call-frame-url.js b/src/v8/test/inspector/debugger/call-frame-url.js
new file mode 100644
index 0000000..af8e908
--- /dev/null
+++ b/src/v8/test/inspector/debugger/call-frame-url.js
@@ -0,0 +1,20 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+    InspectorTest.start('Tests url in Debugger.CallFrame.');
+
+contextGroup.addScript(`
+eval('function foo1() { debugger; }');
+eval('function foo2() { foo1() } //# sourceURL=source-url.js');
+function foo3() { foo2(); }
+`, 0, 0, 'test.js');
+
+(async function test() {
+  Protocol.Debugger.enable();
+  Protocol.Runtime.evaluate({expression: 'foo3()//# sourceURL=expr.js'});
+  let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+  InspectorTest.logMessage(callFrames.map(frame => ({url: frame.url})));
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/debugger/caught-exception-from-framework-inside-async-expected.txt b/src/v8/test/inspector/debugger/caught-exception-from-framework-inside-async-expected.txt
new file mode 100644
index 0000000..aff06b2
--- /dev/null
+++ b/src/v8/test/inspector/debugger/caught-exception-from-framework-inside-async-expected.txt
@@ -0,0 +1,4 @@
+Async caught exception prediction and blackboxing.
+paused at:
+#debugger;
+
diff --git a/src/v8/test/inspector/debugger/caught-exception-from-framework-inside-async.js b/src/v8/test/inspector/debugger/caught-exception-from-framework-inside-async.js
new file mode 100644
index 0000000..f59e71f
--- /dev/null
+++ b/src/v8/test/inspector/debugger/caught-exception-from-framework-inside-async.js
@@ -0,0 +1,38 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Async caught exception prediction and blackboxing.');
+
+contextGroup.addScript(`
+function constructorThrow() {
+  return new Promise((resolve, reject) =>
+    Promise.resolve().then(() =>
+      reject("f")  // Exception f
+    )
+  );
+}
+
+function dotCatch(producer) {
+  Promise.resolve(producer()).catch(() => {});
+}
+//# sourceURL=framework.js`);
+
+session.setupScriptMap();
+(async function test() {
+  Protocol.Debugger.enable();
+  Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js']});
+  Protocol.Debugger.setPauseOnExceptions({state: 'all'});
+  Protocol.Runtime.evaluate({expression: 'dotCatch(constructorThrow);'});
+  // Should break at this debugger statement, not at reject.
+  Protocol.Runtime.evaluate({expression: 'setTimeout(\'debugger;\', 0);'});
+  await waitPauseAndDumpLocation();
+  InspectorTest.completeTest();
+})();
+
+async function waitPauseAndDumpLocation() {
+  var message = await Protocol.Debugger.oncePaused();
+  InspectorTest.log('paused at:');
+  session.logSourceLocation(message.params.callFrames[0].location);
+  return message;
+}
diff --git a/src/v8/test/inspector/debugger/caught-uncaught-exceptions-expected.txt b/src/v8/test/inspector/debugger/caught-uncaught-exceptions-expected.txt
new file mode 100644
index 0000000..b784fa5
--- /dev/null
+++ b/src/v8/test/inspector/debugger/caught-uncaught-exceptions-expected.txt
@@ -0,0 +1,5 @@
+Check that inspector correctly passes caught/uncaught information.
+paused in throwCaught
+uncaught: false
+paused in throwUncaught
+uncaught: true
diff --git a/src/v8/test/inspector/debugger/caught-uncaught-exceptions.js b/src/v8/test/inspector/debugger/caught-uncaught-exceptions.js
new file mode 100644
index 0000000..38b622d
--- /dev/null
+++ b/src/v8/test/inspector/debugger/caught-uncaught-exceptions.js
@@ -0,0 +1,25 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Check that inspector correctly passes caught/uncaught information.");
+
+contextGroup.addScript(
+`function throwCaught() { try { throw new Error(); } catch (_) {} }
+ function throwUncaught() { throw new Error(); }
+ function schedule(f) { setTimeout(f, 0); }
+`);
+
+Protocol.Debugger.enable();
+
+Protocol.Debugger.setPauseOnExceptions({ "state": "all" });
+Protocol.Debugger.onPaused(message => {
+  InspectorTest.log("paused in " + message.params.callFrames[0].functionName);
+  InspectorTest.log("uncaught: " + message.params.data.uncaught);
+  Protocol.Debugger.resume();
+});
+
+Protocol.Runtime.evaluate({ "expression": "schedule(throwCaught);" })
+  .then(() => Protocol.Runtime.evaluate(
+      { "expression": "schedule(throwUncaught);" }))
+  .then(() => InspectorTest.completeTest());
diff --git a/src/v8/test/inspector/debugger/clear-breakpoints-on-disable-expected.txt b/src/v8/test/inspector/debugger/clear-breakpoints-on-disable-expected.txt
new file mode 100644
index 0000000..0d3794e
--- /dev/null
+++ b/src/v8/test/inspector/debugger/clear-breakpoints-on-disable-expected.txt
@@ -0,0 +1,5 @@
+Tests that we clear breakpoints on agent disabled
+function foo() {#}
+
+foo();#debugger;
+
diff --git a/src/v8/test/inspector/debugger/clear-breakpoints-on-disable.js b/src/v8/test/inspector/debugger/clear-breakpoints-on-disable.js
new file mode 100644
index 0000000..729af84
--- /dev/null
+++ b/src/v8/test/inspector/debugger/clear-breakpoints-on-disable.js
@@ -0,0 +1,28 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+  InspectorTest.start('Tests that we clear breakpoints on agent disabled');
+
+(async function test() {
+session.setupScriptMap();
+  Protocol.Runtime.evaluate({expression: 'function foo() {}'});
+  Protocol.Debugger.enable();
+  let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
+  await Protocol.Debugger.setBreakpoint({
+    location: {
+      lineNumber: 0, columnNumber: 16, scriptId
+    }
+  });
+  Protocol.Runtime.evaluate({expression: 'foo()'});
+  var {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+  await session.logSourceLocation(callFrames[0].location);
+  await Protocol.Debugger.disable();
+  await Protocol.Debugger.enable();
+  Protocol.Debugger.onPaused(InspectorTest.logMessage);
+  Protocol.Runtime.evaluate({expression: 'foo();debugger;'});
+  var {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+  await session.logSourceLocation(callFrames[0].location);
+  InspectorTest.completeTest();
+})()
diff --git a/src/v8/test/inspector/debugger/collect-obsolete-async-tasks-expected.txt b/src/v8/test/inspector/debugger/collect-obsolete-async-tasks-expected.txt
new file mode 100644
index 0000000..c114e34
--- /dev/null
+++ b/src/v8/test/inspector/debugger/collect-obsolete-async-tasks-expected.txt
@@ -0,0 +1,37 @@
+Checks that we collect obsolete async tasks with async stacks.
+Async stacks count: 2
+Scheduled async tasks: 1
+Created async tasks: 1
+Async tasks with parent: 0
+Recurring async tasks: 1
+
+Async stacks count: 0
+Scheduled async tasks: 0
+Created async tasks: 0
+Async tasks with parent: 0
+Recurring async tasks: 0
+
+Async stacks count: 2
+Scheduled async tasks: 0
+Created async tasks: 2
+Async tasks with parent: 2
+Recurring async tasks: 0
+
+Async stacks count: 0
+Scheduled async tasks: 0
+Created async tasks: 0
+Async tasks with parent: 0
+Recurring async tasks: 0
+
+Async stacks count: 1
+Scheduled async tasks: 1
+Created async tasks: 0
+Async tasks with parent: 0
+Recurring async tasks: 0
+
+Async stacks count: 0
+Scheduled async tasks: 0
+Created async tasks: 0
+Async tasks with parent: 0
+Recurring async tasks: 0
+
diff --git a/src/v8/test/inspector/debugger/collect-obsolete-async-tasks.js b/src/v8/test/inspector/debugger/collect-obsolete-async-tasks.js
new file mode 100644
index 0000000..cfef345
--- /dev/null
+++ b/src/v8/test/inspector/debugger/collect-obsolete-async-tasks.js
@@ -0,0 +1,35 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that we collect obsolete async tasks with async stacks.');
+
+contextGroup.addScript(`
+function test() {
+  inspector.setMaxAsyncTaskStacks(128);
+  var p = Promise.resolve();
+
+  inspector.dumpAsyncTaskStacksStateForTest();
+  inspector.setMaxAsyncTaskStacks(128);
+  inspector.dumpAsyncTaskStacksStateForTest();
+
+  p.then(() => 42).then(() => 239);
+
+  inspector.dumpAsyncTaskStacksStateForTest();
+  inspector.setMaxAsyncTaskStacks(128);
+  inspector.dumpAsyncTaskStacksStateForTest();
+
+  setTimeout(() => 42, 0);
+
+  inspector.dumpAsyncTaskStacksStateForTest();
+  inspector.setMaxAsyncTaskStacks(128);
+  inspector.dumpAsyncTaskStacksStateForTest();
+}
+`);
+
+(async function test() {
+  Protocol.Debugger.enable();
+  Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
+  await Protocol.Runtime.evaluate({expression: 'test()'});
+  InspectorTest.completeTest();
+})()
diff --git a/src/v8/test/inspector/debugger/collect-old-async-call-chains-expected.txt b/src/v8/test/inspector/debugger/collect-old-async-call-chains-expected.txt
new file mode 100644
index 0000000..64fef4a
--- /dev/null
+++ b/src/v8/test/inspector/debugger/collect-old-async-call-chains-expected.txt
@@ -0,0 +1,211 @@
+Checks that we drop old async call chains.
+
+Running test: testInfrastructure
+inspector.setMaxAsyncTaskStacks(1024)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(1024)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(1024)
+Run expression 'console.trace(42)' with async chain len: 5
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(1024)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(1024)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 2
+
+inspector.setMaxAsyncTaskStacks(1024)
+Run expression 'console.trace(42)' with async chain len: 5
+actual async chain len: 5
+
+
+Running test: testZeroLimit
+inspector.setMaxAsyncTaskStacks(0)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 0
+
+inspector.setMaxAsyncTaskStacks(0)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 0
+
+inspector.setMaxAsyncTaskStacks(0)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 0
+
+inspector.setMaxAsyncTaskStacks(0)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 0
+
+
+Running test: testOneLimit
+inspector.setMaxAsyncTaskStacks(1)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(1)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(1)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(1)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 1
+
+
+Running test: testTwoLimit
+inspector.setMaxAsyncTaskStacks(2)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(2)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 0
+
+inspector.setMaxAsyncTaskStacks(2)
+Run expression 'console.trace(42)' with async chain len: 3
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(2)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(2)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 2
+
+inspector.setMaxAsyncTaskStacks(2)
+Run expression 'console.trace(42)' with async chain len: 3
+actual async chain len: 1
+
+
+Running test: testMoreThanTwoLimit
+inspector.setMaxAsyncTaskStacks(3)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(3)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(3)
+Run expression 'console.trace(42)' with async chain len: 3
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(3)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(3)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 2
+
+inspector.setMaxAsyncTaskStacks(3)
+Run expression 'console.trace(42)' with async chain len: 3
+actual async chain len: 3
+
+inspector.setMaxAsyncTaskStacks(4)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(4)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(4)
+Run expression 'console.trace(42)' with async chain len: 3
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(4)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(4)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 2
+
+inspector.setMaxAsyncTaskStacks(4)
+Run expression 'console.trace(42)' with async chain len: 3
+actual async chain len: 3
+
+inspector.setMaxAsyncTaskStacks(5)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(5)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(5)
+Run expression 'console.trace(42)' with async chain len: 3
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(5)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(5)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 2
+
+inspector.setMaxAsyncTaskStacks(5)
+Run expression 'console.trace(42)' with async chain len: 3
+actual async chain len: 3
+
+inspector.setMaxAsyncTaskStacks(6)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(6)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(6)
+Run expression 'console.trace(42)' with async chain len: 3
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(6)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(6)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 2
+
+inspector.setMaxAsyncTaskStacks(6)
+Run expression 'console.trace(42)' with async chain len: 3
+actual async chain len: 3
+
+inspector.setMaxAsyncTaskStacks(7)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(7)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(7)
+Run expression 'console.trace(42)' with async chain len: 3
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(7)
+Run expression 'console.trace(42)' with async chain len: 1
+actual async chain len: 1
+
+inspector.setMaxAsyncTaskStacks(7)
+Run expression 'console.trace(42)' with async chain len: 2
+actual async chain len: 2
+
+inspector.setMaxAsyncTaskStacks(7)
+Run expression 'console.trace(42)' with async chain len: 3
+actual async chain len: 3
+
diff --git a/src/v8/test/inspector/debugger/collect-old-async-call-chains.js b/src/v8/test/inspector/debugger/collect-old-async-call-chains.js
new file mode 100644
index 0000000..7ac8225
--- /dev/null
+++ b/src/v8/test/inspector/debugger/collect-old-async-call-chains.js
@@ -0,0 +1,171 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that we drop old async call chains.');
+
+Protocol.Debugger.enable();
+Protocol.Runtime.enable();
+InspectorTest.runAsyncTestSuite([
+  async function testInfrastructure() {
+    Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
+    await setMaxAsyncTaskStacks(1024);
+    runWithAsyncChainPromise(1, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(1024);
+    runWithAsyncChainPromise(2, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(1024);
+    runWithAsyncChainPromise(5, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(1024);
+    runWithAsyncChainSetTimeout(1, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(1024);
+    runWithAsyncChainSetTimeout(2, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(1024);
+    runWithAsyncChainSetTimeout(5, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+  },
+
+  async function testZeroLimit() {
+    const limit = 0;
+    Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainPromise(1, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainPromise(2, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainSetTimeout(1, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainSetTimeout(2, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+  },
+
+  async function testOneLimit() {
+    const limit = 1;
+    Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainPromise(1, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainPromise(2, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainSetTimeout(1, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainSetTimeout(2, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+  },
+
+  async function testTwoLimit() {
+    const limit = 2;
+    Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainPromise(1, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainPromise(2, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainPromise(3, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainSetTimeout(1, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainSetTimeout(2, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    await setMaxAsyncTaskStacks(limit);
+    runWithAsyncChainSetTimeout(3, 'console.trace(42)');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+  },
+
+  async function testMoreThanTwoLimit() {
+    for (let limit = 3; limit <= 7; ++limit) {
+      Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
+
+      await setMaxAsyncTaskStacks(limit);
+      runWithAsyncChainPromise(1, 'console.trace(42)');
+      dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+      await setMaxAsyncTaskStacks(limit);
+      runWithAsyncChainPromise(2, 'console.trace(42)');
+      dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+      await setMaxAsyncTaskStacks(limit);
+      runWithAsyncChainPromise(3, 'console.trace(42)');
+      dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+      await setMaxAsyncTaskStacks(limit);
+      runWithAsyncChainSetTimeout(1, 'console.trace(42)');
+      dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+      await setMaxAsyncTaskStacks(limit);
+      runWithAsyncChainSetTimeout(2, 'console.trace(42)');
+      dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+      await setMaxAsyncTaskStacks(limit);
+      runWithAsyncChainSetTimeout(3, 'console.trace(42)');
+      dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+    }
+  },
+]);
+
+function runWithAsyncChainPromise(len, source) {
+  InspectorTest.log(`Run expression '${source}' with async chain len: ${len}`);
+  let then = '.then(() => 1)';
+  let pause = `.then(() => { ${source} })`;
+  Protocol.Runtime.evaluate({
+    expression: `Promise.resolve()${then.repeat(len - 1)}${pause}`
+  });
+}
+
+function runWithAsyncChainSetTimeout(len, source) {
+  InspectorTest.log(`Run expression '${source}' with async chain len: ${len}`);
+  let setTimeoutPrefix = '() => setTimeout(';
+  let setTimeoutSuffix = ', 0)';
+  Protocol.Runtime.evaluate({
+    expression: `setTimeout(${setTimeoutPrefix.repeat(len - 1)}'${source}'${setTimeoutSuffix.repeat(len - 1)}, 0)`
+  });
+}
+
+function dumpAsyncChainLength(message) {
+  let stackTrace = message.params.asyncStackTrace || message.params.stackTrace.parent;
+  let asyncChainCount = 0;
+  while (stackTrace) {
+    ++asyncChainCount;
+    stackTrace = stackTrace.parent;
+  }
+  InspectorTest.log(`actual async chain len: ${asyncChainCount}\n`);
+}
+
+async function setMaxAsyncTaskStacks(max) {
+  let expression = `inspector.setMaxAsyncTaskStacks(${max})`;
+  InspectorTest.log(expression);
+  await Protocol.Runtime.evaluate({expression});
+}
diff --git a/src/v8/test/inspector/debugger/command-line-api-with-bound-function-expected.txt b/src/v8/test/inspector/debugger/command-line-api-with-bound-function-expected.txt
new file mode 100644
index 0000000..338b136
--- /dev/null
+++ b/src/v8/test/inspector/debugger/command-line-api-with-bound-function-expected.txt
@@ -0,0 +1,23 @@
+Check that debug and monitor methods from Command Line API works with bound function.
+> debug foo and bar
+> call foo and bar
+paused in foo
+paused in boo
+> undebug foo and bar
+> call foo and bar
+> monitor foo and bar
+> call foo and bar
+function foo called
+function boo called
+> unmonitor foo and bar
+> call foo and bar
+> monitor and debug bar
+> call bar
+function boo called
+paused in boo
+> undebug bar
+> call bar
+function boo called
+> debug and unmonitor bar
+> call bar
+paused in boo
diff --git a/src/v8/test/inspector/debugger/command-line-api-with-bound-function.js b/src/v8/test/inspector/debugger/command-line-api-with-bound-function.js
new file mode 100644
index 0000000..3c00585
--- /dev/null
+++ b/src/v8/test/inspector/debugger/command-line-api-with-bound-function.js
@@ -0,0 +1,64 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Check that debug and monitor methods from Command Line API works with bound function.");
+
+contextGroup.addScript(`
+function foo() {}
+function boo() {}
+var bar = boo.bind(null);
+
+function testFunction() {
+  console.log("> debug foo and bar");
+  debug(foo);
+  debug(bar);
+  console.log("> call foo and bar");
+  foo();
+  bar();
+  console.log("> undebug foo and bar");
+  undebug(foo);
+  undebug(bar);
+  console.log("> call foo and bar");
+  foo();
+  bar();
+
+  console.log("> monitor foo and bar");
+  monitor(foo);
+  monitor(bar);
+  console.log("> call foo and bar");
+  foo();
+  bar();
+  console.log("> unmonitor foo and bar");
+  unmonitor(foo);
+  unmonitor(bar);
+  console.log("> call foo and bar");
+  foo();
+  bar();
+
+  console.log("> monitor and debug bar");
+  monitor(bar);
+  debug(bar);
+  console.log("> call bar");
+  bar();
+  console.log("> undebug bar");
+  undebug(bar);
+  console.log("> call bar");
+  bar();
+  console.log("> debug and unmonitor bar");
+  debug(bar);
+  unmonitor(bar);
+  console.log("> call bar");
+  bar();
+}`);
+
+Protocol.Runtime.enable();
+Protocol.Debugger.enable();
+Protocol.Debugger.onPaused(message => {
+  var functionName = message.params.callFrames[0].functionName;
+  InspectorTest.log(`paused in ${functionName}`);
+  Protocol.Debugger.resume();
+});
+Protocol.Runtime.onConsoleAPICalled(message => InspectorTest.log(message.params.args[0].value));
+Protocol.Runtime.evaluate({ expression: "testFunction()", includeCommandLineAPI: true })
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/continue-to-location-expected.txt b/src/v8/test/inspector/debugger/continue-to-location-expected.txt
new file mode 100644
index 0000000..948edd8
--- /dev/null
+++ b/src/v8/test/inspector/debugger/continue-to-location-expected.txt
@@ -0,0 +1,31 @@
+Tests Debugger.continueToLocation
+Paused on debugger statement
+Paused after continueToLocation
+Stopped on line 8, expected 8, requested 8, (0-based numbers).
+Control parameter 'step' calculation result: 1, expected: 1
+SUCCESS
+Paused on debugger statement
+Paused after continueToLocation
+Stopped on line 8, expected 8, requested 8, (0-based numbers).
+Control parameter 'step' calculation result: 1, expected: 1
+SUCCESS
+Paused on debugger statement
+Paused after continueToLocation
+Stopped on line 17, expected 17, requested 12, (0-based numbers).
+Control parameter 'step' calculation result: 6, expected: 6
+SUCCESS
+Paused on debugger statement
+Paused after continueToLocation
+Stopped on line 17, expected 17, requested 13, (0-based numbers).
+Control parameter 'step' calculation result: 6, expected: 6
+SUCCESS
+Paused on debugger statement
+Paused after continueToLocation
+Stopped on line 17, expected 17, requested 17, (0-based numbers).
+Control parameter 'step' calculation result: 6, expected: 6
+SUCCESS
+Paused on debugger statement
+Paused after continueToLocation
+Stopped on line 17, expected 17, requested 17, (0-based numbers).
+Control parameter 'step' calculation result: 6, expected: 6
+SUCCESS
diff --git a/src/v8/test/inspector/debugger/continue-to-location-target-call-frames-expected.txt b/src/v8/test/inspector/debugger/continue-to-location-target-call-frames-expected.txt
new file mode 100644
index 0000000..1f41dcf
--- /dev/null
+++ b/src/v8/test/inspector/debugger/continue-to-location-target-call-frames-expected.txt
@@ -0,0 +1,81 @@
+Check that continue-to-location works with different strategies.
+
+Running test: testAwaitAny
+(anonymous) (expr.js:0:0)
+
+asyncFact (test.js:9:2)
+(anonymous) (expr.js:0:0)
+
+asyncFact (test.js:11:2)
+-- async function --
+asyncFact (test.js:8:24)
+asyncFact (test.js:10:20)
+asyncFact (test.js:10:20)
+asyncFact (test.js:10:20)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testAwaitCurrent
+(anonymous) (expr.js:0:0)
+
+asyncFact (test.js:9:2)
+(anonymous) (expr.js:0:0)
+
+asyncFact (test.js:11:2)
+-- async function --
+asyncFact (test.js:8:24)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testAny
+(anonymous) (expr.js:0:0)
+
+fact (test.js:16:2)
+(anonymous) (expr.js:0:0)
+
+fact (test.js:18:2)
+fact (test.js:17:14)
+fact (test.js:17:14)
+fact (test.js:17:14)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testCurrent
+(anonymous) (expr.js:0:0)
+
+fact (test.js:16:2)
+(anonymous) (expr.js:0:0)
+
+fact (test.js:18:2)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testTopLevelAny
+(anonymous) (expr.js:0:0)
+
+topLevel (test.js:23:2)
+(anonymous) (expr.js:0:0)
+
+(anonymous) (:1:10)
+topLevel (test.js:23:2)
+(anonymous) (expr.js:0:0)
+
+(anonymous) (:4:10)
+topLevel (test.js:23:2)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testTopLevelCurrent
+(anonymous) (expr.js:0:0)
+
+topLevel (test.js:23:2)
+(anonymous) (expr.js:0:0)
+
+(anonymous) (:1:10)
+topLevel (test.js:23:2)
+(anonymous) (expr.js:0:0)
+
+(anonymous) (:4:10)
+topLevel (test.js:23:2)
+(anonymous) (expr.js:0:0)
+
diff --git a/src/v8/test/inspector/debugger/continue-to-location-target-call-frames.js b/src/v8/test/inspector/debugger/continue-to-location-target-call-frames.js
new file mode 100644
index 0000000..c33ff6b
--- /dev/null
+++ b/src/v8/test/inspector/debugger/continue-to-location-target-call-frames.js
@@ -0,0 +1,139 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Check that continue-to-location works with different strategies.');
+
+contextGroup.addScript(`
+async function asyncFact(n) {
+  if (n == 0) return 1;
+  let r = n * await asyncFact(n - 1);
+  console.log(r);
+  return r;
+}
+
+function fact(n) {
+  if (n == 0) return 1;
+  let r = n * fact(n - 1);
+  console.log(r);
+  return r;
+}
+
+function topLevel() {
+  eval(` + '`' + `
+  var a = 1;
+  var b = 2;
+  fact(3);
+  console.log(a + b);
+  ` + '`' + `);
+}
+
+//# sourceURL=test.js`, 7, 26);
+
+session.setupScriptMap();
+InspectorTest.runAsyncTestSuite([
+  async function testAwaitAny() {
+    Protocol.Debugger.enable();
+    Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: 'asyncFact(4)//# sourceURL=expr.js'});
+    await pausedAndDumpStack();
+    Protocol.Debugger.stepInto();
+    let message = await pausedAndDumpStack();
+    let location = message.params.callFrames[0].location;
+    location.lineNumber = 11;
+    Protocol.Debugger.continueToLocation({location, targetCallFrames: 'any'});
+    await pausedAndDumpStack();
+    Protocol.Debugger.disable();
+  },
+
+  async function testAwaitCurrent() {
+    Protocol.Debugger.enable();
+    Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: 'asyncFact(4)//# sourceURL=expr.js'});
+    await pausedAndDumpStack();
+    Protocol.Debugger.stepInto();
+    let message = await pausedAndDumpStack();
+    let location = message.params.callFrames[0].location;
+    location.lineNumber = 11;
+    Protocol.Debugger.continueToLocation({location, targetCallFrames: 'current'});
+    await pausedAndDumpStack();
+    await Protocol.Debugger.resume();
+    Protocol.Debugger.disable();
+  },
+
+  async function testAny() {
+    Protocol.Debugger.enable();
+    Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: 'fact(4)//# sourceURL=expr.js'});
+    await pausedAndDumpStack();
+    Protocol.Debugger.stepInto();
+    let message = await pausedAndDumpStack();
+    let location = message.params.callFrames[0].location;
+    location.lineNumber = 18;
+    Protocol.Debugger.continueToLocation({location, targetCallFrames: 'any'});
+    await pausedAndDumpStack();
+    Protocol.Debugger.disable();
+  },
+
+  async function testCurrent() {
+    Protocol.Debugger.enable();
+    Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: 'fact(4)//# sourceURL=expr.js'});
+    await pausedAndDumpStack();
+    Protocol.Debugger.stepInto();
+    let message = await pausedAndDumpStack();
+    let location = message.params.callFrames[0].location;
+    location.lineNumber = 18;
+    Protocol.Debugger.continueToLocation({location, targetCallFrames: 'current'});
+    await pausedAndDumpStack();
+    await Protocol.Debugger.resume();
+    Protocol.Debugger.disable();
+  },
+
+  async function testTopLevelAny() {
+    Protocol.Debugger.enable();
+    Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: 'topLevel()//# sourceURL=expr.js'});
+    await pausedAndDumpStack();
+    Protocol.Debugger.stepInto();
+    await pausedAndDumpStack();
+    Protocol.Debugger.stepInto();
+    let message = await pausedAndDumpStack();
+    let location = message.params.callFrames[0].location;
+    location.lineNumber = 4;
+    Protocol.Debugger.continueToLocation({location, targetCallFrames: 'any'});
+    await pausedAndDumpStack();
+    Protocol.Debugger.disable();
+  },
+
+  async function testTopLevelCurrent() {
+    Protocol.Debugger.enable();
+    Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: 'topLevel()//# sourceURL=expr.js'});
+    await pausedAndDumpStack();
+    Protocol.Debugger.stepInto();
+    await pausedAndDumpStack();
+    Protocol.Debugger.stepInto();
+    let message = await pausedAndDumpStack();
+    let location = message.params.callFrames[0].location;
+    location.lineNumber = 4;
+    Protocol.Debugger.continueToLocation({location, targetCallFrames: 'current'});
+    await pausedAndDumpStack();
+    await Protocol.Debugger.resume();
+    Protocol.Debugger.disable();
+  }
+]);
+
+async function pausedAndDumpStack() {
+  let message = await Protocol.Debugger.oncePaused();
+  session.logCallFrames(message.params.callFrames);
+  session.logAsyncStackTrace(message.params.asyncStackTrace);
+  InspectorTest.log('');
+  return message;
+}
diff --git a/src/v8/test/inspector/debugger/continue-to-location.js b/src/v8/test/inspector/debugger/continue-to-location.js
new file mode 100644
index 0000000..878499d
--- /dev/null
+++ b/src/v8/test/inspector/debugger/continue-to-location.js
@@ -0,0 +1,116 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests Debugger.continueToLocation');
+
+contextGroup.addScript(
+`function statementsExample()
+{
+  var self = arguments.callee;
+
+  debugger;
+
+  self.step = 1;
+
+  self.step = 2;
+
+  void [
+    self.step = 3,
+    self.step = 4,
+    self.step = 5,
+    self.step = 6
+  ];
+
+  self.step = 7;
+}`);
+
+var scenario = [
+  // requested line number, expected control parameter 'step', expected line number
+  [ 8, 1, 8 ],
+  [ 8, 1, 8 ],
+  [ 12, 6, 17 ],
+  [ 13, 6, 17 ],
+  [ 17, 6, 17 ],
+  [ 17, 6, 17 ],
+];
+
+Protocol.Debugger.enable();
+
+Protocol.Runtime.evaluate({ "expression": "statementsExample" }).then(callbackEvalFunctionObject);
+
+function callbackEvalFunctionObject(response)
+{
+  var functionObjectId = response.result.result.objectId;
+  Protocol.Runtime.getProperties({ objectId: functionObjectId }).then(callbackFunctionDetails);
+}
+
+function callbackFunctionDetails(response)
+{
+  var result = response.result;
+  var scriptId;
+  for (var prop of result.internalProperties) {
+    if (prop.name === "[[FunctionLocation]]")
+      scriptId = prop.value.value.scriptId;
+  }
+
+  nextScenarioStep(0);
+
+  function nextScenarioStep(pos)
+  {
+    if (pos < scenario.length)
+      gotoSinglePassChain(scriptId, scenario[pos][0], scenario[pos][1], scenario[pos][2], nextScenarioStep.bind(this, pos + 1));
+    else
+      InspectorTest.completeTest();
+  }
+}
+
+function gotoSinglePassChain(scriptId, lineNumber, expectedResult, expectedLineNumber, next)
+{
+  Protocol.Debugger.oncePaused().then(handleDebuggerPausedOne);
+
+  Protocol.Runtime.evaluate({ "expression": "setTimeout(statementsExample, 0)" });
+
+  function handleDebuggerPausedOne(messageObject)
+  {
+    InspectorTest.log("Paused on debugger statement");
+
+    Protocol.Debugger.oncePaused().then(handleDebuggerPausedTwo);
+
+    Protocol.Debugger.continueToLocation({ location: { scriptId: scriptId, lineNumber: lineNumber, columnNumber: 0} }).then(logContinueToLocation);
+
+    function logContinueToLocation(response)
+    {
+      if (response.error) {
+        InspectorTest.log("Failed to execute continueToLocation " + JSON.stringify(response.error));
+        InspectorTest.completeTest();
+      }
+    }
+  }
+  function handleDebuggerPausedTwo(messageObject)
+  {
+    InspectorTest.log("Paused after continueToLocation");
+    var actualLineNumber = messageObject.params.callFrames[0].location.lineNumber;
+
+    InspectorTest.log("Stopped on line " + actualLineNumber + ", expected " + expectedLineNumber + ", requested " + lineNumber + ", (0-based numbers).");
+
+    Protocol.Debugger.oncePaused(handleDebuggerPausedUnexpected);
+
+    Protocol.Runtime.evaluate({ "expression": "statementsExample.step" }).then(callbackStepEvaluate);
+  }
+
+  function callbackStepEvaluate(response)
+  {
+    var resultValue = response.result.result.value;
+    InspectorTest.log("Control parameter 'step' calculation result: " + resultValue + ", expected: " + expectedResult);
+    InspectorTest.log(resultValue === expectedResult ? "SUCCESS" : "FAIL");
+    Protocol.Debugger.resume();
+    next();
+  }
+
+  function handleDebuggerPausedUnexpected(messageObject)
+  {
+    InspectorTest.log("Unexpected debugger pause");
+    InspectorTest.completeTest();
+  }
+}
diff --git a/src/v8/test/inspector/debugger/destory-in-break-program-expected.txt b/src/v8/test/inspector/debugger/destory-in-break-program-expected.txt
new file mode 100644
index 0000000..c0ce88e
--- /dev/null
+++ b/src/v8/test/inspector/debugger/destory-in-break-program-expected.txt
@@ -0,0 +1 @@
+Check destroying agent inside of breakProgram
diff --git a/src/v8/test/inspector/debugger/destory-in-break-program.js b/src/v8/test/inspector/debugger/destory-in-break-program.js
new file mode 100644
index 0000000..e002328
--- /dev/null
+++ b/src/v8/test/inspector/debugger/destory-in-break-program.js
@@ -0,0 +1,13 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Check destroying agent inside of breakProgram');
+
+(async function test(){
+  await Protocol.Debugger.enable();
+  Protocol.Runtime.evaluate({expression: 'inspector.breakProgram(\'\', \'{}\')'});
+  await Protocol.Debugger.oncePaused();
+  session.disconnect();
+  InspectorTest.quitImmediately();
+})();
diff --git a/src/v8/test/inspector/debugger/doesnt-step-into-injected-script-expected.txt b/src/v8/test/inspector/debugger/doesnt-step-into-injected-script-expected.txt
new file mode 100644
index 0000000..29ac3bf
--- /dev/null
+++ b/src/v8/test/inspector/debugger/doesnt-step-into-injected-script-expected.txt
@@ -0,0 +1,17 @@
+Check that stepInto at then end of the script go to next user script instead InjectedScriptSource.js.
+paused at:
+(function boo() { setTimeout(() => 239, 0); #debugger; })()
+
+
+paused at:
+(function boo() { setTimeout(() => 239, 0); debugger; #})()
+
+
+paused at:
+(function boo() { setTimeout(() => 239, 0); debugger; })()#
+
+
+paused at:
+(function boo() { setTimeout(() => #239, 0); debugger; })()
+
+
diff --git a/src/v8/test/inspector/debugger/doesnt-step-into-injected-script.js b/src/v8/test/inspector/debugger/doesnt-step-into-injected-script.js
new file mode 100644
index 0000000..98c7bf2
--- /dev/null
+++ b/src/v8/test/inspector/debugger/doesnt-step-into-injected-script.js
@@ -0,0 +1,27 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Check that stepInto at then end of the script go to next user script instead InjectedScriptSource.js.');
+
+(async function test() {
+  session.setupScriptMap();
+  await Protocol.Debugger.enable();
+  Protocol.Runtime.evaluate({expression: '(function boo() { setTimeout(() => 239, 0); debugger; })()\n'});
+  await waitPauseAndDumpLocation();
+  Protocol.Debugger.stepInto();
+  await waitPauseAndDumpLocation();
+  Protocol.Debugger.stepInto();
+  await waitPauseAndDumpLocation();
+  Protocol.Debugger.stepInto();
+  await waitPauseAndDumpLocation();
+  await Protocol.Debugger.disable();
+  InspectorTest.completeTest();
+})();
+
+async function waitPauseAndDumpLocation() {
+  var message = await Protocol.Debugger.oncePaused();
+  InspectorTest.log('paused at:');
+  session.logSourceLocation(message.params.callFrames[0].location);
+  return message;
+}
diff --git a/src/v8/test/inspector/debugger/es6-module-script-parsed-expected.txt b/src/v8/test/inspector/debugger/es6-module-script-parsed-expected.txt
new file mode 100644
index 0000000..7639ab6
--- /dev/null
+++ b/src/v8/test/inspector/debugger/es6-module-script-parsed-expected.txt
@@ -0,0 +1,58 @@
+Debugger.scriptParsed and Debugger.scriptFailedToParse with ES6 module
+
+Running test: testLoadedModulesOnDebuggerEnable
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 1
+        endLine : 3
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : F8E59942466284E2766FD161CA6FFD024048A807
+        isLiveEdit : false
+        isModule : true
+        length : 39
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : module1.js
+    }
+}
+
+Running test: testScriptEventsWhenDebuggerIsEnabled
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 1
+        endLine : 3
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : F8E59942466284E2766FD161CA6FFD024048A807
+        isLiveEdit : false
+        isModule : true
+        length : 39
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : module2.js
+    }
+}
+{
+    method : Debugger.scriptFailedToParse
+    params : {
+        endColumn : 1
+        endLine : 0
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : FF746120E4E4F1BA4CB5762843D429DC872EBA18
+        isModule : true
+        length : 1
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : module-with-syntax-error-2.js
+    }
+}
diff --git a/src/v8/test/inspector/debugger/es6-module-script-parsed.js b/src/v8/test/inspector/debugger/es6-module-script-parsed.js
new file mode 100644
index 0000000..94b623d
--- /dev/null
+++ b/src/v8/test/inspector/debugger/es6-module-script-parsed.js
@@ -0,0 +1,28 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Debugger.scriptParsed and Debugger.scriptFailedToParse with ES6 module');
+
+let moduleSource = `
+export function foo() {
+  return 42;
+}`;
+
+contextGroup.addModule(moduleSource, 'module1.js');
+contextGroup.addModule('}', 'module-with-syntax-error-1.js');
+
+Protocol.Debugger.onScriptParsed(InspectorTest.logMessage);
+Protocol.Debugger.onScriptFailedToParse(InspectorTest.logMessage);
+
+InspectorTest.runTestSuite([
+  function testLoadedModulesOnDebuggerEnable(next) {
+    Protocol.Debugger.enable().then(next);
+  },
+
+  function testScriptEventsWhenDebuggerIsEnabled(next) {
+    contextGroup.addModule(moduleSource, 'module2.js');
+    contextGroup.addModule('}', 'module-with-syntax-error-2.js');
+    InspectorTest.waitForPendingTasks().then(next);
+  }
+]);
diff --git a/src/v8/test/inspector/debugger/es6-module-set-script-source-expected.txt b/src/v8/test/inspector/debugger/es6-module-set-script-source-expected.txt
new file mode 100644
index 0000000..cd0ef1f
--- /dev/null
+++ b/src/v8/test/inspector/debugger/es6-module-set-script-source-expected.txt
@@ -0,0 +1,8 @@
+Checks that Debugger.setScriptSource doesn't crash with modules
+{
+    error : {
+        code : -32000
+        message : Editing module's script is not supported.
+    }
+    id : <messageId>
+}
diff --git a/src/v8/test/inspector/debugger/es6-module-set-script-source.js b/src/v8/test/inspector/debugger/es6-module-set-script-source.js
new file mode 100644
index 0000000..81d97b6
--- /dev/null
+++ b/src/v8/test/inspector/debugger/es6-module-set-script-source.js
@@ -0,0 +1,33 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that Debugger.setScriptSource doesn\'t crash with modules');
+
+var module1 = `
+export function foo() {
+  return 42;
+}`;
+
+var editedModule1 = `
+export function foo() {
+  return 239;
+}`;
+
+var module2 = `
+import { foo } from 'module1';
+console.log(foo());
+`;
+
+var module1Id;
+Protocol.Debugger.onScriptParsed(message => {
+  if (message.params.url === 'module1')
+    module1Id = message.params.scriptId;
+});
+Protocol.Debugger.enable()
+  .then(() => contextGroup.addModule(module1, 'module1'))
+  .then(() => contextGroup.addModule(module2, 'module2'))
+  .then(() => InspectorTest.waitForPendingTasks())
+  .then(() => Protocol.Debugger.setScriptSource({ scriptId: module1Id, scriptSource: editedModule1 }))
+  .then(InspectorTest.logMessage)
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/eval-scopes-expected.txt b/src/v8/test/inspector/debugger/eval-scopes-expected.txt
new file mode 100644
index 0000000..71d6618
--- /dev/null
+++ b/src/v8/test/inspector/debugger/eval-scopes-expected.txt
@@ -0,0 +1,20 @@
+Tests that variables introduced in eval scopes are accessible
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : hest
+                value : {
+                    description : 420
+                    type : number
+                    value : 420
+                }
+                writable : true
+            }
+        ]
+    }
+}
diff --git a/src/v8/test/inspector/debugger/eval-scopes.js b/src/v8/test/inspector/debugger/eval-scopes.js
new file mode 100644
index 0000000..e5a0f13
--- /dev/null
+++ b/src/v8/test/inspector/debugger/eval-scopes.js
@@ -0,0 +1,45 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that variables introduced in eval scopes are accessible');
+
+contextGroup.addScript(
+`function testNonEmptyEvalScope() {
+  eval("'use strict'; var hest = 420; debugger;");
+}
+function testEmptyEvalScope() {
+  eval("var fisk = 42; testNonEmptyEvalScope();");
+}`);
+
+Protocol.Debugger.enable();
+Protocol.Debugger.oncePaused().then(dumpScopeOnPause);
+Protocol.Runtime.evaluate({ "expression": "testEmptyEvalScope();" });
+
+var waitScopeObjects = 0;
+function dumpScopeOnPause(message)
+{
+  var scopeChain = message.params.callFrames[0].scopeChain;
+  var evalScopeObjectIds = [];
+  for (var scope of scopeChain) {
+    if (scope.type === "eval") {
+      evalScopeObjectIds.push(scope.object.objectId);
+    }
+  }
+  waitScopeObjects = evalScopeObjectIds.length;
+  if (!waitScopeObjects) {
+    InspectorTest.completeTest();
+  } else {
+    for (var objectId of evalScopeObjectIds)
+      Protocol.Runtime.getProperties({ "objectId" : objectId })
+          .then(dumpProperties);
+  }
+}
+
+function dumpProperties(message)
+{
+  InspectorTest.logMessage(message);
+  --waitScopeObjects;
+  if (!waitScopeObjects)
+    Protocol.Debugger.resume().then(InspectorTest.completeTest);
+}
diff --git a/src/v8/test/inspector/debugger/evaluate-on-call-frame-in-module-expected.txt b/src/v8/test/inspector/debugger/evaluate-on-call-frame-in-module-expected.txt
new file mode 100644
index 0000000..e4819bd
--- /dev/null
+++ b/src/v8/test/inspector/debugger/evaluate-on-call-frame-in-module-expected.txt
@@ -0,0 +1,505 @@
+Tests evaluateOnCallFrame in module.
+
+Running test: testTotal
+foo1 (module1:7:2)
+foo2 (module2:6:9)
+(anonymous) (module3:4:0)
+local:foo1
+[
+    [0] : c1 = 12
+    [1] : g1 = 2
+]
+module
+[
+    [0] : a1 = 10
+    [1] : g1 = 1
+    [2] : b1 = 11
+    [3] : foo1 = function foo1() {   let c1 = 12;   let g1 = 2;   debugger;   return a1 + b1 + c1 + g1; }
+]
+global
+[
+  ...
+]
+Check variables in frame#0
+  let g1 = 2;
+  #debugger;
+  return a1 + b1 + c1 + g1;
+
+Array = 
+{
+    className : Function
+    description : function Array() { [native code] }
+    objectId : <objectId>
+    type : function
+}
+c1 = 
+{
+    description : 12
+    type : number
+    value : 12
+}
+Evaluating: ++c1
+updated c1 = 
+{
+    description : 13
+    type : number
+    value : 13
+}
+Evaluating: --c1
+g1 = 
+{
+    description : 2
+    type : number
+    value : 2
+}
+Evaluating: ++g1
+updated g1 = 
+{
+    description : 3
+    type : number
+    value : 3
+}
+Evaluating: --g1
+a1 = 
+{
+    description : 10
+    type : number
+    value : 10
+}
+Evaluating: ++a1
+updated a1 = 
+{
+    description : 11
+    type : number
+    value : 11
+}
+Evaluating: --a1
+b1 = 
+{
+    description : 11
+    type : number
+    value : 11
+}
+Evaluating: ++b1
+updated b1 = 
+{
+    description : 12
+    type : number
+    value : 12
+}
+Evaluating: --b1
+foo1 = 
+{
+    className : Function
+    description : function foo1() {   let c1 = 12;   let g1 = 2;   debugger;   return a1 + b1 + c1 + g1; }
+    objectId : <objectId>
+    type : function
+}
+local:foo2
+[
+    [0] : c2 = 22
+]
+module
+[
+    [0] : a2 = 20
+    [1] : foo1 = function foo1() {   let c1 = 12;   let g1 = 2;   debugger;   return a1 + b1 + c1 + g1; }
+    [2] : b2 = 21
+    [3] : foo2 = function foo2() {   let c2 = 22;   return foo1() + a2 + b2 + c2; }
+]
+global
+[
+  ...
+]
+Check variables in frame#1
+  let c2 = 22;
+  return #foo1() + a2 + b2 + c2;
+}
+
+Array = 
+{
+    className : Function
+    description : function Array() { [native code] }
+    objectId : <objectId>
+    type : function
+}
+c2 = 
+{
+    description : 22
+    type : number
+    value : 22
+}
+Evaluating: ++c2
+updated c2 = 
+{
+    description : 23
+    type : number
+    value : 23
+}
+Evaluating: --c2
+a2 = 
+{
+    description : 20
+    type : number
+    value : 20
+}
+Evaluating: ++a2
+updated a2 = 
+{
+    description : 21
+    type : number
+    value : 21
+}
+Evaluating: --a2
+foo1 = 
+{
+    className : Function
+    description : function foo1() {   let c1 = 12;   let g1 = 2;   debugger;   return a1 + b1 + c1 + g1; }
+    objectId : <objectId>
+    type : function
+}
+b2 = 
+{
+    description : 21
+    type : number
+    value : 21
+}
+Evaluating: ++b2
+updated b2 = 
+{
+    description : 22
+    type : number
+    value : 22
+}
+Evaluating: --b2
+foo2 = 
+{
+    className : Function
+    description : function foo2() {   let c2 = 22;   return foo1() + a2 + b2 + c2; }
+    objectId : <objectId>
+    type : function
+}
+module
+[
+    [0] : a3 = 30
+    [1] : foo2 = function foo2() {   let c2 = 22;   return foo1() + a2 + b2 + c2; }
+    [2] : b3 = 31
+]
+global
+[
+  ...
+]
+Check variables in frame#2
+export let b3 = 31;
+#foo2();
+
+
+Array = 
+{
+    className : Function
+    description : function Array() { [native code] }
+    objectId : <objectId>
+    type : function
+}
+a3 = 
+{
+    description : 30
+    type : number
+    value : 30
+}
+Evaluating: ++a3
+updated a3 = 
+{
+    description : 31
+    type : number
+    value : 31
+}
+Evaluating: --a3
+foo2 = 
+{
+    className : Function
+    description : function foo2() {   let c2 = 22;   return foo1() + a2 + b2 + c2; }
+    objectId : <objectId>
+    type : function
+}
+b3 = 
+{
+    description : 31
+    type : number
+    value : 31
+}
+Evaluating: ++b3
+updated b3 = 
+{
+    description : 32
+    type : number
+    value : 32
+}
+Evaluating: --b3
+
+Running test: testAnother
+(anonymous) (module4:5:13)
+bar (module4:5:24)
+(anonymous) (module4:7:0)
+local
+[
+]
+closure:bar
+[
+    [0] : a = 0
+]
+module
+[
+    [0] : a = 1
+    [1] : b = 2
+    [2] : bar = function bar() {   let a = 0;   (() => {a; debugger;})(); }
+]
+global
+[
+  ...
+]
+Check variables in frame#0
+  let a = 0;
+  (() => {a; #debugger;})();
+};
+
+Array = 
+{
+    className : Function
+    description : function Array() { [native code] }
+    objectId : <objectId>
+    type : function
+}
+a = 
+{
+    description : 0
+    type : number
+    value : 0
+}
+Evaluating: ++a
+updated a = 
+{
+    description : 1
+    type : number
+    value : 1
+}
+Evaluating: --a
+b = 
+{
+    description : 2
+    type : number
+    value : 2
+}
+Evaluating: ++b
+updated b = 
+{
+    description : 3
+    type : number
+    value : 3
+}
+Evaluating: --b
+bar = 
+{
+    className : Function
+    description : function bar() {   let a = 0;   (() => {a; debugger;})(); }
+    objectId : <objectId>
+    type : function
+}
+local:bar
+[
+    [0] : a = 0
+]
+module
+[
+    [0] : a = 1
+    [1] : b = 2
+    [2] : bar = function bar() {   let a = 0;   (() => {a; debugger;})(); }
+]
+global
+[
+  ...
+]
+Check variables in frame#1
+  let a = 0;
+  (() => {a; debugger;})#();
+};
+
+Array = 
+{
+    className : Function
+    description : function Array() { [native code] }
+    objectId : <objectId>
+    type : function
+}
+a = 
+{
+    description : 0
+    type : number
+    value : 0
+}
+Evaluating: ++a
+updated a = 
+{
+    description : 1
+    type : number
+    value : 1
+}
+Evaluating: --a
+b = 
+{
+    description : 2
+    type : number
+    value : 2
+}
+Evaluating: ++b
+updated b = 
+{
+    description : 3
+    type : number
+    value : 3
+}
+Evaluating: --b
+bar = 
+{
+    className : Function
+    description : function bar() {   let a = 0;   (() => {a; debugger;})(); }
+    objectId : <objectId>
+    type : function
+}
+module
+[
+    [0] : a = 1
+    [1] : b = 2
+    [2] : bar = function bar() {   let a = 0;   (() => {a; debugger;})(); }
+]
+global
+[
+  ...
+]
+Check variables in frame#2
+};
+#bar();
+
+Array = 
+{
+    className : Function
+    description : function Array() { [native code] }
+    objectId : <objectId>
+    type : function
+}
+a = 
+{
+    description : 1
+    type : number
+    value : 1
+}
+Evaluating: ++a
+updated a = 
+{
+    description : 2
+    type : number
+    value : 2
+}
+Evaluating: --a
+b = 
+{
+    description : 2
+    type : number
+    value : 2
+}
+Evaluating: ++b
+updated b = 
+{
+    description : 3
+    type : number
+    value : 3
+}
+Evaluating: --b
+bar = 
+{
+    className : Function
+    description : function bar() {   let a = 0;   (() => {a; debugger;})(); }
+    objectId : <objectId>
+    type : function
+}
+
+Running test: testDifferentModuleVariables
+(anonymous) (module5:5:0)
+module
+[
+    [0] : b2 = 21
+    [1] : a = 0
+    [2] : b = 0
+    [3] : c = 0
+]
+global
+[
+  ...
+]
+Check variables in frame#0
+export var c = 0;
+#debugger;
+
+
+Array = 
+{
+    className : Function
+    description : function Array() { [native code] }
+    objectId : <objectId>
+    type : function
+}
+b2 = 
+{
+    description : 21
+    type : number
+    value : 21
+}
+Evaluating: ++b2
+updated b2 = 
+{
+    description : 21
+    type : number
+    value : 21
+}
+Evaluating: --b2
+a = 
+{
+    description : 0
+    type : number
+    value : 0
+}
+Evaluating: ++a
+updated a = 
+{
+    description : 0
+    type : number
+    value : 0
+}
+Evaluating: --a
+b = 
+{
+    description : 0
+    type : number
+    value : 0
+}
+Evaluating: ++b
+updated b = 
+{
+    description : 1
+    type : number
+    value : 1
+}
+Evaluating: --b
+c = 
+{
+    description : 0
+    type : number
+    value : 0
+}
+Evaluating: ++c
+updated c = 
+{
+    description : 1
+    type : number
+    value : 1
+}
+Evaluating: --c
diff --git a/src/v8/test/inspector/debugger/evaluate-on-call-frame-in-module.js b/src/v8/test/inspector/debugger/evaluate-on-call-frame-in-module.js
new file mode 100644
index 0000000..ef9050e
--- /dev/null
+++ b/src/v8/test/inspector/debugger/evaluate-on-call-frame-in-module.js
@@ -0,0 +1,141 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+  InspectorTest.start('Tests evaluateOnCallFrame in module.');
+
+var module1 = `
+let a1 = 10;
+let g1 = 1;
+export let b1 = 11;
+export function foo1() {
+  let c1 = 12;
+  let g1 = 2;
+  debugger;
+  return a1 + b1 + c1 + g1;
+}`;
+
+var module2 = `
+import { foo1 } from 'module1';
+let a2 = 20;
+export let b2 = 21;
+export function foo2() {
+  let c2 = 22;
+  return foo1() + a2 + b2 + c2;
+}`;
+
+var module3 = `
+import { foo2 } from 'module2';
+let a3 = 30;
+export let b3 = 31;
+foo2();
+`;
+
+var module4 = `
+let a = 1;
+let b = 2;
+function bar() {
+  let a = 0;
+  (() => {a; debugger;})();
+};
+bar();`;
+
+var module5 = `
+import { b2 } from 'module2';
+export const a = 0;
+export let b = 0;
+export var c = 0;
+debugger;
+`;
+
+InspectorTest.runAsyncTestSuite([
+  async function testTotal() {
+    session.setupScriptMap();
+    Protocol.Debugger.enable();
+    contextGroup.addModule(module1, 'module1');
+    contextGroup.addModule(module2, 'module2');
+    contextGroup.addModule(module3, 'module3');
+    let {params:{callFrames}} = (await Protocol.Debugger.oncePaused());
+    session.logCallFrames(callFrames);
+    for (let i = 0; i < callFrames.length; ++i) {
+      await checkFrame(callFrames[i], i);
+    }
+    await Protocol.Debugger.resume();
+  },
+
+  async function testAnother() {
+    contextGroup.addModule(module4, 'module4');
+    let {params:{callFrames}} = (await Protocol.Debugger.oncePaused());
+    session.logCallFrames(callFrames);
+    for (let i = 0; i < callFrames.length; ++i) {
+      await checkFrame(callFrames[i], i);
+    }
+    await Protocol.Debugger.resume();
+  },
+
+  async function testDifferentModuleVariables() {
+    contextGroup.addModule(module5, 'module5');
+    let {params:{callFrames}} = (await Protocol.Debugger.oncePaused());
+    session.logCallFrames(callFrames);
+    for (let i = 0; i < callFrames.length; ++i) {
+      await checkFrame(callFrames[i], i);
+    }
+    await Protocol.Debugger.resume();
+  }
+]);
+
+async function checkFrame(frame, i) {
+  let variables = new Set();
+  variables.add('Array');
+
+  for (let scopeChain of frame.scopeChain) {
+    if (scopeChain.name) {
+      InspectorTest.log(scopeChain.type + ':' + scopeChain.name);
+    } else {
+      InspectorTest.log(scopeChain.type);
+    }
+    if (scopeChain.type === 'global') {
+      InspectorTest.log('[\n  ...\n]');
+      continue;
+    }
+    let {result: {result}} = await Protocol.Runtime.getProperties({
+        objectId: scopeChain.object.objectId});
+    result.forEach(v => variables.add(v.name));
+    result = result.map(v => v.value  ?
+       (v.name + ' = ' + v.value.description) : (v.name));
+    InspectorTest.logMessage(result);
+  }
+
+  InspectorTest.log(`Check variables in frame#${i}`);
+  await session.logSourceLocation(frame.location);
+  await checkVariables(frame.callFrameId, variables);
+}
+
+async function checkVariables(callFrameId, names) {
+  for (let name of names) {
+    var {result:{result}} = await Protocol.Debugger.evaluateOnCallFrame({
+      callFrameId, expression: name});
+    if (result.type === 'object' && result.subtype && result.subtype === 'error') {
+      continue;
+    }
+    InspectorTest.log(name + ' = ');
+    InspectorTest.logMessage(result);
+    if (result.type === "number") {
+      let updateExpression = '++' + name;
+      InspectorTest.log('Evaluating: ' + updateExpression);
+      await Protocol.Debugger.evaluateOnCallFrame({
+        callFrameId, expression: updateExpression});
+
+      var {result:{result}} = await Protocol.Debugger.evaluateOnCallFrame({
+        callFrameId, expression: name});
+      InspectorTest.log('updated ' + name + ' = ');
+      InspectorTest.logMessage(result);
+
+      updateExpression = '--' + name;
+      InspectorTest.log('Evaluating: ' + updateExpression);
+      await Protocol.Debugger.evaluateOnCallFrame({
+        callFrameId, expression: updateExpression});
+    }
+  }
+}
diff --git a/src/v8/test/inspector/debugger/for-of-loops-expected.txt b/src/v8/test/inspector/debugger/for-of-loops-expected.txt
new file mode 100644
index 0000000..6d23c94
--- /dev/null
+++ b/src/v8/test/inspector/debugger/for-of-loops-expected.txt
@@ -0,0 +1,395 @@
+Tests breakable locations in for-of loops.
+
+Running test: testBreakLocations
+
+Running test: testStepInto
+
+function testFunction() {
+  var obj = |_|{a : 1};
+  var arr = |_|[1];
+  var all = |_|[];
+  for (var |_|k in |_|arr) { all.|C|push(k); }
+  for (var |_|k of |_|arr) { all.|C|push(k); }
+  for (var |_|k in |_|obj) { all.|C|push(k); }
+  for (let |_|k in |_|arr) { all.|C|push(k); }
+  for (let |_|k of |_|arr) { all.|C|push(k); }
+  for (let |_|k in |_|obj) { all.|C|push(k); }
+
+  var iterable = |_|{
+    [Symbol.iterator]() {
+      |_|return {
+        i: 0,
+        next() {
+          if (this.|_|i < 1) {
+            |_|return { value: this.i++, done: false };|R|
+          }
+          |_|return { value: undefined, done: true };|R|
+        }
+      };|R|
+    }
+  };
+  for (var |_|k of |_|iterable) { all.|C|push(k); }
+  |_|iterable.i = 0;
+  for (let |_|k of |_|iterable) { all.|C|push(k); }
+|R|}
+
+(anonymous) (expr.js:0:0)
+
+
+testFunction (test.js:2:12)
+(anonymous) (expr.js:0:0)
+function testFunction() {
+  var obj = #{a : 1};
+  var arr = [1];
+
+testFunction (test.js:3:12)
+(anonymous) (expr.js:0:0)
+  var obj = {a : 1};
+  var arr = #[1];
+  var all = [];
+
+testFunction (test.js:4:12)
+(anonymous) (expr.js:0:0)
+  var arr = [1];
+  var all = #[];
+  for (var k in arr) { all.push(k); }
+
+testFunction (test.js:5:16)
+(anonymous) (expr.js:0:0)
+  var all = [];
+  for (var k in #arr) { all.push(k); }
+  for (var k of arr) { all.push(k); }
+
+testFunction (test.js:5:11)
+(anonymous) (expr.js:0:0)
+  var all = [];
+  for (var #k in arr) { all.push(k); }
+  for (var k of arr) { all.push(k); }
+
+testFunction (test.js:5:27)
+(anonymous) (expr.js:0:0)
+  var all = [];
+  for (var k in arr) { all.#push(k); }
+  for (var k of arr) { all.push(k); }
+
+testFunction (test.js:5:11)
+(anonymous) (expr.js:0:0)
+  var all = [];
+  for (var #k in arr) { all.push(k); }
+  for (var k of arr) { all.push(k); }
+
+testFunction (test.js:6:16)
+(anonymous) (expr.js:0:0)
+  for (var k in arr) { all.push(k); }
+  for (var k of #arr) { all.push(k); }
+  for (var k in obj) { all.push(k); }
+
+testFunction (test.js:6:11)
+(anonymous) (expr.js:0:0)
+  for (var k in arr) { all.push(k); }
+  for (var #k of arr) { all.push(k); }
+  for (var k in obj) { all.push(k); }
+
+testFunction (test.js:6:27)
+(anonymous) (expr.js:0:0)
+  for (var k in arr) { all.push(k); }
+  for (var k of arr) { all.#push(k); }
+  for (var k in obj) { all.push(k); }
+
+testFunction (test.js:6:11)
+(anonymous) (expr.js:0:0)
+  for (var k in arr) { all.push(k); }
+  for (var #k of arr) { all.push(k); }
+  for (var k in obj) { all.push(k); }
+
+testFunction (test.js:7:16)
+(anonymous) (expr.js:0:0)
+  for (var k of arr) { all.push(k); }
+  for (var k in #obj) { all.push(k); }
+  for (let k in arr) { all.push(k); }
+
+testFunction (test.js:7:11)
+(anonymous) (expr.js:0:0)
+  for (var k of arr) { all.push(k); }
+  for (var #k in obj) { all.push(k); }
+  for (let k in arr) { all.push(k); }
+
+testFunction (test.js:7:27)
+(anonymous) (expr.js:0:0)
+  for (var k of arr) { all.push(k); }
+  for (var k in obj) { all.#push(k); }
+  for (let k in arr) { all.push(k); }
+
+testFunction (test.js:7:11)
+(anonymous) (expr.js:0:0)
+  for (var k of arr) { all.push(k); }
+  for (var #k in obj) { all.push(k); }
+  for (let k in arr) { all.push(k); }
+
+testFunction (test.js:8:16)
+(anonymous) (expr.js:0:0)
+  for (var k in obj) { all.push(k); }
+  for (let k in #arr) { all.push(k); }
+  for (let k of arr) { all.push(k); }
+
+testFunction (test.js:8:11)
+(anonymous) (expr.js:0:0)
+  for (var k in obj) { all.push(k); }
+  for (let #k in arr) { all.push(k); }
+  for (let k of arr) { all.push(k); }
+
+testFunction (test.js:8:27)
+(anonymous) (expr.js:0:0)
+  for (var k in obj) { all.push(k); }
+  for (let k in arr) { all.#push(k); }
+  for (let k of arr) { all.push(k); }
+
+testFunction (test.js:8:11)
+(anonymous) (expr.js:0:0)
+  for (var k in obj) { all.push(k); }
+  for (let #k in arr) { all.push(k); }
+  for (let k of arr) { all.push(k); }
+
+testFunction (test.js:9:16)
+(anonymous) (expr.js:0:0)
+  for (let k in arr) { all.push(k); }
+  for (let k of #arr) { all.push(k); }
+  for (let k in obj) { all.push(k); }
+
+testFunction (test.js:9:11)
+(anonymous) (expr.js:0:0)
+  for (let k in arr) { all.push(k); }
+  for (let #k of arr) { all.push(k); }
+  for (let k in obj) { all.push(k); }
+
+testFunction (test.js:9:27)
+(anonymous) (expr.js:0:0)
+  for (let k in arr) { all.push(k); }
+  for (let k of arr) { all.#push(k); }
+  for (let k in obj) { all.push(k); }
+
+testFunction (test.js:9:11)
+(anonymous) (expr.js:0:0)
+  for (let k in arr) { all.push(k); }
+  for (let #k of arr) { all.push(k); }
+  for (let k in obj) { all.push(k); }
+
+testFunction (test.js:10:16)
+(anonymous) (expr.js:0:0)
+  for (let k of arr) { all.push(k); }
+  for (let k in #obj) { all.push(k); }
+
+
+testFunction (test.js:10:11)
+(anonymous) (expr.js:0:0)
+  for (let k of arr) { all.push(k); }
+  for (let #k in obj) { all.push(k); }
+
+
+testFunction (test.js:10:27)
+(anonymous) (expr.js:0:0)
+  for (let k of arr) { all.push(k); }
+  for (let k in obj) { all.#push(k); }
+
+
+testFunction (test.js:10:11)
+(anonymous) (expr.js:0:0)
+  for (let k of arr) { all.push(k); }
+  for (let #k in obj) { all.push(k); }
+
+
+testFunction (test.js:12:17)
+(anonymous) (expr.js:0:0)
+
+  var iterable = #{
+    [Symbol.iterator]() {
+
+testFunction (test.js:25:16)
+(anonymous) (expr.js:0:0)
+  };
+  for (var k of #iterable) { all.push(k); }
+  iterable.i = 0;
+
+[Symbol.iterator] (test.js:14:6)
+testFunction (test.js:25:16)
+(anonymous) (expr.js:0:0)
+    [Symbol.iterator]() {
+      #return {
+        i: 0,
+
+[Symbol.iterator] (test.js:22:8)
+testFunction (test.js:25:16)
+(anonymous) (expr.js:0:0)
+        }
+      };#
+    }
+
+testFunction (test.js:25:11)
+(anonymous) (expr.js:0:0)
+  };
+  for (var #k of iterable) { all.push(k); }
+  iterable.i = 0;
+
+next (test.js:17:19)
+testFunction (test.js:25:11)
+(anonymous) (expr.js:0:0)
+        next() {
+          if (this.#i < 1) {
+            return { value: this.i++, done: false };
+
+next (test.js:18:12)
+testFunction (test.js:25:11)
+(anonymous) (expr.js:0:0)
+          if (this.i < 1) {
+            #return { value: this.i++, done: false };
+          }
+
+next (test.js:18:52)
+testFunction (test.js:25:11)
+(anonymous) (expr.js:0:0)
+          if (this.i < 1) {
+            return { value: this.i++, done: false };#
+          }
+
+testFunction (test.js:25:32)
+(anonymous) (expr.js:0:0)
+  };
+  for (var k of iterable) { all.#push(k); }
+  iterable.i = 0;
+
+testFunction (test.js:25:11)
+(anonymous) (expr.js:0:0)
+  };
+  for (var #k of iterable) { all.push(k); }
+  iterable.i = 0;
+
+next (test.js:17:19)
+testFunction (test.js:25:11)
+(anonymous) (expr.js:0:0)
+        next() {
+          if (this.#i < 1) {
+            return { value: this.i++, done: false };
+
+next (test.js:20:10)
+testFunction (test.js:25:11)
+(anonymous) (expr.js:0:0)
+          }
+          #return { value: undefined, done: true };
+        }
+
+next (test.js:20:50)
+testFunction (test.js:25:11)
+(anonymous) (expr.js:0:0)
+          }
+          return { value: undefined, done: true };#
+        }
+
+testFunction (test.js:26:2)
+(anonymous) (expr.js:0:0)
+  for (var k of iterable) { all.push(k); }
+  #iterable.i = 0;
+  for (let k of iterable) { all.push(k); }
+
+testFunction (test.js:27:16)
+(anonymous) (expr.js:0:0)
+  iterable.i = 0;
+  for (let k of #iterable) { all.push(k); }
+}
+
+[Symbol.iterator] (test.js:14:6)
+testFunction (test.js:27:16)
+(anonymous) (expr.js:0:0)
+    [Symbol.iterator]() {
+      #return {
+        i: 0,
+
+[Symbol.iterator] (test.js:22:8)
+testFunction (test.js:27:16)
+(anonymous) (expr.js:0:0)
+        }
+      };#
+    }
+
+testFunction (test.js:27:11)
+(anonymous) (expr.js:0:0)
+  iterable.i = 0;
+  for (let #k of iterable) { all.push(k); }
+}
+
+next (test.js:17:19)
+testFunction (test.js:27:11)
+(anonymous) (expr.js:0:0)
+        next() {
+          if (this.#i < 1) {
+            return { value: this.i++, done: false };
+
+next (test.js:18:12)
+testFunction (test.js:27:11)
+(anonymous) (expr.js:0:0)
+          if (this.i < 1) {
+            #return { value: this.i++, done: false };
+          }
+
+next (test.js:18:52)
+testFunction (test.js:27:11)
+(anonymous) (expr.js:0:0)
+          if (this.i < 1) {
+            return { value: this.i++, done: false };#
+          }
+
+testFunction (test.js:27:32)
+(anonymous) (expr.js:0:0)
+  iterable.i = 0;
+  for (let k of iterable) { all.#push(k); }
+}
+
+testFunction (test.js:27:11)
+(anonymous) (expr.js:0:0)
+  iterable.i = 0;
+  for (let #k of iterable) { all.push(k); }
+}
+
+next (test.js:17:19)
+testFunction (test.js:27:11)
+(anonymous) (expr.js:0:0)
+        next() {
+          if (this.#i < 1) {
+            return { value: this.i++, done: false };
+
+next (test.js:20:10)
+testFunction (test.js:27:11)
+(anonymous) (expr.js:0:0)
+          }
+          #return { value: undefined, done: true };
+        }
+
+next (test.js:20:50)
+testFunction (test.js:27:11)
+(anonymous) (expr.js:0:0)
+          }
+          return { value: undefined, done: true };#
+        }
+
+testFunction (test.js:28:0)
+(anonymous) (expr.js:0:0)
+  for (let k of iterable) { all.push(k); }
+#}
+
+(anonymous) (expr.js:0:34)
+
+
+
+Running test: testStepIntoAfterBreakpoint
+testFunction (test.js:25:11)
+(anonymous) (expr.js:0:0)
+  };
+  for (var #k of iterable) { all.push(k); }
+  iterable.i = 0;
+
+next (test.js:17:19)
+testFunction (test.js:25:11)
+(anonymous) (expr.js:0:0)
+        next() {
+          if (this.#i < 1) {
+            return { value: this.i++, done: false };
+
diff --git a/src/v8/test/inspector/debugger/for-of-loops.js b/src/v8/test/inspector/debugger/for-of-loops.js
new file mode 100644
index 0000000..0fa0a26
--- /dev/null
+++ b/src/v8/test/inspector/debugger/for-of-loops.js
@@ -0,0 +1,82 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+  InspectorTest.start('Tests breakable locations in for-of loops.');
+
+let source = `
+function testFunction() {
+  var obj = {a : 1};
+  var arr = [1];
+  var all = [];
+  for (var k in arr) { all.push(k); }
+  for (var k of arr) { all.push(k); }
+  for (var k in obj) { all.push(k); }
+  for (let k in arr) { all.push(k); }
+  for (let k of arr) { all.push(k); }
+  for (let k in obj) { all.push(k); }
+
+  var iterable = {
+    [Symbol.iterator]() {
+      return {
+        i: 0,
+        next() {
+          if (this.i < 1) {
+            return { value: this.i++, done: false };
+          }
+          return { value: undefined, done: true };
+        }
+      };
+    }
+  };
+  for (var k of iterable) { all.push(k); }
+  iterable.i = 0;
+  for (let k of iterable) { all.push(k); }
+}
+//# sourceURL=test.js`;
+
+contextGroup.addScript(source);
+session.setupScriptMap();
+
+InspectorTest.runAsyncTestSuite([
+  async function testBreakLocations() {
+    Protocol.Debugger.enable();
+    let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
+    let {result:{locations}} = await Protocol.Debugger.getPossibleBreakpoints({
+      start: {lineNumber: 0, columnNumber : 0, scriptId}});
+    session.logBreakLocations(locations);
+  },
+
+  async function testStepInto() {
+    Protocol.Debugger.pause();
+    let fin = Protocol.Runtime.evaluate({
+      expression: 'testFunction()//# sourceURL=expr.js'}).then(() => false);
+    let result;
+    while (result = await Promise.race([fin, Protocol.Debugger.oncePaused()])) {
+      let {params:{callFrames}} = result;
+      session.logCallFrames(callFrames);
+      session.logSourceLocation(callFrames[0].location);
+      Protocol.Debugger.stepInto();
+    }
+    Protocol.Runtime.evaluate({expression: '42'});
+    await Protocol.Debugger.oncePaused();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testStepIntoAfterBreakpoint() {
+    Protocol.Debugger.setBreakpointByUrl({lineNumber: 25, url: 'test.js'});
+    Protocol.Runtime.evaluate({
+      expression: 'testFunction()//# sourceURL=expr.js'});
+    await awaitPausedAndDump();
+    Protocol.Debugger.stepInto();
+    await awaitPausedAndDump();
+    await Protocol.Debugger.resume();
+
+    async function awaitPausedAndDump() {
+      let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+      session.logCallFrames(callFrames);
+      session.logSourceLocation(callFrames[0].location);
+    }
+  }
+]);
diff --git a/src/v8/test/inspector/debugger/framework-break-expected.txt b/src/v8/test/inspector/debugger/framework-break-expected.txt
new file mode 100644
index 0000000..e858e83
--- /dev/null
+++ b/src/v8/test/inspector/debugger/framework-break-expected.txt
@@ -0,0 +1,70 @@
+Checks that breaks in framework code correctly processed.
+
+Running test: testConsoleAssert
+> all frames in framework:
+> mixed, top frame in framework:
+frameworkAssert (framework.js:10:10)
+(anonymous) (user.js:0:0)
+
+
+Running test: testCaughtException
+> all frames in framework:
+> mixed, top frame in framework:
+
+Running test: testUncaughtException
+> all frames in framework:
+> mixed, top frame in framework:
+throwUncaughtError (framework.js:21:2)
+(anonymous) (user.js:0:0)
+
+
+Running test: testUncaughtExceptionWithInlinedFrame
+> mixed top frame in framework:
+throwUserException (user.js:66:2)
+inlinedWrapper (framework.js:56:4)
+throwInlinedUncaughtError (framework.js:59:2)
+(anonymous) (framework.js:0:0)
+
+
+Running test: testBreakpoint
+> all frames in framework:
+breakpoint (framework.js:25:2)
+(anonymous) (framework.js:0:0)
+
+> mixed, top frame in framework:
+breakpoint (framework.js:25:2)
+(anonymous) (user.js:0:0)
+
+
+Running test: testDebuggerStatement
+> all frames in framework:
+> mixed, top frame in framework:
+
+Running test: testSyncDOMBreakpoint
+> all frames in framework:
+> mixed, top frame in framework:
+syncDOMBreakpoint (framework.js:33:12)
+(anonymous) (user.js:0:0)
+
+
+Running test: testSyncDOMBreakpointWithInlinedUserFrame
+> mixed, top frame in framework:
+syncDOMBreakpoint (framework.js:33:12)
+userFunction (user.js:70:2)
+inlinedWrapper (framework.js:64:4)
+syncDOMBreakpointWithInlinedUserFrame (framework.js:67:2)
+(anonymous) (framework.js:0:0)
+
+
+Running test: testAsyncDOMBreakpoint
+> all frames in framework:
+(anonymous) (user.js:0:0)
+
+
+Running test: testCaughtSyntaxError
+> all frames in framework:
+> mixed, top frame in framework:
+
+Running test: testCaughtJSONParseError
+> all frames in framework:
+> mixed, top frame in framework:
diff --git a/src/v8/test/inspector/debugger/framework-break.js b/src/v8/test/inspector/debugger/framework-break.js
new file mode 100644
index 0000000..9b9fee6
--- /dev/null
+++ b/src/v8/test/inspector/debugger/framework-break.js
@@ -0,0 +1,234 @@
+// Copyright 2017 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.
+// Flags: --allow-natives-syntax
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that breaks in framework code correctly processed.');
+
+contextGroup.addScript(`
+function frameworkAssert() {
+  console.assert(false);
+}
+
+function throwCaughtError() {
+  try {
+    throw new Error();
+  } catch (e) {
+  }
+}
+
+function throwUncaughtError() {
+  throw new Error();
+}
+
+function breakpoint() {
+  return 239;
+}
+
+function debuggerStatement() {
+  debugger;
+}
+
+function syncDOMBreakpoint() {
+  inspector.breakProgram('', '');
+}
+
+function asyncDOMBreakpoint() {
+  return 42;
+}
+
+function throwCaughtSyntaxError() {
+  try {
+    eval('}');
+  } catch (e) {
+  }
+}
+
+function throwFromJSONParse() {
+  try {
+    JSON.parse('ping');
+  } catch (e) {
+  }
+}
+
+function throwInlinedUncaughtError() {
+  function inlinedWrapper() {
+    throwUserException();
+  }
+  %OptimizeFunctionOnNextCall(inlinedWrapper);
+  inlinedWrapper();
+}
+
+function syncDOMBreakpointWithInlinedUserFrame() {
+  function inlinedWrapper() {
+    userFunction();
+  }
+  %OptimizeFunctionOnNextCall(inlinedWrapper);
+  inlinedWrapper();
+}
+
+//# sourceURL=framework.js`, 8, 26);
+
+contextGroup.addScript(`
+function throwUserException() {
+  throw new Error();
+}
+
+function userFunction() {
+  syncDOMBreakpoint();
+}
+
+//# sourceURL=user.js`, 64, 26)
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  session.logCallFrames(message.params.callFrames);
+  InspectorTest.log('');
+  Protocol.Debugger.resume();
+});
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js']});
+
+InspectorTest.runTestSuite([
+  function testConsoleAssert(next) {
+    Protocol.Debugger.setPauseOnExceptions({state: 'all'})
+        .then(() => InspectorTest.log('> all frames in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'frameworkAssert()//# sourceURL=framework.js'}))
+        .then(() => InspectorTest.log('> mixed, top frame in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'frameworkAssert()//# sourceURL=user.js'}))
+        .then(() => Protocol.Debugger.setPauseOnExceptions({state: 'none'}))
+        .then(next);
+  },
+
+  function testCaughtException(next) {
+    Protocol.Debugger.setPauseOnExceptions({state: 'all'})
+        .then(() => InspectorTest.log('> all frames in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'throwCaughtError()//# sourceURL=framework.js'}))
+        .then(() => InspectorTest.log('> mixed, top frame in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'throwCaughtError()//# sourceURL=user.js'}))
+        .then(() => Protocol.Debugger.setPauseOnExceptions({state: 'none'}))
+        .then(next);
+  },
+
+  function testUncaughtException(next) {
+    Protocol.Debugger.setPauseOnExceptions({state: 'all'})
+        .then(() => InspectorTest.log('> all frames in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'setTimeout(\'throwUncaughtError()//# sourceURL=framework.js\', 0)//# sourceURL=framework.js'}))
+        .then(() => Protocol.Runtime.evaluate({ expression: "new Promise(resolve => setTimeout(resolve, 0))", awaitPromise: true}))
+        .then(() => InspectorTest.log('> mixed, top frame in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'setTimeout(\'throwUncaughtError()//# sourceURL=user.js\', 0)'}))
+        .then(() => Protocol.Runtime.evaluate({ expression: "new Promise(resolve => setTimeout(resolve, 0))", awaitPromise: true}))
+        .then(() => Protocol.Debugger.setPauseOnExceptions({state: 'none'}))
+        .then(next);
+  },
+
+  function testUncaughtExceptionWithInlinedFrame(next) {
+    Protocol.Debugger.setPauseOnExceptions({state: 'all'})
+        .then(() => InspectorTest.log('> mixed top frame in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'setTimeout(\'throwInlinedUncaughtError()//# sourceURL=framework.js\', 0)//# sourceURL=framework.js'}))
+        .then(() => Protocol.Runtime.evaluate({ expression: "new Promise(resolve => setTimeout(resolve, 0))", awaitPromise: true}))
+        .then(next);
+  },
+
+  function testBreakpoint(next) {
+    Protocol.Debugger.setBreakpointByUrl({lineNumber: 25, url: 'framework.js'})
+        .then(() => InspectorTest.log('> all frames in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'breakpoint()//# sourceURL=framework.js'}))
+        .then(() => InspectorTest.log('> mixed, top frame in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'breakpoint()//# sourceURL=user.js'}))
+        .then(next);
+  },
+
+  function testDebuggerStatement(next) {
+    InspectorTest.log('> all frames in framework:');
+    Protocol.Runtime
+        .evaluate({expression: 'debuggerStatement()//# sourceURL=framework.js'})
+        .then(() => InspectorTest.log('> mixed, top frame in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'debuggerStatement()//# sourceURL=user.js'}))
+        .then(next);
+  },
+
+  function testSyncDOMBreakpoint(next) {
+    InspectorTest.log('> all frames in framework:');
+    Protocol.Runtime
+        .evaluate({expression: 'syncDOMBreakpoint()//# sourceURL=framework.js'})
+        .then(() => InspectorTest.log('> mixed, top frame in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'syncDOMBreakpoint()//# sourceURL=user.js'}))
+        .then(next);
+  },
+
+  function testSyncDOMBreakpointWithInlinedUserFrame(next) {
+    InspectorTest.log('> mixed, top frame in framework:');
+    Protocol.Runtime
+        .evaluate({expression: 'syncDOMBreakpointWithInlinedUserFrame()//# sourceURL=framework.js'})
+        .then(next);
+  },
+
+  function testAsyncDOMBreakpoint(next) {
+    contextGroup.schedulePauseOnNextStatement('', '');
+    InspectorTest.log('> all frames in framework:');
+    Protocol.Runtime
+        .evaluate(
+            {expression: 'asyncDOMBreakpoint()//# sourceURL=framework.js'})
+        .then(() => contextGroup.cancelPauseOnNextStatement())
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: '42//# sourceURL=user.js'}))
+        .then(() => contextGroup.schedulePauseOnNextStatement('', ''))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'asyncDOMBreakpoint()//# sourceURL=user.js'}))
+        .then(next);
+  },
+
+  function testCaughtSyntaxError(next) {
+    Protocol.Debugger.setPauseOnExceptions({state: 'all'})
+        .then(() => InspectorTest.log('> all frames in framework:'))
+        .then(() => Protocol.Runtime.evaluate({
+          expression: 'throwCaughtSyntaxError()//# sourceURL=framework.js'
+        }))
+        .then(() => InspectorTest.log('> mixed, top frame in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'throwCaughtSyntaxError()//# sourceURL=user.js'}))
+        .then(() => Protocol.Debugger.setPauseOnExceptions({state: 'none'}))
+        .then(next);
+  },
+
+  function testCaughtJSONParseError(next) {
+    Protocol.Debugger.setPauseOnExceptions({state: 'all'})
+        .then(() => InspectorTest.log('> all frames in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'throwFromJSONParse()//# sourceURL=framework.js'}))
+        .then(() => InspectorTest.log('> mixed, top frame in framework:'))
+        .then(
+            () => Protocol.Runtime.evaluate(
+                {expression: 'throwFromJSONParse()//# sourceURL=user.js'}))
+        .then(() => Protocol.Debugger.setPauseOnExceptions({state: 'none'}))
+        .then(next);
+  }
+]);
diff --git a/src/v8/test/inspector/debugger/framework-nested-scheduled-break-expected.txt b/src/v8/test/inspector/debugger/framework-nested-scheduled-break-expected.txt
new file mode 100644
index 0000000..f9901f0
--- /dev/null
+++ b/src/v8/test/inspector/debugger/framework-nested-scheduled-break-expected.txt
@@ -0,0 +1,41 @@
+Checks nested scheduled break in framework code.
+break reason: framework-break
+break aux data: {
+  "data": "data for framework-break"
+}
+doFrameworkBreak (framework.js:20:12)
+doFrameworkWork (framework.js:15:12)
+frameworkCall (framework.js:9:12)
+testFunction (user.js:27:12)
+(anonymous) (expr.js:0:0)
+
+break reason: ambiguous
+break aux data: {
+  "reasons": [
+    {
+      "reason": "top-scheduled-break"
+    },
+    {
+      "reason": "top-framework-scheduled-break",
+      "auxData": {
+        "data": "data for top-framework-scheduled-break"
+      }
+    }
+  ]
+}
+callback (user.js:31:17)
+doFrameworkWork (framework.js:16:2)
+frameworkCall (framework.js:9:12)
+testFunction (user.js:27:12)
+(anonymous) (expr.js:0:0)
+
+break reason: user-break
+break aux data: {
+  "data": "data for user-break"
+}
+callback (user.js:32:12)
+doFrameworkWork (framework.js:16:2)
+frameworkCall (framework.js:9:12)
+testFunction (user.js:27:12)
+(anonymous) (expr.js:0:0)
+
diff --git a/src/v8/test/inspector/debugger/framework-nested-scheduled-break.js b/src/v8/test/inspector/debugger/framework-nested-scheduled-break.js
new file mode 100644
index 0000000..3e62991
--- /dev/null
+++ b/src/v8/test/inspector/debugger/framework-nested-scheduled-break.js
@@ -0,0 +1,49 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks nested scheduled break in framework code.');
+
+contextGroup.addScript(`
+function frameworkCall(callback) {
+  inspector.callWithScheduledBreak(doFrameworkWork.bind(null, callback),
+    'top-framework-scheduled-break',
+    JSON.stringify({ data: 'data for top-framework-scheduled-break' }));
+}
+
+function doFrameworkWork(callback) {
+  inspector.callWithScheduledBreak(doFrameworkBreak, 'should-not-be-a-reason', '');
+  callback();
+}
+
+function doFrameworkBreak() {
+  inspector.breakProgram('framework-break', JSON.stringify({ data: 'data for framework-break' }));
+}
+
+//# sourceURL=framework.js`, 7, 26);
+
+contextGroup.addScript(`
+function testFunction() {
+  inspector.callWithScheduledBreak(frameworkCall.bind(null, callback),
+    'top-scheduled-break', '');
+}
+
+function callback() {
+  inspector.breakProgram('user-break', JSON.stringify({ data: 'data for user-break' }));
+  return 42;
+}
+
+//# sourceURL=user.js`, 25, 26);
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  InspectorTest.log('break reason: ' + message.params.reason);
+  InspectorTest.log('break aux data: ' + JSON.stringify(message.params.data || {}, null, '  '));
+  session.logCallFrames(message.params.callFrames);
+  InspectorTest.log('');
+  Protocol.Debugger.resume();
+});
+Protocol.Debugger.enable()
+  .then(() => Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js']}))
+  .then(() => Protocol.Runtime.evaluate({ expression: 'testFunction()//# sourceURL=expr.js'}))
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/framework-precise-ranges-expected.txt b/src/v8/test/inspector/debugger/framework-precise-ranges-expected.txt
new file mode 100644
index 0000000..0e0791d
--- /dev/null
+++ b/src/v8/test/inspector/debugger/framework-precise-ranges-expected.txt
@@ -0,0 +1,140 @@
+Checks framework debugging with blackboxed ranges.
+
+Running test: testEntireScript
+{
+    id : <messageId>
+    result : {
+    }
+}
+
+Running test: testFooNotBlackboxed
+{
+    id : <messageId>
+    result : {
+    }
+}
+foo (test.js:8:12)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+foo (test.js:9:2)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+foo (test.js:9:15)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testFooBlackboxed
+{
+    id : <messageId>
+    result : {
+    }
+}
+testFunction (test.js:14:21)
+(anonymous) (expr.js:0:0)
+
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+boo (test.js:12:2)
+foo (test.js:9:9)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+boo (test.js:12:12)
+foo (test.js:9:9)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+testFunction (test.js:16:0)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testBooPartiallyBlackboxed1
+{
+    id : <messageId>
+    result : {
+    }
+}
+foo (test.js:8:12)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+foo (test.js:9:2)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+boo (test.js:12:2)
+foo (test.js:9:9)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+boo (test.js:12:12)
+foo (test.js:9:9)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+foo (test.js:9:15)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testBooPartiallyBlackboxed2
+{
+    id : <messageId>
+    result : {
+    }
+}
+foo (test.js:8:12)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+foo (test.js:9:2)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+boo (test.js:12:2)
+foo (test.js:9:9)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+boo (test.js:12:12)
+foo (test.js:9:9)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+foo (test.js:9:15)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+
+Running test: testBooPartiallyBlackboxed3
+{
+    id : <messageId>
+    result : {
+    }
+}
+foo (test.js:8:12)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+foo (test.js:9:2)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+boo (test.js:12:2)
+foo (test.js:9:9)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+boo (test.js:12:12)
+foo (test.js:9:9)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
+foo (test.js:9:15)
+testFunction (test.js:15:2)
+(anonymous) (expr.js:0:0)
+
diff --git a/src/v8/test/inspector/debugger/framework-precise-ranges.js b/src/v8/test/inspector/debugger/framework-precise-ranges.js
new file mode 100644
index 0000000..4f76033
--- /dev/null
+++ b/src/v8/test/inspector/debugger/framework-precise-ranges.js
@@ -0,0 +1,78 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks framework debugging with blackboxed ranges.');
+
+contextGroup.addScript(
+    `
+function foo() {
+  return boo();
+}
+function boo() {
+  return 42;
+}
+function testFunction() {
+  foo();
+}
+//# sourceURL=test.js`,
+    7, 26);
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  session.logCallFrames(message.params.callFrames);
+  InspectorTest.log('');
+  Protocol.Debugger.stepInto();
+});
+var scriptId;
+Protocol.Debugger.onScriptParsed(message => {
+  if (message.params.url === 'test.js') {
+    scriptId = message.params.scriptId;
+  }
+});
+
+Protocol.Debugger.enable()
+    .then(() => Protocol.Debugger.setBlackboxPatterns({patterns: ['expr\.js']}))
+    .then(() => InspectorTest.runTestSuite(testSuite));
+
+var testSuite = [
+  function testEntireScript(next) {
+    testPositions([position(0, 0)]).then(next);
+  },
+  function testFooNotBlackboxed(next) {
+    testPositions([position(11, 0)]).then(next);
+  },
+  function testFooBlackboxed(next) {
+    testPositions([position(8, 0), position(10, 3)]).then(next);
+  },
+  function testBooPartiallyBlackboxed1(next) {
+    // first line is not blackboxed, second and third - blackboxed.
+    testPositions([position(12, 0)]).then(next);
+  },
+  function testBooPartiallyBlackboxed2(next) {
+    // first line is blackboxed, second - not, third - blackboxed.
+    testPositions([
+      position(11, 0), position(12, 0), position(13, 0)
+    ]).then(next);
+  },
+  function testBooPartiallyBlackboxed3(next) {
+    // first line is blackboxed, second and third - not.
+    testPositions([
+      position(11, 0), position(12, 0), position(14, 0)
+    ]).then(next);
+  }
+];
+
+function testPositions(positions) {
+  contextGroup.schedulePauseOnNextStatement('', '');
+  return Protocol.Debugger
+      .setBlackboxedRanges({scriptId: scriptId, positions: positions})
+      .then(InspectorTest.logMessage)
+      .then(
+          () => Protocol.Runtime.evaluate(
+              {expression: 'testFunction()//# sourceURL=expr.js'}));
+}
+
+function position(line, column) {
+  return {lineNumber: line, columnNumber: column};
+}
diff --git a/src/v8/test/inspector/debugger/framework-stepping-expected.txt b/src/v8/test/inspector/debugger/framework-stepping-expected.txt
new file mode 100644
index 0000000..fa2bb35
--- /dev/null
+++ b/src/v8/test/inspector/debugger/framework-stepping-expected.txt
@@ -0,0 +1,102 @@
+Checks stepping with blackboxed frames on stack
+
+Running test: testStepIntoFromUser
+(anonymous) (expr.js:0:0)
+
+Executing stepInto...
+Executing stepInto...
+userFoo (user.js:23:2)
+frameworkCall (framework.js:10:23)
+testStepFromUser (user.js:31:2)
+(anonymous) (expr.js:0:0)
+
+Executing stepInto...
+Executing stepInto...
+userBoo (user.js:27:2)
+frameworkCall (framework.js:10:23)
+testStepFromUser (user.js:31:2)
+(anonymous) (expr.js:0:0)
+
+Executing stepInto...
+Executing stepInto...
+testStepFromUser (user.js:32:0)
+(anonymous) (expr.js:0:0)
+
+Executing resume...
+
+Running test: testStepOverFromUser
+(anonymous) (expr.js:0:0)
+
+Executing stepInto...
+Executing stepInto...
+userFoo (user.js:23:2)
+frameworkCall (framework.js:10:23)
+testStepFromUser (user.js:31:2)
+(anonymous) (expr.js:0:0)
+
+Executing stepOver...
+Executing stepOver...
+userBoo (user.js:27:2)
+frameworkCall (framework.js:10:23)
+testStepFromUser (user.js:31:2)
+(anonymous) (expr.js:0:0)
+
+Executing stepOver...
+Executing stepOver...
+testStepFromUser (user.js:32:0)
+(anonymous) (expr.js:0:0)
+
+Executing resume...
+
+Running test: testStepOutFromUser
+(anonymous) (expr.js:0:0)
+
+Executing stepInto...
+Executing stepInto...
+userFoo (user.js:23:2)
+frameworkCall (framework.js:10:23)
+testStepFromUser (user.js:31:2)
+(anonymous) (expr.js:0:0)
+
+Executing stepOut...
+userBoo (user.js:27:2)
+frameworkCall (framework.js:10:23)
+testStepFromUser (user.js:31:2)
+(anonymous) (expr.js:0:0)
+
+Executing resume...
+
+Running test: testStepIntoFromFramework
+frameworkBreakAndCall (framework.js:14:12)
+testStepFromFramework (user.js:35:2)
+(anonymous) (expr.js:0:0)
+
+Executing stepInto...
+userFoo (user.js:23:2)
+frameworkBreakAndCall (framework.js:15:23)
+testStepFromFramework (user.js:35:2)
+(anonymous) (expr.js:0:0)
+
+Executing resume...
+
+Running test: testStepOverFromFramework
+frameworkBreakAndCall (framework.js:14:12)
+testStepFromFramework (user.js:35:2)
+(anonymous) (expr.js:0:0)
+
+Executing stepOver...
+testStepFromFramework (user.js:36:0)
+(anonymous) (expr.js:0:0)
+
+Executing resume...
+
+Running test: testStepOutFromFramework
+frameworkBreakAndCall (framework.js:14:12)
+testStepFromFramework (user.js:35:2)
+(anonymous) (expr.js:0:0)
+
+Executing stepOut...
+testStepFromFramework (user.js:36:0)
+(anonymous) (expr.js:0:0)
+
+Executing resume...
diff --git a/src/v8/test/inspector/debugger/framework-stepping.js b/src/v8/test/inspector/debugger/framework-stepping.js
new file mode 100644
index 0000000..f91c06b
--- /dev/null
+++ b/src/v8/test/inspector/debugger/framework-stepping.js
@@ -0,0 +1,113 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks stepping with blackboxed frames on stack');
+
+contextGroup.addScript(
+    `
+function frameworkCall(funcs) {
+  for (var f of funcs) f();
+}
+
+function frameworkBreakAndCall(funcs) {
+  inspector.breakProgram('', '');
+  for (var f of funcs) f();
+}
+//# sourceURL=framework.js`,
+    8, 4);
+
+contextGroup.addScript(
+    `
+function userFoo() {
+  return 1;
+}
+
+function userBoo() {
+  return 2;
+}
+
+function testStepFromUser() {
+  frameworkCall([userFoo, userBoo])
+}
+
+function testStepFromFramework() {
+  frameworkBreakAndCall([userFoo, userBoo]);
+}
+//# sourceURL=user.js`,
+    21, 4);
+
+session.setupScriptMap();
+
+Protocol.Debugger.enable()
+    .then(
+        () => Protocol.Debugger.setBlackboxPatterns(
+            {patterns: ['framework\.js']}))
+    .then(() => InspectorTest.runTestSuite(testSuite));
+
+var testSuite = [
+  function testStepIntoFromUser(next) {
+    contextGroup.schedulePauseOnNextStatement('', '');
+    test('testStepFromUser()', [
+      'print',                          // before testStepFromUser call
+      'stepInto', 'stepInto', 'print',  // userFoo
+      'stepInto', 'stepInto', 'print',  // userBoo
+      'stepInto', 'stepInto', 'print'   // testStepFromUser
+    ]).then(next);
+  },
+
+  function testStepOverFromUser(next) {
+    contextGroup.schedulePauseOnNextStatement('', '');
+    test('testStepFromUser()', [
+      'print',                          // before testStepFromUser call
+      'stepInto', 'stepInto', 'print',  // userFoo
+      'stepOver', 'stepOver', 'print',  // userBoo
+      'stepOver', 'stepOver', 'print'   // testStepFromUser
+    ]).then(next);
+  },
+
+  function testStepOutFromUser(next) {
+    contextGroup.schedulePauseOnNextStatement('', '');
+    test('testStepFromUser()', [
+      'print',                          // before testStepFromUser call
+      'stepInto', 'stepInto', 'print',  // userFoo
+      'stepOut', 'print'                // testStepFromUser
+    ]).then(next);
+  },
+
+  function testStepIntoFromFramework(next) {
+    test('testStepFromFramework()', [
+      'print',              // frameworkBreakAndCall
+      'stepInto', 'print',  // userFoo
+    ]).then(next);
+  },
+
+  function testStepOverFromFramework(next) {
+    test('testStepFromFramework()', [
+      'print',              // frameworkBreakAndCall
+      'stepOver', 'print',  // testStepFromFramework
+    ]).then(next);
+  },
+
+  function testStepOutFromFramework(next) {
+    test('testStepFromFramework()', [
+      'print',             // frameworkBreakAndCall
+      'stepOut', 'print',  // testStepFromFramework
+    ]).then(next);
+  }
+];
+
+function test(entryExpression, actions) {
+  Protocol.Debugger.onPaused(message => {
+    var action = actions.shift() || 'resume';
+    if (action === 'print') {
+      session.logCallFrames(message.params.callFrames);
+      InspectorTest.log('');
+      action = actions.shift() || 'resume';
+    }
+    if (action) InspectorTest.log(`Executing ${action}...`);
+    Protocol.Debugger[action]();
+  });
+  return Protocol.Runtime.evaluate(
+      {expression: entryExpression + '//# sourceURL=expr.js'});
+}
diff --git a/src/v8/test/inspector/debugger/get-possible-breakpoints-array-literal-expected.txt b/src/v8/test/inspector/debugger/get-possible-breakpoints-array-literal-expected.txt
new file mode 100644
index 0000000..c5d8c24
--- /dev/null
+++ b/src/v8/test/inspector/debugger/get-possible-breakpoints-array-literal-expected.txt
@@ -0,0 +1,30 @@
+Tests possible breakpoints in array literal
+{
+    id : <messageId>
+    result : {
+        locations : [
+            [0] : {
+                columnNumber : 0
+                lineNumber : 0
+                scriptId : <scriptId>
+            }
+            [1] : {
+                columnNumber : 6
+                lineNumber : 0
+                scriptId : <scriptId>
+            }
+            [2] : {
+                columnNumber : 7
+                lineNumber : 0
+                scriptId : <scriptId>
+                type : return
+            }
+            [3] : {
+                columnNumber : 8
+                lineNumber : 0
+                scriptId : <scriptId>
+                type : return
+            }
+        ]
+    }
+}
diff --git a/src/v8/test/inspector/debugger/get-possible-breakpoints-array-literal.js b/src/v8/test/inspector/debugger/get-possible-breakpoints-array-literal.js
new file mode 100644
index 0000000..a5aeeff
--- /dev/null
+++ b/src/v8/test/inspector/debugger/get-possible-breakpoints-array-literal.js
@@ -0,0 +1,14 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests possible breakpoints in array literal');
+
+Protocol.Debugger.enable();
+
+Protocol.Debugger.onceScriptParsed().then(message => message.params.scriptId)
+  .then((scriptId) => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber: 0, scriptId: scriptId }}))
+  .then(InspectorTest.logMessage)
+  .then(InspectorTest.completeTest);
+
+contextGroup.addScript("() => []");
diff --git a/src/v8/test/inspector/debugger/get-possible-breakpoints-expected.txt b/src/v8/test/inspector/debugger/get-possible-breakpoints-expected.txt
new file mode 100644
index 0000000..972a757
--- /dev/null
+++ b/src/v8/test/inspector/debugger/get-possible-breakpoints-expected.txt
@@ -0,0 +1,271 @@
+Test for Debugger.getPossibleBreakpoints
+
+Running test: getPossibleBreakpointsInRange
+Test start.scriptId != end.scriptId.
+{
+    error : {
+        code : -32000
+        message : Locations should contain the same scriptId
+    }
+    id : <messageId>
+}
+Test not existing scriptId.
+{
+    error : {
+        code : -32000
+        message : Script not found
+    }
+    id : <messageId>
+}
+Test end < start.
+function foo(){ return Promise.resolve(); }
+function boo(){ return Promise.resolve().then(() => 42); }
+
+
+Test empty range in first line.
+function foo(){ return Promise.resolve(); }
+function boo(){ return Promise.resolve().then(() => 42); }
+
+
+Test one character range in first line.
+function foo(){ #return Promise.resolve(); }
+function boo(){ return Promise.resolve().then(() => 42); }
+
+
+Test empty range in not first line.
+function foo(){ return Promise.resolve(); }
+function boo(){ return Promise.resolve().then(() => 42); }
+
+
+Test one character range in not first line.
+function foo(){ return Promise.resolve(); }
+function boo(){ #return Promise.resolve().then(() => 42); }
+
+
+Test end is undefined
+function foo(){ #return Promise.#resolve();# }
+function boo(){ #return Promise.#resolve().#then(() => #42#);# }
+#
+
+Test end.lineNumber > scripts.lineCount()
+function foo(){ #return Promise.#resolve();# }
+function boo(){ #return Promise.#resolve().#then(() => #42#);# }
+#
+
+Test one string
+function foo(){ #return Promise.#resolve();# }
+function boo(){ return Promise.resolve().then(() => 42); }
+
+
+Test end.columnNumber > end.line.length(), should be the same as previous.
+function foo(){ #return Promise.#resolve();# }
+function boo(){ return Promise.resolve().then(() => 42); }
+
+
+
+Running test: getPossibleBreakpointsInArrow
+function foo() { #return Promise.#resolve().#then(() => #239#).#then(() => #42#).#then(() => #() => #42#)# #}
+
+Running test: arrowFunctionFirstLine
+function foo1() { #Promise.#resolve().#then(() => #42#) #}
+function foo2() { Promise.resolve().then(() => 42) }
+paused in foo1
+function foo1() { ^Promise.resolve().then(() => 42) }
+function foo2() { Promise.resolve().then(() => 42) }
+paused in foo1
+function foo1() { Promise.^resolve().then(() => 42) }
+function foo2() { Promise.resolve().then(() => 42) }
+paused in foo1
+function foo1() { Promise.resolve().^then(() => 42) }
+function foo2() { Promise.resolve().then(() => 42) }
+paused in foo1
+function foo1() { Promise.resolve().then(() => 42) ^}
+function foo2() { Promise.resolve().then(() => 42) }
+paused in Promise.resolve.then
+function foo1() { Promise.resolve().then(() => ^42) }
+function foo2() { Promise.resolve().then(() => 42) }
+paused in Promise.resolve.then
+function foo1() { Promise.resolve().then(() => 42^) }
+function foo2() { Promise.resolve().then(() => 42) }
+
+Running test: arrowFunctionOnPause
+#debugger; function foo3() { #Promise.#resolve().#then(() => #42#) #}
+function foo4() { #Promise.#resolve().#then(() => #42#) #};
+#foo3();
+#foo4()#;
+paused in 
+debugger; function foo3() { Promise.resolve().then(() => 42) }
+function foo4() { Promise.resolve().then(() => 42) };
+^foo3();
+foo4();
+paused in foo3
+debugger; function foo3() { ^Promise.resolve().then(() => 42) }
+function foo4() { Promise.resolve().then(() => 42) };
+foo3();
+foo4();
+paused in foo3
+debugger; function foo3() { Promise.^resolve().then(() => 42) }
+function foo4() { Promise.resolve().then(() => 42) };
+foo3();
+foo4();
+paused in foo3
+debugger; function foo3() { Promise.resolve().^then(() => 42) }
+function foo4() { Promise.resolve().then(() => 42) };
+foo3();
+foo4();
+paused in foo3
+debugger; function foo3() { Promise.resolve().then(() => 42) ^}
+function foo4() { Promise.resolve().then(() => 42) };
+foo3();
+foo4();
+paused in 
+debugger; function foo3() { Promise.resolve().then(() => 42) }
+function foo4() { Promise.resolve().then(() => 42) };
+foo3();
+^foo4();
+paused in foo4
+debugger; function foo3() { Promise.resolve().then(() => 42) }
+function foo4() { ^Promise.resolve().then(() => 42) };
+foo3();
+foo4();
+paused in foo4
+debugger; function foo3() { Promise.resolve().then(() => 42) }
+function foo4() { Promise.^resolve().then(() => 42) };
+foo3();
+foo4();
+paused in foo4
+debugger; function foo3() { Promise.resolve().then(() => 42) }
+function foo4() { Promise.resolve().^then(() => 42) };
+foo3();
+foo4();
+paused in foo4
+debugger; function foo3() { Promise.resolve().then(() => 42) }
+function foo4() { Promise.resolve().then(() => 42) ^};
+foo3();
+foo4();
+paused in 
+debugger; function foo3() { Promise.resolve().then(() => 42) }
+function foo4() { Promise.resolve().then(() => 42) };
+foo3();
+foo4()^;
+paused in Promise.resolve.then
+debugger; function foo3() { Promise.resolve().then(() => ^42) }
+function foo4() { Promise.resolve().then(() => 42) };
+foo3();
+foo4();
+paused in Promise.resolve.then
+debugger; function foo3() { Promise.resolve().then(() => 42^) }
+function foo4() { Promise.resolve().then(() => 42) };
+foo3();
+foo4();
+paused in Promise.resolve.then
+debugger; function foo3() { Promise.resolve().then(() => 42) }
+function foo4() { Promise.resolve().then(() => ^42) };
+foo3();
+foo4();
+paused in Promise.resolve.then
+debugger; function foo3() { Promise.resolve().then(() => 42) }
+function foo4() { Promise.resolve().then(() => 42^) };
+foo3();
+foo4();
+
+Running test: getPossibleBreakpointsInRangeWithOffset
+Test empty range in first line.
+function foo(){ return Promise.resolve(); }
+function boo(){ return Promise.resolve().then(() => 42); }
+
+
+Test one character range in first line.
+function foo(){ #return Promise.resolve(); }
+function boo(){ return Promise.resolve().then(() => 42); }
+
+
+Test empty range in not first line.
+function foo(){ return Promise.resolve(); }
+function boo(){ return Promise.resolve().then(() => 42); }
+
+
+Test one character range in not first line.
+function foo(){ return Promise.resolve(); }
+function boo(){ #return Promise.resolve().then(() => 42); }
+
+
+Test end is undefined
+function foo(){ #return Promise.#resolve();# }
+function boo(){ #return Promise.#resolve().#then(() => #42#);# }
+#
+
+Test end.lineNumber > scripts.lineCount()
+function foo(){ #return Promise.#resolve();# }
+function boo(){ #return Promise.#resolve().#then(() => #42#);# }
+#
+
+Test one string
+function foo(){ #return Promise.#resolve();# }
+function boo(){ return Promise.resolve().then(() => 42); }
+
+
+Test end.columnNumber > end.line.length(), should be the same as previous.
+function foo(){ #return Promise.#resolve();# }
+function boo(){ return Promise.resolve().then(() => 42); }
+
+
+
+Running test: withOffset
+function foo5() { #Promise.#resolve().#then(() => #42#) #}
+function foo6() { #Promise.#resolve().#then(() => #42#) #}
+paused in foo5
+function foo5() { ^Promise.resolve().then(() => 42) }
+function foo6() { Promise.resolve().then(() => 42) }
+paused in foo5
+function foo5() { Promise.^resolve().then(() => 42) }
+function foo6() { Promise.resolve().then(() => 42) }
+paused in foo5
+function foo5() { Promise.resolve().^then(() => 42) }
+function foo6() { Promise.resolve().then(() => 42) }
+paused in foo5
+function foo5() { Promise.resolve().then(() => 42) ^}
+function foo6() { Promise.resolve().then(() => 42) }
+paused in foo6
+function foo5() { Promise.resolve().then(() => 42) }
+function foo6() { ^Promise.resolve().then(() => 42) }
+paused in foo6
+function foo5() { Promise.resolve().then(() => 42) }
+function foo6() { Promise.^resolve().then(() => 42) }
+paused in foo6
+function foo5() { Promise.resolve().then(() => 42) }
+function foo6() { Promise.resolve().^then(() => 42) }
+paused in foo6
+function foo5() { Promise.resolve().then(() => 42) }
+function foo6() { Promise.resolve().then(() => 42) ^}
+paused in Promise.resolve.then
+function foo5() { Promise.resolve().then(() => ^42) }
+function foo6() { Promise.resolve().then(() => 42) }
+paused in Promise.resolve.then
+function foo5() { Promise.resolve().then(() => 42^) }
+function foo6() { Promise.resolve().then(() => 42) }
+paused in Promise.resolve.then
+function foo5() { Promise.resolve().then(() => 42) }
+function foo6() { Promise.resolve().then(() => ^42) }
+paused in Promise.resolve.then
+function foo5() { Promise.resolve().then(() => 42) }
+function foo6() { Promise.resolve().then(() => 42^) }
+
+Running test: arrowFunctionReturn
+#() => #239#
+
+function foo() { function boo() { #return 239# }  #}#
+
+#() => { #239 #}#
+
+function foo() { #239 #}#
+
+#() => #23#9#
+#() => { #return 239# #}
+
+Running test: argumentsAsCalls
+function foo(){#}
+function boo(){#}
+function main(f1,f2){#}
+#main(#foo(), #boo());#
+
diff --git a/src/v8/test/inspector/debugger/get-possible-breakpoints-lazy-error-expected.txt b/src/v8/test/inspector/debugger/get-possible-breakpoints-lazy-error-expected.txt
new file mode 100644
index 0000000..9c65ba2
--- /dev/null
+++ b/src/v8/test/inspector/debugger/get-possible-breakpoints-lazy-error-expected.txt
@@ -0,0 +1,26 @@
+getPossibleBreakpoints should not crash during lazy compilation (crbug.com/715334)
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 21
+        endLine : 2
+        executionContextId : <executionContextId>
+        hasSourceURL : true
+        hash : FA2A959297747012766FE9C5006E7F522D88FA72
+        isLiveEdit : false
+        isModule : false
+        length : 52
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : test.js
+    }
+}
+{
+    id : <messageId>
+    result : {
+        locations : [
+        ]
+    }
+}
diff --git a/src/v8/test/inspector/debugger/get-possible-breakpoints-lazy-error.js b/src/v8/test/inspector/debugger/get-possible-breakpoints-lazy-error.js
new file mode 100644
index 0000000..d1326e9
--- /dev/null
+++ b/src/v8/test/inspector/debugger/get-possible-breakpoints-lazy-error.js
@@ -0,0 +1,28 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('getPossibleBreakpoints should not crash during lazy compilation (crbug.com/715334)');
+
+contextGroup.addScript(`
+function test() { continue; }
+//# sourceURL=test.js`);
+
+(async function test() {
+  Protocol.Debugger.enable();
+  let script = await Protocol.Debugger.onceScriptParsed();
+  InspectorTest.logMessage(script);
+  let scriptId = script.params.scriptId;
+  Protocol.Debugger.onScriptFailedToParse(msg => {
+    InspectorTest.logMessage(msg);
+    if (msg.params.scriptId !== script.params.scriptId) {
+      InspectorTest.log('Failed script to parse event has different scriptId');
+    } else {
+      InspectorTest.log('One script is reported twice');
+    }
+  });
+  let response = await Protocol.Debugger.getPossibleBreakpoints({
+    start: {scriptId, lineNumber: 0, columnNumber: 0}});
+  InspectorTest.logMessage(response);
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/debugger/get-possible-breakpoints-master-expected.txt b/src/v8/test/inspector/debugger/get-possible-breakpoints-master-expected.txt
new file mode 100644
index 0000000..7ea0920
--- /dev/null
+++ b/src/v8/test/inspector/debugger/get-possible-breakpoints-master-expected.txt
@@ -0,0 +1,271 @@
+Checks Debugger.getPossibleBreakpoints
+// Copyright 2017 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.
+
+function testEval() {
+  |C|eval('// comment only');
+  |C|eval('// comment only\n');
+|R|}
+
+// function without return
+function procedure() {
+  var a = |_|1;
+  var b = |_|2;
+|R|}
+
+function testProcedure() {
+  |C|procedure();
+|R|}
+
+function returnTrue() {
+  |_|return true;|R|
+}
+
+function testIf() {
+  var a;
+  if (true) |_|a = true;
+  |_|if (!a) {
+    |_|a = true;
+  } else {
+    |_|a = false;
+  }
+  |_|if (|C|returnTrue()) {
+    |_|a = false;
+  } else {
+    |_|a = true;
+  }
+|R|}
+
+function emptyFunction() {|R|}
+
+function testEmptyFunction() {
+  |C|emptyFunction();
+|R|}
+
+function twoArguments(a1, a2) {
+|R|}
+
+function testCallArguments() {
+  |C|twoArguments(|C|emptyFunction(), |C|emptyFunction());
+|R|}
+
+function testNested() {
+  function nested1() {
+    function nested2() {
+      function nested3() {
+      |R|}
+      |C|nested3();
+      |_|return;|R|
+    }
+    return |C|nested2();|R|
+  }
+  |C|nested1();
+|R|}
+
+function return42() {
+  |_|return 42;|R|
+}
+
+function returnCall() {
+  |_|return |C|return42();|R|
+}
+
+function testCallAtReturn() {
+  |_|return |C|returnCall();|R|
+}
+
+function returnObject() {
+  |_|return ({ foo: () => |_|42|R| });|R|
+}
+
+function testWith() {
+  |_|with (|C|returnObject()) {
+    |C|foo();
+  }
+  |_|with({}) {
+    |_|return;|R|
+  }
+}
+
+function testForLoop() {
+  for (var i = |_|0; i |_|< 1; ++|_|i) {}
+  for (var i = |_|0; i |_|< 1; ++|_|i) i;
+  for (var i = |_|0; i |_|< 0; ++|_|i) {}
+|R|}
+
+function testForOfLoop() {
+  for (var |_|k of |_|[]) {}
+  for (var |_|k of |_|[1]) |_|k;
+  var a = |_|[];
+  for (var |_|k of |_|a) {}
+|R|}
+
+function testForInLoop() {
+  var o = |_|{};
+  for (var |_|k in |_|o) {}
+  for (var |_|k in |_|o) |_|k;
+  for (var |_|k in |_|{ a:1 }) {}
+  for (var |_|k in |_|{ a:1 }) |_|k;
+|R|}
+
+function testSimpleExpressions() {
+  1 + 2 + 3;
+  var a = |_|1;
+  |_|++a;
+  |_|a--;
+|R|}
+
+Object.defineProperty(this, 'getterFoo', {
+  get: () => |_|return42|R|
+});
+
+function testGetter() {
+  |C|getterFoo();
+|R|}
+
+var obj = {
+  foo: () => (|_|{
+    boo: () => |_|return42|R|
+  })|R|
+};
+
+function testChainedCalls() {
+  |_|obj.|C|foo().|C|boo()|C|();
+|R|}
+
+function testChainedWithNative() {
+  |_|Array.|C|from([1]).|C|concat([2]).|C|map(v => v |_|* 2|R|);
+|R|}
+
+function testPromiseThen() {
+  |_|return Promise.|C|resolve().|C|then(v => v |_|* 2|R|).|C|then(v => v |_|* 2|R|);|R|
+}
+
+function testSwitch() {
+  for (var i = |_|0; i |_|< 3; ++|_|i) {
+    |_|switch(i) {
+      case 0: |_|continue;
+      case 1: |C|return42(); |_|break;
+      default: |_|return;|R|
+    }
+  }
+|R|}
+
+function* idMaker() {
+  |_|yield 1;
+  |_|yield 2;
+  |_|yield 3;
+|R|}
+
+function testGenerator() {
+  var gen = |C|idMaker();
+  |C|return42();
+  gen.|C|next().value;
+  |D|debugger;
+  gen.|C|next().value;
+  |C|return42();
+  gen.|C|next().value;
+  |C|return42();
+  gen.|C|next().value;
+|R|}
+
+function throwException() {
+  |_|throw |C|new Error();
+}
+
+function testCaughtException() {
+  try {
+    |C|throwException()
+  } catch (e) {
+    |_|return;|R|
+  }
+|R|}
+
+function testClasses() {
+  class Cat {
+    constructor(name) {
+      |_|this.name = name;
+    |R|}
+
+    speak() {
+    |R|}
+  }
+  class Lion extends Cat {
+    constructor(name) {
+      |C|super(name);
+    |R|}
+
+    speak() {
+      |_|super.|C|speak();
+    |R|}
+  }
+  |C|new Lion().|C|speak();
+|R|}
+
+async function asyncFoo() {
+  |_|await Promise.|C|resolve().|C|then(v => v |_|* 2|R|);
+  |C|return42();
+  |_|await |C|asyncBoo();
+|R|}
+
+async function asyncBoo() {
+  |_|await Promise.|C|resolve();
+|R|}
+
+async function testAsyncAwait() {
+  |_|await |C|asyncFoo();
+  |_|await |C|awaitBoo();
+|R|}
+
+// TODO(kozyatinskiy): fix this.
+async function testPromiseAsyncWithCode() {
+  var nextTest;
+  var testPromise = |C|new Promise(resolve => nextTest |_|= resolve|R|);
+  async function main() {
+    async function foo() {
+      var resolveNested;
+      var p = |C|new Promise(resolve => resolveNested |_|= resolve|R|);
+      |C|setTimeout(resolveNested, 0);
+      |_|await p;
+    |R|}
+    |C|setTimeout(returnCall, 0);
+    await |C|foo();
+    await |C|foo();
+    |C|nextTest();
+  |R|}
+  |C|main();
+  |_|return testPromise;
+|R|}
+
+function returnFunction() {
+  |_|return returnObject;|R|
+}
+
+async function testPromiseComplex() {
+  var nextTest;
+  var testPromise = |C|new Promise(resolve => nextTest |_|= resolve|R|);
+  async function main() {
+    async function foo() {
+      |_|await Promise.|C|resolve();
+      |_|return 42;
+    |R|}
+    var x = |_|1;
+    var y = |_|2;
+    |C|returnFunction(|C|emptyFunction(), x++, --y, x => 2 |_|* x|R|, |C|returnCall())|C|().a = await |C|foo((a => 2 |_|*a|R|)|C|(5));
+    |C|nextTest();
+  |R|}
+  |C|main();
+  |_|return testPromise;
+|R|}
+
+function twiceDefined() {
+  return a + b;
+}
+
+function twiceDefined() {
+  |_|return a + b;|R|
+}
+
+
+
diff --git a/src/v8/test/inspector/debugger/get-possible-breakpoints-master.js b/src/v8/test/inspector/debugger/get-possible-breakpoints-master.js
new file mode 100644
index 0000000..33a3d63
--- /dev/null
+++ b/src/v8/test/inspector/debugger/get-possible-breakpoints-master.js
@@ -0,0 +1,15 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks Debugger.getPossibleBreakpoints');
+
+var source = utils.read('test/inspector/debugger/resources/break-locations.js');
+contextGroup.addScript(source);
+session.setupScriptMap();
+
+Protocol.Debugger.onceScriptParsed()
+  .then(message => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber : 0, scriptId: message.params.scriptId }}))
+  .then(message => session.logBreakLocations(message.result.locations))
+  .then(InspectorTest.completeTest);
+Protocol.Debugger.enable();
diff --git a/src/v8/test/inspector/debugger/get-possible-breakpoints-restrict-to-function-expected.txt b/src/v8/test/inspector/debugger/get-possible-breakpoints-restrict-to-function-expected.txt
new file mode 100644
index 0000000..0225fc3
--- /dev/null
+++ b/src/v8/test/inspector/debugger/get-possible-breakpoints-restrict-to-function-expected.txt
@@ -0,0 +1,177 @@
+Checks Debugger.getPossibleBreakpoints with ignoreNestedFunctions
+
+Running test: testWholeFunction
+
+function test() {
+  |_|Array.|C|from([1,2]).|C|map(() => |_|1|R|).|C|filter(() => |_|true|R|);
+  function nested1() {
+    |_|Array.|C|from([1,2]).|C|map(() => |_|1|R|).|C|filter(() => |_|true|R|);
+  |R|}
+  function nested2() {
+    |_|Array.|C|from([1,2]).|C|map(() => |_|1|R|).|C|filter(() => |_|true|R|);
+  |R|}
+  |C|nested1();
+  |C|nested2();
+|R|}
+
+
+Running test: testWholeFunctionWithoutNested
+
+function test() {
+  |_|Array.|C|from([1,2]).|C|map(() => |_|1|R|).|C|filter(() => |_|true|R|);
+  function nested1() {
+    |_|Array.|C|from([1,2]).|C|map(() => |_|1|R|).|C|filter(() => |_|true|R|);
+  |R|}
+  function nested2() {
+    |_|Array.|C|from([1,2]).|C|map(() => |_|1|R|).|C|filter(() => |_|true|R|);
+  |R|}
+  |C|nested1();
+  |C|nested2();
+|R|}
+
+
+Running test: testPartOfFunctionWithoutNested
+
+function test() {
+  |_|Array.|C|from([1,2]).map(() => 1).filter(() => true);
+  function nested1() {
+    Array.from([1,2]).map(() => 1).filter(() => true);
+  }
+  function nested2() {
+    Array.from([1,2]).map(() => 1).filter(() => true);
+  }
+  nested1();
+  nested2();
+}
+
+
+Running test: testNestedFunction
+
+function test() {
+  Array.from([1,2]).map(() => 1).filter(() => true);
+  function nested1() {
+    |_|Array.|C|from([1,2]).|C|map(() => |_|1|R|).|C|filter(() => |_|true|R|);
+  |R|}
+  function nested2() {
+    |_|Array.|C|from([1,2]).|C|map(() => |_|1|R|).|C|filter(() => |_|true|R|);
+  |R|}
+  |C|nested1();
+  |C|nested2();
+|R|}
+
+Run test() to check breakpoints..
+  }
+  #nested1();
+  nested2();
+
+  function nested1() {
+    #Array.from([1,2]).map(() => 1).filter(() => true);
+  }
+
+  function nested1() {
+    Array.#from([1,2]).map(() => 1).filter(() => true);
+  }
+
+  function nested1() {
+    Array.from([1,2]).#map(() => 1).filter(() => true);
+  }
+
+  function nested1() {
+    Array.from([1,2]).map(() => #1).filter(() => true);
+  }
+
+  function nested1() {
+    Array.from([1,2]).map(() => 1#).filter(() => true);
+  }
+
+  function nested1() {
+    Array.from([1,2]).map(() => #1).filter(() => true);
+  }
+
+  function nested1() {
+    Array.from([1,2]).map(() => 1#).filter(() => true);
+  }
+
+  function nested1() {
+    Array.from([1,2]).map(() => 1).#filter(() => true);
+  }
+
+  function nested1() {
+    Array.from([1,2]).map(() => 1).filter(() => #true);
+  }
+
+  function nested1() {
+    Array.from([1,2]).map(() => 1).filter(() => true#);
+  }
+
+  function nested1() {
+    Array.from([1,2]).map(() => 1).filter(() => #true);
+  }
+
+  function nested1() {
+    Array.from([1,2]).map(() => 1).filter(() => true#);
+  }
+
+    Array.from([1,2]).map(() => 1).filter(() => true);
+  #}
+  function nested2() {
+
+  nested1();
+  #nested2();
+}
+
+  function nested2() {
+    #Array.from([1,2]).map(() => 1).filter(() => true);
+  }
+
+  function nested2() {
+    Array.#from([1,2]).map(() => 1).filter(() => true);
+  }
+
+  function nested2() {
+    Array.from([1,2]).#map(() => 1).filter(() => true);
+  }
+
+  function nested2() {
+    Array.from([1,2]).map(() => #1).filter(() => true);
+  }
+
+  function nested2() {
+    Array.from([1,2]).map(() => 1#).filter(() => true);
+  }
+
+  function nested2() {
+    Array.from([1,2]).map(() => #1).filter(() => true);
+  }
+
+  function nested2() {
+    Array.from([1,2]).map(() => 1#).filter(() => true);
+  }
+
+  function nested2() {
+    Array.from([1,2]).map(() => 1).#filter(() => true);
+  }
+
+  function nested2() {
+    Array.from([1,2]).map(() => 1).filter(() => #true);
+  }
+
+  function nested2() {
+    Array.from([1,2]).map(() => 1).filter(() => true#);
+  }
+
+  function nested2() {
+    Array.from([1,2]).map(() => 1).filter(() => #true);
+  }
+
+  function nested2() {
+    Array.from([1,2]).map(() => 1).filter(() => true#);
+  }
+
+    Array.from([1,2]).map(() => 1).filter(() => true);
+  #}
+  nested1();
+
+  nested2();
+#}
+
diff --git a/src/v8/test/inspector/debugger/get-possible-breakpoints-restrict-to-function.js b/src/v8/test/inspector/debugger/get-possible-breakpoints-restrict-to-function.js
new file mode 100644
index 0000000..2a20bca
--- /dev/null
+++ b/src/v8/test/inspector/debugger/get-possible-breakpoints-restrict-to-function.js
@@ -0,0 +1,85 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks Debugger.getPossibleBreakpoints with ignoreNestedFunctions');
+
+var source = `
+function test() {
+  Array.from([1,2]).map(() => 1).filter(() => true);
+  function nested1() {
+    Array.from([1,2]).map(() => 1).filter(() => true);
+  }
+  function nested2() {
+    Array.from([1,2]).map(() => 1).filter(() => true);
+  }
+  nested1();
+  nested2();
+}
+//# sourceURL=test.js`;
+contextGroup.addScript(source);
+
+var scriptId;
+Protocol.Debugger.onceScriptParsed().then(message => {
+  if (message.params.url === 'test.js')
+    scriptId = message.params.scriptId;
+}).then(() => InspectorTest.runTestSuite(tests));
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  session.logSourceLocation(message.params.callFrames[0].location);
+  Protocol.Debugger.resume();
+});
+
+Protocol.Debugger.enable();
+var tests = [
+  function testWholeFunction(next) {
+    Protocol.Debugger.getPossibleBreakpoints({ start: location(1, 18), ignoreNestedFunctions: false })
+      .then(message => session.logBreakLocations(message.result.locations))
+      .then(next);
+  },
+
+  function testWholeFunctionWithoutNested(next) {
+    Protocol.Debugger.getPossibleBreakpoints({ start: location(1, 18), ignoreNestedFunctions: true })
+      .then(message => session.logBreakLocations(message.result.locations))
+      .then(next);
+  },
+
+  function testPartOfFunctionWithoutNested(next) {
+    Protocol.Debugger.getPossibleBreakpoints({ start: location(1, 18), end: location(2, 18), ignoreNestedFunctions: true })
+      .then(message => session.logBreakLocations(message.result.locations))
+      .then(next);
+  },
+
+  function testNestedFunction(next) {
+    Protocol.Debugger.getPossibleBreakpoints({ start: location(4, 0), ignoreNestedFunctions: true })
+      .then(message => session.logBreakLocations(message.result.locations))
+      .then(setAllBreakpoints)
+      .then(() => InspectorTest.log('Run test() to check breakpoints..'))
+      .then(() => Protocol.Runtime.evaluate({ expression: 'test()' }))
+      .then(next);
+  }
+];
+
+function location(lineNumber, columnNumber) {
+  return { lineNumber: lineNumber, columnNumber: columnNumber, scriptId: scriptId };
+}
+
+function setAllBreakpoints(locations) {
+  var promises = [];
+  for (var location of locations)
+    promises.push(Protocol.Debugger.setBreakpoint({ location: location }).then(checkBreakpoint));
+  return Promise.all(promises);
+}
+
+function checkBreakpoint(message) {
+  if (message.error) {
+    InspectorTest.log('FAIL: error in setBreakpoint');
+    InspectorTest.logMessage(message);
+    return;
+  }
+  var id_data = message.result.breakpointId.split(':');
+  if (parseInt(id_data[1]) !== message.result.actualLocation.lineNumber || parseInt(id_data[2]) !== message.result.actualLocation.columnNumber) {
+    InspectorTest.log('FAIL: possible breakpoint was resolved in another location');
+  }
+}
diff --git a/src/v8/test/inspector/debugger/get-possible-breakpoints.js b/src/v8/test/inspector/debugger/get-possible-breakpoints.js
new file mode 100644
index 0000000..3232d59
--- /dev/null
+++ b/src/v8/test/inspector/debugger/get-possible-breakpoints.js
@@ -0,0 +1,233 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Test for Debugger.getPossibleBreakpoints');
+
+Protocol.Runtime.enable();
+Protocol.Debugger.enable();
+
+InspectorTest.runTestSuite([
+
+  function getPossibleBreakpointsInRange(next) {
+    var source = 'function foo(){ return Promise.resolve(); }\nfunction boo(){ return Promise.resolve().then(() => 42); }\n\n';
+    var scriptId;
+    compileScript(source)
+      .then(id => scriptId = id)
+      .then(() => InspectorTest.log('Test start.scriptId != end.scriptId.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber: 0, scriptId: scriptId }, end: { lineNumber: 0, columnNumber: 0, scriptId: scriptId + '0' }}))
+      .then(message => dumpAllLocations(message, source))
+      .then(() => InspectorTest.log('Test not existing scriptId.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber: 0, scriptId: '-1' }}))
+      .then(message => dumpAllLocations(message, source))
+      .then(() => InspectorTest.log('Test end < start.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 1, columnNumber: 0, scriptId: scriptId }, end: { lineNumber: 0, columnNumber: 0, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source))
+      .then(() => InspectorTest.log('Test empty range in first line.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber: 16, scriptId: scriptId }, end: { lineNumber: 0, columnNumber: 16, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source))
+      .then(() => InspectorTest.log('Test one character range in first line.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber: 16, scriptId: scriptId }, end: { lineNumber: 0, columnNumber: 17, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source))
+      .then(() => InspectorTest.log('Test empty range in not first line.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 1, columnNumber: 16, scriptId: scriptId }, end: { lineNumber: 1, columnNumber: 16, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source))
+      .then(() => InspectorTest.log('Test one character range in not first line.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 1, columnNumber: 16, scriptId: scriptId }, end: { lineNumber: 1, columnNumber: 17, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source))
+      .then(() => InspectorTest.log('Test end is undefined'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber: 0, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source))
+      .then(() => InspectorTest.log('Test end.lineNumber > scripts.lineCount()'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber: 0, scriptId: scriptId }, end: { lineNumber: 5, columnNumber: 0, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source))
+      .then(() => InspectorTest.log('Test one string'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber: 0, scriptId: scriptId }, end: { lineNumber: 1, columnNumber: 0, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source))
+      .then(() => InspectorTest.log('Test end.columnNumber > end.line.length(), should be the same as previous.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber: 0, scriptId: scriptId }, end: { lineNumber: 0, columnNumber: 256, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source))
+      .then(next);
+  },
+
+  function getPossibleBreakpointsInArrow(next) {
+    var source = 'function foo() { return Promise.resolve().then(() => 239).then(() => 42).then(() => () => 42) }';
+    var scriptId;
+    compileScript(source)
+      .then(id => scriptId = id)
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber: 0, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source))
+      .then(next);
+  },
+
+  function arrowFunctionFirstLine(next) {
+    Protocol.Debugger.onPaused(message => dumpBreakLocationInSourceAndResume(message, source));
+
+    var source = `function foo1() { Promise.resolve().then(() => 42) }
+function foo2() { Promise.resolve().then(() => 42) }`;
+    waitForPossibleBreakpoints(source, { lineNumber: 0, columnNumber: 0 }, { lineNumber: 1, columnNumber: 0 })
+      .then(message => dumpAllLocations(message, source))
+      .then(setAllBreakpoints)
+      .then(() => Protocol.Runtime.evaluate({ expression: 'foo1(); foo2()'}))
+      .then(next);
+  },
+
+  function arrowFunctionOnPause(next) {
+    var source = `debugger; function foo3() { Promise.resolve().then(() => 42) }
+function foo4() { Promise.resolve().then(() => 42) };\nfoo3();\nfoo4();`;
+    waitForPossibleBreakpointsOnPause(source, { lineNumber: 0, columnNumber: 0 }, undefined, next)
+      .then(message => dumpAllLocations(message, source))
+      .then(setAllBreakpoints)
+      .then(() => Protocol.Debugger.onPaused(message => dumpBreakLocationInSourceAndResume(message, source)))
+      .then(() => Protocol.Debugger.resume());
+  },
+
+  function getPossibleBreakpointsInRangeWithOffset(next) {
+    var source = 'function foo(){ return Promise.resolve(); }\nfunction boo(){ return Promise.resolve().then(() => 42); }\n\n';
+    var scriptId;
+    compileScript(source, { name: 'with-offset.js', line_offset: 1, column_offset: 1 })
+      .then(id => scriptId = id)
+      .then(() => InspectorTest.log('Test empty range in first line.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 1, columnNumber: 17, scriptId: scriptId }, end: { lineNumber: 1, columnNumber: 17, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source, 1, 1))
+      .then(() => InspectorTest.log('Test one character range in first line.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 1, columnNumber: 17, scriptId: scriptId }, end: { lineNumber: 1, columnNumber: 18, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source, 1, 1))
+      .then(() => InspectorTest.log('Test empty range in not first line.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 2, columnNumber: 16, scriptId: scriptId }, end: { lineNumber: 2, columnNumber: 16, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source, 1, 1))
+      .then(() => InspectorTest.log('Test one character range in not first line.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 2, columnNumber: 16, scriptId: scriptId }, end: { lineNumber: 2, columnNumber: 17, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source, 1, 1))
+      .then(() => InspectorTest.log('Test end is undefined'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber: 0, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source, 1, 1))
+      .then(() => InspectorTest.log('Test end.lineNumber > scripts.lineCount()'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 0, columnNumber: 0, scriptId: scriptId }, end: { lineNumber: 5, columnNumber: 0, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source, 1, 1))
+      .then(() => InspectorTest.log('Test one string'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 1, columnNumber: 1, scriptId: scriptId }, end: { lineNumber: 2, columnNumber: 0, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source, 1, 1))
+      .then(() => InspectorTest.log('Test end.columnNumber > end.line.length(), should be the same as previous.'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: 1, columnNumber: 1, scriptId: scriptId }, end: { lineNumber: 1, columnNumber: 256, scriptId: scriptId }}))
+      .then(message => dumpAllLocations(message, source, 1, 1))
+      .then(next);
+  },
+
+  function withOffset(next) {
+    Protocol.Debugger.onPaused(message => dumpBreakLocationInSourceAndResume(message, source, 3, 18));
+
+    var source = `function foo5() { Promise.resolve().then(() => 42) }
+function foo6() { Promise.resolve().then(() => 42) }`;
+    waitForPossibleBreakpoints(source, { lineNumber: 0, columnNumber: 0 }, undefined, { name: 'with-offset.js', line_offset: 3, column_offset: 18 })
+      .then(message => dumpAllLocations(message, source, 3, 18))
+      .then(setAllBreakpoints)
+      .then(() => Protocol.Runtime.evaluate({ expression: 'foo5(); foo6()'}))
+      .then(next);
+  },
+
+  function arrowFunctionReturn(next) {
+    function checkSource(source, location) {
+      return waitForPossibleBreakpoints(source, location)
+        .then(message => dumpAllLocations(message, source));
+    }
+
+    checkSource('() => 239\n', { lineNumber: 0, columnNumber: 0 })
+      .then(() => checkSource('function foo() { function boo() { return 239 }  }\n', { lineNumber: 0, columnNumber: 0 }))
+      .then(() => checkSource('() => { 239 }\n', { lineNumber: 0, columnNumber: 0 }))
+      .then(() => checkSource('function foo() { 239 }\n', { lineNumber: 0, columnNumber: 0 }))
+      // TODO(kozyatinskiy): lineNumber for return position should be only 9, not 8.
+      .then(() => checkSource('() => 239', { lineNumber: 0, columnNumber: 0 }))
+      .then(() => checkSource('() => { return 239 }', { lineNumber: 0, columnNumber: 0 }))
+      .then(next);
+  },
+
+  function argumentsAsCalls(next) {
+    var source = 'function foo(){}\nfunction boo(){}\nfunction main(f1,f2){}\nmain(foo(), boo());\n';
+    waitForPossibleBreakpoints(source, { lineNumber: 0, columnNumber: 0 })
+      .then(message => dumpAllLocations(message, source))
+      .then(next);
+  }
+]);
+
+function compileScript(source, origin) {
+  var promise = Protocol.Debugger.onceScriptParsed().then(message => message.params.scriptId);
+  if (!origin) origin = { name: '', line_offset: 0, column_offset: 0 };
+  contextGroup.addScript(source, origin.line_offset, origin.column_offset, origin.name);
+  return promise;
+}
+
+function waitForPossibleBreakpoints(source, start, end, origin) {
+  return compileScript(source, origin)
+    .then(scriptId => { (start || {}).scriptId = scriptId; (end || {}).scriptId = scriptId })
+    .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: start, end: end }));
+}
+
+function waitForPossibleBreakpointsOnPause(source, start, end, next) {
+  var promise = Protocol.Debugger.oncePaused()
+    .then(msg => { (start || {}).scriptId = msg.params.callFrames[0].location.scriptId; (end || {}).scriptId = msg.params.callFrames[0].location.scriptId })
+    .then(() => Protocol.Debugger.getPossibleBreakpoints({ start: start, end: end }));
+  Protocol.Runtime.evaluate({ expression: source }).then(next);
+  return promise;
+}
+
+function setAllBreakpoints(message) {
+  var promises = [];
+  for (var location of message.result.locations)
+    promises.push(Protocol.Debugger.setBreakpoint({ location: location }).then(checkBreakpoint));
+  return Promise.all(promises);
+}
+
+function checkBreakpoint(message) {
+  if (message.error) {
+    InspectorTest.log('FAIL: error in setBreakpoint');
+    InspectorTest.logMessage(message);
+    return;
+  }
+  var id_data = message.result.breakpointId.split(':');
+  if (parseInt(id_data[1]) !== message.result.actualLocation.lineNumber || parseInt(id_data[2]) !== message.result.actualLocation.columnNumber) {
+    InspectorTest.log('FAIL: possible breakpoint was resolved in another location');
+  }
+}
+
+function dumpAllLocations(message, source, lineOffset, columnOffset) {
+  if (message.error) {
+    InspectorTest.logMessage(message);
+    return;
+  }
+
+  lineOffset = lineOffset || 0;
+  columnOffset = columnOffset || 0;
+
+  var sourceLines = source.split('\n')
+  var lineOffsets = Array(sourceLines.length).fill(0);
+  for (var location of message.result.locations) {
+    var lineNumber = location.lineNumber - lineOffset;
+    var columnNumber = lineNumber !== 0 ? location.columnNumber : location.columnNumber - columnOffset;
+    var line = sourceLines[lineNumber] || '';
+    var offset = lineOffsets[lineNumber];
+    line = line.slice(0, columnNumber + offset) + '#' + line.slice(columnNumber + offset);
+    ++lineOffsets[lineNumber];
+    sourceLines[lineNumber] = line;
+  }
+  InspectorTest.log(sourceLines.join('\n'));
+  return message;
+}
+
+function dumpBreakLocationInSourceAndResume(message, source, lineOffset, columnOffset) {
+  lineOffset = lineOffset || 0;
+  columnOffset = columnOffset || 0;
+
+  InspectorTest.log('paused in ' + message.params.callFrames[0].functionName);
+  var location = message.params.callFrames[0].location;
+  var sourceLines = source.split('\n')
+
+  var lineNumber = location.lineNumber - lineOffset;
+  var columnNumber = lineNumber !== 0 ? location.columnNumber : location.columnNumber - columnOffset;
+
+  var line = sourceLines[lineNumber];
+  line = line.slice(0, columnNumber) + '^' + line.slice(columnNumber);
+  sourceLines[lineNumber] = line;
+  InspectorTest.log(sourceLines.join('\n'));
+  Protocol.Debugger.resume();
+}
diff --git a/src/v8/test/inspector/debugger/inspector-break-api-expected.txt b/src/v8/test/inspector/debugger/inspector-break-api-expected.txt
new file mode 100644
index 0000000..1677b59
--- /dev/null
+++ b/src/v8/test/inspector/debugger/inspector-break-api-expected.txt
@@ -0,0 +1,38 @@
+Checks breakProgram,(schedule|cancel)PauseOnNextStatement test API
+
+Running test: testBreakProgram
+Stack:
+callBreakProgram (:9:12)
+(anonymous) (:0:0)
+Other data:
+{
+    method : Debugger.paused
+    params : {
+        data : {
+            a : 42
+        }
+        hitBreakpoints : [
+        ]
+        reason : reason
+    }
+}
+
+
+Running test: testSchedulePauseOnNextStatement
+Stack:
+(anonymous) (expr1.js:0:0)
+Other data:
+{
+    method : Debugger.paused
+    params : {
+        data : {
+            a : 42
+        }
+        hitBreakpoints : [
+        ]
+        reason : reason
+    }
+}
+
+
+Running test: testCancelPauseOnNextStatement
diff --git a/src/v8/test/inspector/debugger/inspector-break-api.js b/src/v8/test/inspector/debugger/inspector-break-api.js
new file mode 100644
index 0000000..dc39924
--- /dev/null
+++ b/src/v8/test/inspector/debugger/inspector-break-api.js
@@ -0,0 +1,50 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Checks breakProgram,(schedule|cancel)PauseOnNextStatement test API");
+
+contextGroup.addScript(`
+function callBreakProgram() {
+  inspector.breakProgram('reason', JSON.stringify({a: 42}));
+}
+
+function foo() {
+  return 42;
+}`, 7, 26);
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  InspectorTest.log('Stack:');
+  session.logCallFrames(message.params.callFrames);
+  delete message.params.callFrames;
+  InspectorTest.log('Other data:');
+  InspectorTest.logMessage(message);
+  InspectorTest.log('');
+  Protocol.Debugger.resume();
+});
+
+Protocol.Debugger.enable();
+
+InspectorTest.runTestSuite([
+  function testBreakProgram(next) {
+    Protocol.Runtime.evaluate({ expression: 'callBreakProgram()'})
+      .then(next);
+  },
+
+  function testSchedulePauseOnNextStatement(next) {
+    contextGroup.schedulePauseOnNextStatement('reason', JSON.stringify({a: 42}));
+    Protocol.Runtime.evaluate({ expression: 'foo()//# sourceURL=expr1.js'})
+      .then(() => Protocol.Runtime.evaluate({
+        expression: 'foo()//# sourceURL=expr2.js'}))
+      .then(() => contextGroup.cancelPauseOnNextStatement())
+      .then(next);
+  },
+
+  function testCancelPauseOnNextStatement(next) {
+    contextGroup.schedulePauseOnNextStatement('reason', JSON.stringify({a: 42}));
+    contextGroup.cancelPauseOnNextStatement();
+    Protocol.Runtime.evaluate({ expression: 'foo()'})
+      .then(next);
+  }
+]);
diff --git a/src/v8/test/inspector/debugger/max-async-call-chain-depth-expected.txt b/src/v8/test/inspector/debugger/max-async-call-chain-depth-expected.txt
new file mode 100644
index 0000000..0c421da
--- /dev/null
+++ b/src/v8/test/inspector/debugger/max-async-call-chain-depth-expected.txt
@@ -0,0 +1,91 @@
+Checks that we trim async call chains correctly.
+set async chain depth to 8
+
+Running test: testDebuggerPaused
+Run expression 'debugger;' with async chain len: 4
+actual async chain len: 1
+Run expression 'debugger;' with async chain len: 8
+actual async chain len: 1
+Run expression 'debugger;' with async chain len: 9
+actual async chain len: 1
+Run expression 'debugger;' with async chain len: 32
+actual async chain len: 1
+
+Running test: testConsoleTrace
+Run expression 'console.trace(42);' with async chain len: 4
+actual async chain len: 1
+Run expression 'console.trace(42);' with async chain len: 8
+actual async chain len: 1
+Run expression 'console.trace(42);' with async chain len: 9
+actual async chain len: 1
+Run expression 'console.trace(42);' with async chain len: 32
+actual async chain len: 1
+
+Running test: testDebuggerPausedSetTimeout
+Run expression 'debugger;' with async chain len: 4
+actual async chain len: 4
+Run expression 'debugger;' with async chain len: 8
+actual async chain len: 8
+Run expression 'debugger;' with async chain len: 9
+actual async chain len: 8
+Run expression 'debugger;' with async chain len: 32
+actual async chain len: 8
+
+Running test: testConsoleTraceSetTimeout
+Run expression 'console.trace(42);' with async chain len: 4
+actual async chain len: 4
+Run expression 'console.trace(42);' with async chain len: 8
+actual async chain len: 8
+Run expression 'console.trace(42);' with async chain len: 9
+actual async chain len: 8
+Run expression 'console.trace(42);' with async chain len: 32
+actual async chain len: 8
+
+Running test: testConsoleTraceWithEmptySync
+{
+    callFrames : [
+        [0] : {
+            columnNumber : 66
+            functionName : Promise.then
+            lineNumber : 0
+            scriptId : <scriptId>
+            url : 
+        }
+    ]
+    parent : {
+        callFrames : [
+            [0] : {
+                columnNumber : 47
+                functionName : 
+                lineNumber : 0
+                scriptId : <scriptId>
+                url : 
+            }
+        ]
+        description : Promise.resolve
+    }
+}
+
+Running test: testDebuggerPausedThenableJob
+Run expression 'debugger;' with async chain len: 4
+actual async chain len: 1
+Run expression 'debugger;' with async chain len: 8
+actual async chain len: 1
+Run expression 'debugger;' with async chain len: 9
+actual async chain len: 1
+Run expression 'debugger;' with async chain len: 32
+actual async chain len: 1
+
+Running test: testConsoleTraceThenableJob
+Run expression 'console.trace(42);' with async chain len: 4
+actual async chain len: 1
+Run expression 'console.trace(42);' with async chain len: 8
+actual async chain len: 1
+Run expression 'console.trace(42);' with async chain len: 9
+actual async chain len: 1
+Run expression 'console.trace(42);' with async chain len: 32
+actual async chain len: 1
+
+Running test: twoConsoleAssert
+actual async chain len: 1
+actual async chain len: 2
diff --git a/src/v8/test/inspector/debugger/max-async-call-chain-depth.js b/src/v8/test/inspector/debugger/max-async-call-chain-depth.js
new file mode 100644
index 0000000..ae98f55
--- /dev/null
+++ b/src/v8/test/inspector/debugger/max-async-call-chain-depth.js
@@ -0,0 +1,162 @@
+// Copyright 2017 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.
+
+// TODO(kozyatinskiy): fix or remove it later.
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that we trim async call chains correctly.');
+
+Protocol.Debugger.enable();
+InspectorTest.log('set async chain depth to 8');
+Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 8});
+InspectorTest.runAsyncTestSuite([
+  async function testDebuggerPaused() {
+    runWithAsyncChain(4, 'debugger;');
+    dumpAsyncChainLength(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+
+    runWithAsyncChain(8, 'debugger;');
+    dumpAsyncChainLength(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+
+    runWithAsyncChain(9, 'debugger;');
+    dumpAsyncChainLength(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+
+    runWithAsyncChain(32, 'debugger;');
+    dumpAsyncChainLength(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testConsoleTrace() {
+    Protocol.Runtime.enable();
+    runWithAsyncChain(4, 'console.trace(42);');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    runWithAsyncChain(8, 'console.trace(42);');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    runWithAsyncChain(9, 'console.trace(42);');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    runWithAsyncChain(32, 'console.trace(42);');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+  },
+
+  async function testDebuggerPausedSetTimeout() {
+    runWithAsyncChainSetTimeout(4, 'debugger;');
+    dumpAsyncChainLength(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+
+    runWithAsyncChainSetTimeout(8, 'debugger;');
+    dumpAsyncChainLength(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+
+    runWithAsyncChainSetTimeout(9, 'debugger;');
+    dumpAsyncChainLength(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+
+    runWithAsyncChainSetTimeout(32, 'debugger;');
+    dumpAsyncChainLength(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testConsoleTraceSetTimeout() {
+    runWithAsyncChainSetTimeout(4, 'console.trace(42);');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    runWithAsyncChainSetTimeout(8, 'console.trace(42);');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    runWithAsyncChainSetTimeout(9, 'console.trace(42);');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    runWithAsyncChainSetTimeout(32, 'console.trace(42);');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+  },
+
+  async function testConsoleTraceWithEmptySync() {
+    Protocol.Runtime.evaluate({
+      expression: 'new Promise(resolve => setTimeout(resolve, 0)).then(() => console.trace(42))'
+    });
+    InspectorTest.logMessage((await Protocol.Runtime.onceConsoleAPICalled()).params.stackTrace);
+  },
+
+  async function testDebuggerPausedThenableJob() {
+    runWithThenableJob(4, 'debugger;');
+    dumpAsyncChainLength(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+
+    runWithThenableJob(8, 'debugger;');
+    dumpAsyncChainLength(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+
+    runWithThenableJob(9, 'debugger;');
+    dumpAsyncChainLength(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+
+    runWithThenableJob(32, 'debugger;');
+    dumpAsyncChainLength(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testConsoleTraceThenableJob() {
+    runWithThenableJob(4, 'console.trace(42);');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    runWithThenableJob(8, 'console.trace(42);');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    runWithThenableJob(9, 'console.trace(42);');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+
+    runWithThenableJob(32, 'console.trace(42);');
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+  },
+
+  async function twoConsoleAssert() {
+    Protocol.Runtime.evaluate({
+      expression: 'setTimeout(' +
+        'setTimeout.bind(null, ' +
+          'setTimeout.bind(null, () => { console.assert(); setTimeout(console.assert, 0) }, 0), 0), 0)'
+    });
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+    dumpAsyncChainLength(await Protocol.Runtime.onceConsoleAPICalled());
+  }
+]);
+
+function runWithAsyncChain(len, source) {
+  InspectorTest.log(`Run expression '${source}' with async chain len: ${len}`);
+  let then = '.then(() => 1)';
+  let pause = `.then(() => { ${source} })`;
+  Protocol.Runtime.evaluate({
+    expression: `Promise.resolve()${then.repeat(len - 1)}${pause}`
+  });
+}
+
+function runWithAsyncChainSetTimeout(len, source) {
+  InspectorTest.log(`Run expression '${source}' with async chain len: ${len}`);
+  let setTimeout = 'setTimeout(() => {';
+  let suffix = '}, 0)';
+  Protocol.Runtime.evaluate({
+    expression: `${setTimeout.repeat(len)}${source}${suffix.repeat(len)}`
+  });
+}
+
+function runWithThenableJob(len, source) {
+  InspectorTest.log(`Run expression '${source}' with async chain len: ${len}`);
+  let then = '.then(Promise.resolve.bind(Promise, 0))';
+  let pause = `.then(() => { ${source} })`;
+  Protocol.Runtime.evaluate({
+    expression: `Promise.resolve()${then.repeat(len - 1)}${pause}`
+  });
+}
+
+function dumpAsyncChainLength(message) {
+  let stackTrace = message.params.asyncStackTrace || message.params.stackTrace.parent;
+  let asyncChainCount = 0;
+  while (stackTrace) {
+    ++asyncChainCount;
+    stackTrace = stackTrace.parent;
+  }
+  InspectorTest.log(`actual async chain len: ${asyncChainCount}`);
+}
diff --git a/src/v8/test/inspector/debugger/not-hold-promises-expected.txt b/src/v8/test/inspector/debugger/not-hold-promises-expected.txt
new file mode 100644
index 0000000..93929b1
--- /dev/null
+++ b/src/v8/test/inspector/debugger/not-hold-promises-expected.txt
@@ -0,0 +1,2 @@
+Tests that we don't hold promises.
+SUCCESS
diff --git a/src/v8/test/inspector/debugger/not-hold-promises.js b/src/v8/test/inspector/debugger/not-hold-promises.js
new file mode 100644
index 0000000..815b618
--- /dev/null
+++ b/src/v8/test/inspector/debugger/not-hold-promises.js
@@ -0,0 +1,36 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+  InspectorTest.start('Tests that we don\'t hold promises.');
+
+(async function test() {
+  Protocol.Runtime.enable();
+  Protocol.Debugger.enable();
+  Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
+  Protocol.HeapProfiler.enable();
+  // Force inspector internal scripts compilation.
+  await Protocol.Runtime.evaluate({expression: ''});
+  let snapshot = '';
+  Protocol.HeapProfiler.onAddHeapSnapshotChunk(msg => snapshot += msg.params.chunk);
+  await Protocol.HeapProfiler.collectGarbage();
+  await Protocol.HeapProfiler.takeHeapSnapshot();
+  let initial_node_count = JSON.parse(snapshot).snapshot.node_count;
+
+  await Protocol.Runtime.evaluate({
+    expression: `for (let i = 0; i < ${initial_node_count / 4}; ++i) Promise.resolve()`});
+  snapshot = '';
+  Protocol.HeapProfiler.onAddHeapSnapshotChunk(msg => snapshot += msg.params.chunk);
+  await Protocol.HeapProfiler.collectGarbage();
+  await Protocol.HeapProfiler.takeHeapSnapshot();
+  let without_storing_node_count = JSON.parse(snapshot).snapshot.node_count;
+  let diff_without_storing = (without_storing_node_count - initial_node_count);
+
+  if (diff_without_storing < initial_node_count / 4) {
+    InspectorTest.log('SUCCESS');
+  } else {
+    InspectorTest.log('FAILED: looks like all promises were not collected.');
+  }
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/debugger/object-preview-internal-properties-expected.txt b/src/v8/test/inspector/debugger/object-preview-internal-properties-expected.txt
new file mode 100644
index 0000000..394c1be
--- /dev/null
+++ b/src/v8/test/inspector/debugger/object-preview-internal-properties-expected.txt
@@ -0,0 +1,248 @@
+Check internal properties reported in object preview.
+
+Running test: boxedObjects
+expression: new Number(239)
+{
+    name : [[PrimitiveValue]]
+    type : number
+    value : 239
+}
+
+expression: new Boolean(false)
+{
+    name : [[PrimitiveValue]]
+    type : boolean
+    value : false
+}
+
+expression: new String("abc")
+{
+    name : [[PrimitiveValue]]
+    type : string
+    value : abc
+}
+
+expression: Object(Symbol(42))
+{
+    name : [[PrimitiveValue]]
+    type : symbol
+    valuePreview : {
+        description : Symbol
+        overflow : false
+        properties : [
+        ]
+        type : object
+    }
+}
+
+
+Running test: promise
+expression: Promise.resolve(42)
+{
+    name : [[PromiseStatus]]
+    type : string
+    value : resolved
+}
+{
+    name : [[PromiseValue]]
+    type : number
+    value : 42
+}
+
+expression: new Promise(() => undefined)
+{
+    name : [[PromiseStatus]]
+    type : string
+    value : pending
+}
+{
+    name : [[PromiseValue]]
+    type : undefined
+    value : undefined
+}
+
+
+Running test: generatorObject
+expression: (function* foo() { yield 1 })()
+{
+    name : [[GeneratorStatus]]
+    type : string
+    value : suspended
+}
+
+
+Running test: entriesInMapAndSet
+expression: new Map([[1,2]])
+[[Entries]]:
+[
+    [0] : {
+        key : {
+            description : 1
+            overflow : false
+            properties : [
+            ]
+            type : number
+        }
+        value : {
+            description : 2
+            overflow : false
+            properties : [
+            ]
+            type : number
+        }
+    }
+]
+
+expression: new Set([1])
+[[Entries]]:
+[
+    [0] : {
+        value : {
+            description : 1
+            overflow : false
+            properties : [
+            ]
+            type : number
+        }
+    }
+]
+
+expression: new WeakMap([[{}, 42]])
+[[Entries]]:
+[
+    [0] : {
+        key : {
+            description : Object
+            overflow : false
+            properties : [
+            ]
+            type : object
+        }
+        value : {
+            description : 42
+            overflow : false
+            properties : [
+            ]
+            type : number
+        }
+    }
+]
+
+expression: new WeakSet([{}])
+[[Entries]]:
+[
+    [0] : {
+        value : {
+            description : Object
+            overflow : false
+            properties : [
+            ]
+            type : object
+        }
+    }
+]
+
+
+Running test: iteratorObject
+expression: (new Map([[1,2]])).entries()
+[[Entries]]:
+[
+    [0] : {
+        key : {
+            description : 1
+            overflow : false
+            properties : [
+            ]
+            type : number
+        }
+        value : {
+            description : 2
+            overflow : false
+            properties : [
+            ]
+            type : number
+        }
+    }
+]
+
+expression: (new Set([[1,2]])).entries()
+[[Entries]]:
+[
+    [0] : {
+        value : {
+            description : Array(2)
+            overflow : false
+            properties : [
+                [0] : {
+                    name : 0
+                    type : number
+                    value : 1
+                }
+                [1] : {
+                    name : 1
+                    type : number
+                    value : 2
+                }
+            ]
+            subtype : array
+            type : object
+        }
+    }
+]
+
+
+Running test: noPreviewForFunctionObject
+(function foo(){})
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function foo(){}
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+
+Running test: otherObjects
+expression: [1,2,3]
+{
+    name : 0
+    type : number
+    value : 1
+}
+{
+    name : 1
+    type : number
+    value : 2
+}
+{
+    name : 2
+    type : number
+    value : 3
+}
+
+expression: /123/
+{
+    name : lastIndex
+    type : number
+    value : 0
+}
+
+expression: ({})
+
+
+Running test: overridenArrayGetter
+expression: Promise.resolve(42)
+{
+    name : [[PromiseStatus]]
+    type : string
+    value : resolved
+}
+{
+    name : [[PromiseValue]]
+    type : number
+    value : 42
+}
+
diff --git a/src/v8/test/inspector/debugger/object-preview-internal-properties.js b/src/v8/test/inspector/debugger/object-preview-internal-properties.js
new file mode 100644
index 0000000..6c655d1
--- /dev/null
+++ b/src/v8/test/inspector/debugger/object-preview-internal-properties.js
@@ -0,0 +1,107 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Check internal properties reported in object preview.");
+
+Protocol.Debugger.enable();
+Protocol.Runtime.enable();
+Protocol.Runtime.onConsoleAPICalled(dumpInternalPropertiesAndEntries);
+
+contextGroup.setupInjectedScriptEnvironment();
+
+InspectorTest.runTestSuite([
+  function boxedObjects(next)
+  {
+    checkExpression("new Number(239)")
+      .then(() => checkExpression("new Boolean(false)"))
+      .then(() => checkExpression("new String(\"abc\")"))
+      .then(() => checkExpression("Object(Symbol(42))"))
+      .then(next);
+  },
+
+  function promise(next)
+  {
+    checkExpression("Promise.resolve(42)")
+      .then(() => checkExpression("new Promise(() => undefined)"))
+      .then(next);
+  },
+
+  function generatorObject(next)
+  {
+    checkExpression("(function* foo() { yield 1 })()")
+      .then(next);
+  },
+
+  function entriesInMapAndSet(next)
+  {
+    checkExpression("new Map([[1,2]])")
+      .then(() => checkExpression("new Set([1])"))
+      .then(() => checkExpression("new WeakMap([[{}, 42]])"))
+      .then(() => checkExpression("new WeakSet([{}])"))
+      .then(next);
+  },
+
+  function iteratorObject(next)
+  {
+    checkExpression("(new Map([[1,2]])).entries()")
+      .then(() => checkExpression("(new Set([[1,2]])).entries()"))
+      .then(next);
+  },
+
+  function noPreviewForFunctionObject(next)
+  {
+    var expression = "(function foo(){})";
+    InspectorTest.log(expression);
+    Protocol.Runtime.evaluate({ expression: expression, generatePreview: true})
+      .then(message => InspectorTest.logMessage(message))
+      .then(next);
+  },
+
+  function otherObjects(next)
+  {
+    checkExpression("[1,2,3]")
+      .then(() => checkExpression("/123/"))
+      .then(() => checkExpression("({})"))
+      .then(next);
+  },
+
+  function overridenArrayGetter(next)
+  {
+    Protocol.Runtime.evaluate({ expression: "Array.prototype.__defineGetter__(\"0\",() => { throw new Error() }) "})
+      .then(() => checkExpression("Promise.resolve(42)"))
+      .then(next);
+  }
+]);
+
+function checkExpression(expression)
+{
+  InspectorTest.log(`expression: ${expression}`);
+  // console.table has higher limits for internal properties amount in preview.
+  return Protocol.Runtime.evaluate({ expression: `console.table(${expression})`, generatePreview: true });
+}
+
+function dumpInternalPropertiesAndEntries(message)
+{
+  var properties;
+  var entries;
+  try {
+    var preview = message.params.args[0].preview;
+    properties = preview.properties;
+    entries = preview.entries;
+  } catch (e) {
+    InspectorTest.logMessage(message);
+    return;
+  }
+  if (!properties) {
+    InspectorTest.logMessage(message);
+    return;
+  }
+  for (var property of properties)
+    InspectorTest.logMessage(property);
+  if (entries) {
+    InspectorTest.log("[[Entries]]:");
+    InspectorTest.logMessage(entries);
+  }
+  InspectorTest.log("");
+}
diff --git a/src/v8/test/inspector/debugger/pause-at-negative-offset-expected.txt b/src/v8/test/inspector/debugger/pause-at-negative-offset-expected.txt
new file mode 100644
index 0000000..23c5490
--- /dev/null
+++ b/src/v8/test/inspector/debugger/pause-at-negative-offset-expected.txt
@@ -0,0 +1,2 @@
+Tests that we dont crash on pause at negative offset
+(anonymous) (test.js:-3:-3)
diff --git a/src/v8/test/inspector/debugger/pause-at-negative-offset.js b/src/v8/test/inspector/debugger/pause-at-negative-offset.js
new file mode 100644
index 0000000..4d0928b
--- /dev/null
+++ b/src/v8/test/inspector/debugger/pause-at-negative-offset.js
@@ -0,0 +1,15 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+  InspectorTest.start('Tests that we dont crash on pause at negative offset');
+
+(async function test() {
+  session.setupScriptMap();
+  await Protocol.Debugger.enable();
+  contextGroup.addScript(`debugger;//# sourceURL=test.js`, -3, -3);
+  let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+  session.logCallFrames(callFrames);
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/debugger/pause-expected.txt b/src/v8/test/inspector/debugger/pause-expected.txt
new file mode 100644
index 0000000..2489191
--- /dev/null
+++ b/src/v8/test/inspector/debugger/pause-expected.txt
@@ -0,0 +1,73 @@
+Checks Debugger.pause
+
+Running test: testPause
+paused at:
+#var a = 42;
+
+
+Running test: testSkipFrameworks
+paused at:
+#var a = 239;
+
+
+Running test: testSkipOtherContext1
+paused at:
+var a = #1;
+
+
+Running test: testSkipOtherContext2
+paused at:
+#var a = 239;
+
+paused at:
+var a = #239;
+
+
+Running test: testWithNativeBreakpoint
+paused at:
+#var a = 42;
+
+paused at:
+#var a = 42;
+
+paused at:
+#var a = 42;
+
+
+Running test: testResumeAnotherGroup
+paused at:
+#var a = 42;
+
+{
+    error : {
+        code : -32000
+        message : Can only perform operation while paused.
+    }
+    id : <messageId>
+}
+{
+    error : {
+        code : -32000
+        message : Can only perform operation while paused.
+    }
+    id : <messageId>
+}
+{
+    error : {
+        code : -32000
+        message : Can only perform operation while paused.
+    }
+    id : <messageId>
+}
+{
+    error : {
+        code : -32000
+        message : Can only perform operation while paused.
+    }
+    id : <messageId>
+}
+
+Running test: testDisableBreaksShouldCancelPause
+paused at:
+#debugger
+
diff --git a/src/v8/test/inspector/debugger/pause-on-oom-expected.txt b/src/v8/test/inspector/debugger/pause-on-oom-expected.txt
new file mode 100644
index 0000000..4ca988d
--- /dev/null
+++ b/src/v8/test/inspector/debugger/pause-on-oom-expected.txt
@@ -0,0 +1,2 @@
+Check pause on OOM
+reason: OOM
diff --git a/src/v8/test/inspector/debugger/pause-on-oom.js b/src/v8/test/inspector/debugger/pause-on-oom.js
new file mode 100644
index 0000000..fe5d61b
--- /dev/null
+++ b/src/v8/test/inspector/debugger/pause-on-oom.js
@@ -0,0 +1,28 @@
+// Copyright 2017 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.
+
+// Flags: --max-old-space-size=8
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Check pause on OOM');
+
+contextGroup.addScript(`
+var arr = [];
+var stop = false;
+function generateGarbage() {
+  while(!stop) {
+    arr.push(42);
+  }
+}
+//# sourceURL=test.js`, 10, 26);
+
+Protocol.Debugger.onPaused((message) => {
+  InspectorTest.log(`reason: ${message.params.reason}`);
+  Protocol.Debugger.evaluateOnCallFrame({
+    callFrameId: message.params.callFrames[0].callFrameId,
+    expression: 'arr = []; stop = true;'
+  }).then(() => Protocol.Debugger.resume());
+});
+Protocol.Debugger.enable();
+Protocol.Runtime.evaluate({ expression: 'generateGarbage()' })
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/pause.js b/src/v8/test/inspector/debugger/pause.js
new file mode 100644
index 0000000..fdef666
--- /dev/null
+++ b/src/v8/test/inspector/debugger/pause.js
@@ -0,0 +1,118 @@
+// Copyright 2017 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.
+
+InspectorTest.log('Checks Debugger.pause');
+let contextGroup1 = new InspectorTest.ContextGroup();
+let session1 = contextGroup1.connect();
+let Protocol1 = session1.Protocol;
+
+session1.setupScriptMap();
+Protocol1.Debugger.enable();
+InspectorTest.runAsyncTestSuite([
+  async function testPause() {
+    Protocol1.Debugger.pause();
+    Protocol1.Runtime.evaluate({expression: 'var a = 42;'});
+    await waitPauseAndDumpLocation(session1);
+    await Protocol1.Debugger.resume();
+  },
+
+  async function testSkipFrameworks() {
+    Protocol1.Debugger.setBlackboxPatterns({patterns: ['framework\.js']});
+    Protocol1.Debugger.pause();
+    Protocol1.Runtime.evaluate({expression: 'var a = 42; //# sourceURL=framework.js'});
+    Protocol1.Runtime.evaluate({expression: 'var a = 239;'});
+    await waitPauseAndDumpLocation(session1);
+    await Protocol1.Debugger.resume();
+  },
+
+  async function testSkipOtherContext1() {
+    let contextGroup2 = new InspectorTest.ContextGroup();
+    let session2 = contextGroup2.connect();
+    let Protocol2 = session2.Protocol;
+    Protocol2.Debugger.enable({});
+    Protocol1.Debugger.pause();
+    Protocol1.Runtime.evaluate({expression: 'var a = 42; //# sourceURL=framework.js'});
+    Protocol2.Runtime.evaluate({expression: 'var a = 239;'});
+    Protocol1.Runtime.evaluate({expression: 'var a = 1;'});
+    await waitPauseAndDumpLocation(session1);
+    await Protocol1.Debugger.resume();
+    await Protocol2.Debugger.disable({});
+  },
+
+  async function testSkipOtherContext2() {
+    let contextGroup2 = new InspectorTest.ContextGroup();
+    let session2 = contextGroup2.connect();
+    let Protocol2 = session2.Protocol;
+    session2.setupScriptMap();
+    Protocol2.Debugger.enable({});
+    Protocol2.Debugger.pause({});
+    Protocol1.Runtime.evaluate({expression: 'var a = 42; //# sourceURL=framework.js'});
+    Protocol2.Runtime.evaluate({expression: 'var a = 239;'});
+    Protocol1.Runtime.evaluate({expression: 'var a = 1;'});
+    await waitPauseAndDumpLocation(session2);
+    // should not resume pause from different context group id.
+    Protocol1.Debugger.resume();
+    Protocol2.Debugger.stepOver({});
+    await waitPauseAndDumpLocation(session2);
+    await Protocol2.Debugger.resume({});
+    await Protocol2.Debugger.disable({});
+  },
+
+  async function testWithNativeBreakpoint() {
+    contextGroup1.schedulePauseOnNextStatement('', '');
+    await Protocol1.Debugger.pause();
+    contextGroup1.cancelPauseOnNextStatement();
+    Protocol1.Runtime.evaluate({expression: 'var a = 42;'});
+    await waitPauseAndDumpLocation(session1);
+    await Protocol1.Debugger.resume();
+
+    await Protocol1.Debugger.pause();
+    contextGroup1.schedulePauseOnNextStatement('', '');
+    contextGroup1.cancelPauseOnNextStatement();
+    Protocol1.Runtime.evaluate({expression: 'var a = 42;'});
+    await waitPauseAndDumpLocation(session1);
+    await Protocol1.Debugger.resume();
+
+    contextGroup1.schedulePauseOnNextStatement('', '');
+    contextGroup1.cancelPauseOnNextStatement();
+    await Protocol1.Debugger.pause();
+    Protocol1.Runtime.evaluate({expression: 'var a = 42;'});
+    await waitPauseAndDumpLocation(session1);
+    await Protocol1.Debugger.resume();
+  },
+
+  async function testResumeAnotherGroup() {
+    let contextGroup2 = new InspectorTest.ContextGroup();
+    let session2 = contextGroup2.connect();
+    session2.setupScriptMap();
+    let Protocol2 = session2.Protocol;
+    Protocol2.Debugger.enable();
+    Protocol1.Debugger.pause();
+    Protocol1.Runtime.evaluate({expression: 'var a = 42;'});
+    await waitPauseAndDumpLocation(session1);
+    InspectorTest.logMessage(await Protocol2.Debugger.resume());
+    InspectorTest.logMessage(await Protocol2.Debugger.stepOver());
+    InspectorTest.logMessage(await Protocol2.Debugger.stepInto());
+    InspectorTest.logMessage(await Protocol2.Debugger.stepOut());
+    await Protocol1.Debugger.resume();
+    await Protocol2.Debugger.disable();
+  },
+
+  async function testDisableBreaksShouldCancelPause() {
+    await Protocol1.Debugger.pause();
+    await Protocol1.Debugger.setBreakpointsActive({active: false});
+    Protocol1.Runtime.evaluate({expression: 'var a = 42;'})
+      .then(() => Protocol1.Debugger.setBreakpointsActive({active: true}))
+      .then(() => Protocol1.Runtime.evaluate({expression: 'debugger'}));
+    await waitPauseAndDumpLocation(session1);
+    await Protocol1.Debugger.resume();
+  }
+]);
+
+async function waitPauseAndDumpLocation(session) {
+  var message = await session.Protocol.Debugger.oncePaused();
+  InspectorTest.log('paused at:');
+  await session.logSourceLocation(message.params.callFrames[0].location);
+  return message;
+}
diff --git a/src/v8/test/inspector/debugger/promise-chain-when-limit-hit-expected.txt b/src/v8/test/inspector/debugger/promise-chain-when-limit-hit-expected.txt
new file mode 100644
index 0000000..57357ab
--- /dev/null
+++ b/src/v8/test/inspector/debugger/promise-chain-when-limit-hit-expected.txt
@@ -0,0 +1,235 @@
+Tests how async promise chains behave when reaching the limit of stacks
+Checks correctness of promise chains when limit hit
+inspector.setMaxAsyncTaskStacks(3)
+Run expression 'console.trace()' with async chain len: 3
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.trace
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 67
+                    functionName : Promise.resolve.then.then.then
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+            parent : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 46
+                        functionName : 
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+        }
+        timestamp : <timestamp>
+        type : trace
+    }
+}
+inspector.setMaxAsyncTaskStacks(4)
+Run expression 'console.trace()' with async chain len: 3
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.trace
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 67
+                    functionName : Promise.resolve.then.then.then
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+            parent : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 46
+                        functionName : 
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+                description : Promise.resolve
+            }
+        }
+        timestamp : <timestamp>
+        type : trace
+    }
+}
+inspector.setMaxAsyncTaskStacks(5)
+Run expression 'console.trace()' with async chain len: 3
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.trace
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 67
+                    functionName : Promise.resolve.then.then.then
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+            parent : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 46
+                        functionName : 
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+                description : Promise.resolve
+            }
+        }
+        timestamp : <timestamp>
+        type : trace
+    }
+}
+inspector.setMaxAsyncTaskStacks(6)
+Run expression 'console.trace()' with async chain len: 3
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.trace
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 67
+                    functionName : Promise.resolve.then.then.then
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+            parent : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 46
+                        functionName : 
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+                description : Promise.resolve
+            }
+        }
+        timestamp : <timestamp>
+        type : trace
+    }
+}
+inspector.setMaxAsyncTaskStacks(7)
+Run expression 'console.trace()' with async chain len: 3
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.trace
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 67
+                    functionName : Promise.resolve.then.then.then
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+            parent : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 46
+                        functionName : 
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+                description : Promise.resolve
+            }
+        }
+        timestamp : <timestamp>
+        type : trace
+    }
+}
+inspector.setMaxAsyncTaskStacks(8)
+Run expression 'console.trace()' with async chain len: 3
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.trace
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 67
+                    functionName : Promise.resolve.then.then.then
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+            parent : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 46
+                        functionName : 
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+                description : Promise.resolve
+            }
+        }
+        timestamp : <timestamp>
+        type : trace
+    }
+}
diff --git a/src/v8/test/inspector/debugger/promise-chain-when-limit-hit.js b/src/v8/test/inspector/debugger/promise-chain-when-limit-hit.js
new file mode 100644
index 0000000..072af73
--- /dev/null
+++ b/src/v8/test/inspector/debugger/promise-chain-when-limit-hit.js
@@ -0,0 +1,54 @@
+// Copyright 2017 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.
+
+// TODO(kozyatinskiy): fix or remove it later.
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests how async promise chains behave when reaching the limit of stacks');
+
+(async function test(){
+  InspectorTest.log('Checks correctness of promise chains when limit hit');
+  await Protocol.Runtime.enable();
+  await Protocol.Debugger.enable();
+  Protocol.Debugger.setAsyncCallStackDepth({maxDepth: 128});
+
+  await setMaxAsyncTaskStacks(3);
+  runWithAsyncChainPromise(3, 'console.trace()');
+  InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+
+  await setMaxAsyncTaskStacks(4);
+  runWithAsyncChainPromise(3, 'console.trace()');
+  InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+
+  await setMaxAsyncTaskStacks(5);
+  runWithAsyncChainPromise(3, 'console.trace()');
+  InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+
+  await setMaxAsyncTaskStacks(6);
+  runWithAsyncChainPromise(3, 'console.trace()');
+  InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+
+  await setMaxAsyncTaskStacks(7);
+  runWithAsyncChainPromise(3, 'console.trace()');
+  InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+
+  await setMaxAsyncTaskStacks(8);
+  runWithAsyncChainPromise(3, 'console.trace()');
+  InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+
+  InspectorTest.completeTest();
+})();
+
+function runWithAsyncChainPromise(len, source) {
+  InspectorTest.log(`Run expression '${source}' with async chain len: ${len}`);
+  let then = '.then(() => 1)';
+  let pause = `.then(() => { ${source} })`;
+  Protocol.Runtime.evaluate({
+    expression: `Promise.resolve()${then.repeat(len - 1)}${pause}`
+  });
+}
+
+async function setMaxAsyncTaskStacks(max) {
+  let expression = `inspector.setMaxAsyncTaskStacks(${max})`;
+  InspectorTest.log(expression);
+  await Protocol.Runtime.evaluate({expression});
+}
diff --git a/src/v8/test/inspector/debugger/protocol-string-to-double-locale-expected.txt b/src/v8/test/inspector/debugger/protocol-string-to-double-locale-expected.txt
new file mode 100644
index 0000000..52919c1
--- /dev/null
+++ b/src/v8/test/inspector/debugger/protocol-string-to-double-locale-expected.txt
@@ -0,0 +1,8 @@
+Tests that double numbers are parsed and serialized correctly on different locales
+This test verifies that we correctly parse doubles with non-US locale
+{
+    a : 0.5
+}
+{
+    a : 1
+}
diff --git a/src/v8/test/inspector/debugger/protocol-string-to-double-locale.js b/src/v8/test/inspector/debugger/protocol-string-to-double-locale.js
new file mode 100644
index 0000000..89b6d82
--- /dev/null
+++ b/src/v8/test/inspector/debugger/protocol-string-to-double-locale.js
@@ -0,0 +1,24 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that double numbers are parsed and serialized correctly on different locales');
+
+(async function() {
+  InspectorTest.log('This test verifies that we correctly parse doubles with non-US locale');
+  utils.setlocale("fr_CA.UTF-8");
+  Protocol.Debugger.enable();
+  Protocol.Runtime.evaluate({
+    expression: 'inspector.breakProgram(\'\', JSON.stringify({a: 0.5}))'});
+  let message = await Protocol.Debugger.oncePaused();
+  InspectorTest.logObject(message.params.data || {});
+  Protocol.Debugger.resume();
+
+  Protocol.Runtime.evaluate({
+    expression: 'inspector.breakProgram(\'\', JSON.stringify({a: 1}))'});
+  message = await Protocol.Debugger.oncePaused();
+  InspectorTest.logObject(message.params.data || {});
+  Protocol.Debugger.resume();
+
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/debugger/resources/break-locations.js b/src/v8/test/inspector/debugger/resources/break-locations.js
new file mode 100644
index 0000000..c16ae67
--- /dev/null
+++ b/src/v8/test/inspector/debugger/resources/break-locations.js
@@ -0,0 +1,269 @@
+// Copyright 2017 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.
+
+function testEval() {
+  eval('// comment only');
+  eval('// comment only\n');
+}
+
+// function without return
+function procedure() {
+  var a = 1;
+  var b = 2;
+}
+
+function testProcedure() {
+  procedure();
+}
+
+function returnTrue() {
+  return true;
+}
+
+function testIf() {
+  var a;
+  if (true) a = true;
+  if (!a) {
+    a = true;
+  } else {
+    a = false;
+  }
+  if (returnTrue()) {
+    a = false;
+  } else {
+    a = true;
+  }
+}
+
+function emptyFunction() {}
+
+function testEmptyFunction() {
+  emptyFunction();
+}
+
+function twoArguments(a1, a2) {
+}
+
+function testCallArguments() {
+  twoArguments(emptyFunction(), emptyFunction());
+}
+
+function testNested() {
+  function nested1() {
+    function nested2() {
+      function nested3() {
+      }
+      nested3();
+      return;
+    }
+    return nested2();
+  }
+  nested1();
+}
+
+function return42() {
+  return 42;
+}
+
+function returnCall() {
+  return return42();
+}
+
+function testCallAtReturn() {
+  return returnCall();
+}
+
+function returnObject() {
+  return ({ foo: () => 42 });
+}
+
+function testWith() {
+  with (returnObject()) {
+    foo();
+  }
+  with({}) {
+    return;
+  }
+}
+
+function testForLoop() {
+  for (var i = 0; i < 1; ++i) {}
+  for (var i = 0; i < 1; ++i) i;
+  for (var i = 0; i < 0; ++i) {}
+}
+
+function testForOfLoop() {
+  for (var k of []) {}
+  for (var k of [1]) k;
+  var a = [];
+  for (var k of a) {}
+}
+
+function testForInLoop() {
+  var o = {};
+  for (var k in o) {}
+  for (var k in o) k;
+  for (var k in { a:1 }) {}
+  for (var k in { a:1 }) k;
+}
+
+function testSimpleExpressions() {
+  1 + 2 + 3;
+  var a = 1;
+  ++a;
+  a--;
+}
+
+Object.defineProperty(this, 'getterFoo', {
+  get: () => return42
+});
+
+function testGetter() {
+  getterFoo();
+}
+
+var obj = {
+  foo: () => ({
+    boo: () => return42
+  })
+};
+
+function testChainedCalls() {
+  obj.foo().boo()();
+}
+
+function testChainedWithNative() {
+  Array.from([1]).concat([2]).map(v => v * 2);
+}
+
+function testPromiseThen() {
+  return Promise.resolve().then(v => v * 2).then(v => v * 2);
+}
+
+function testSwitch() {
+  for (var i = 0; i < 3; ++i) {
+    switch(i) {
+      case 0: continue;
+      case 1: return42(); break;
+      default: return;
+    }
+  }
+}
+
+function* idMaker() {
+  yield 1;
+  yield 2;
+  yield 3;
+}
+
+function testGenerator() {
+  var gen = idMaker();
+  return42();
+  gen.next().value;
+  debugger;
+  gen.next().value;
+  return42();
+  gen.next().value;
+  return42();
+  gen.next().value;
+}
+
+function throwException() {
+  throw new Error();
+}
+
+function testCaughtException() {
+  try {
+    throwException()
+  } catch (e) {
+    return;
+  }
+}
+
+function testClasses() {
+  class Cat {
+    constructor(name) {
+      this.name = name;
+    }
+
+    speak() {
+    }
+  }
+  class Lion extends Cat {
+    constructor(name) {
+      super(name);
+    }
+
+    speak() {
+      super.speak();
+    }
+  }
+  new Lion().speak();
+}
+
+async function asyncFoo() {
+  await Promise.resolve().then(v => v * 2);
+  return42();
+  await asyncBoo();
+}
+
+async function asyncBoo() {
+  await Promise.resolve();
+}
+
+async function testAsyncAwait() {
+  await asyncFoo();
+  await awaitBoo();
+}
+
+// TODO(kozyatinskiy): fix this.
+async function testPromiseAsyncWithCode() {
+  var nextTest;
+  var testPromise = new Promise(resolve => nextTest = resolve);
+  async function main() {
+    async function foo() {
+      var resolveNested;
+      var p = new Promise(resolve => resolveNested = resolve);
+      setTimeout(resolveNested, 0);
+      await p;
+    }
+    setTimeout(returnCall, 0);
+    await foo();
+    await foo();
+    nextTest();
+  }
+  main();
+  return testPromise;
+}
+
+function returnFunction() {
+  return returnObject;
+}
+
+async function testPromiseComplex() {
+  var nextTest;
+  var testPromise = new Promise(resolve => nextTest = resolve);
+  async function main() {
+    async function foo() {
+      await Promise.resolve();
+      return 42;
+    }
+    var x = 1;
+    var y = 2;
+    returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 *a)(5));
+    nextTest();
+  }
+  main();
+  return testPromise;
+}
+
+function twiceDefined() {
+  return a + b;
+}
+
+function twiceDefined() {
+  return a + b;
+}
+
+//# sourceURL=break-locations.js
diff --git a/src/v8/test/inspector/debugger/restore-breakpoint-expected.txt b/src/v8/test/inspector/debugger/restore-breakpoint-expected.txt
new file mode 100644
index 0000000..ac23487
--- /dev/null
+++ b/src/v8/test/inspector/debugger/restore-breakpoint-expected.txt
@@ -0,0 +1,76 @@
+Checks that debugger agent uses source content to restore breakpoints.
+
+Running test: testSameSource
+function foo() {
+#boo();
+}
+function foo() {
+#boo();
+}
+
+Running test: testOneLineOffset
+function foo() {
+#boo();
+}
+function foo() {
+#boo();
+boo();
+}
+
+Running test: testTwoSimilarLinesCloseToOriginalLocation1
+function foo() {
+
+
+#boo();
+}
+function foo() {
+#boo();
+
+newCode();
+boo();
+
+
+
+boo();
+}
+
+Running test: testTwoSimilarLinesCloseToOriginalLocation2
+function foo() {
+
+
+#boo();
+}
+function foo() {
+boo();
+newLongCode();
+newCode();
+#boo();
+
+
+
+boo();
+}
+
+Running test: testHintIgnoreWhiteSpaces
+function foo() {
+
+
+
+#boo();
+}
+function foo() {
+foo();
+
+
+#boo();
+}
+
+Running test: testCheckOnlyLimitedOffsets
+function foo() {
+#boo();
+}
+function foo() {
+#newCode();
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;...
+boo();
+}
diff --git a/src/v8/test/inspector/debugger/restore-breakpoint.js b/src/v8/test/inspector/debugger/restore-breakpoint.js
new file mode 100644
index 0000000..e0d2b84
--- /dev/null
+++ b/src/v8/test/inspector/debugger/restore-breakpoint.js
@@ -0,0 +1,69 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that debugger agent uses source content to restore breakpoints.');
+
+Protocol.Debugger.enable();
+InspectorTest.runTestSuite([
+  function testSameSource(next) {
+    var source = 'function foo() {\nboo();\n}';
+    test(source, source, { lineNumber: 1, columnNumber: 0 }, next);
+  },
+
+  function testOneLineOffset(next) {
+    var source = 'function foo() {\nboo();\n}';
+    var newSource = 'function foo() {\nboo();\nboo();\n}';
+    test(source, newSource, { lineNumber: 1, columnNumber: 0 }, next);
+  },
+
+  function testTwoSimilarLinesCloseToOriginalLocation1(next) {
+    var source = 'function foo() {\n\n\nboo();\n}';
+    var newSource = 'function foo() {\nboo();\n\nnewCode();\nboo();\n\n\n\nboo();\n}';
+    test(source, newSource, { lineNumber: 3, columnNumber: 0 }, next);
+  },
+
+  function testTwoSimilarLinesCloseToOriginalLocation2(next) {
+    var source = 'function foo() {\n\n\nboo();\n}';
+    var newSource = 'function foo() {\nboo();\nnewLongCode();\nnewCode();\nboo();\n\n\n\nboo();\n}';
+    test(source, newSource, { lineNumber: 3, columnNumber: 0 }, next);
+  },
+
+  function testHintIgnoreWhiteSpaces(next) {
+    var source = 'function foo() {\n\n\n\nboo();\n}';
+    var newSource = 'function foo() {\nfoo();\n\n\nboo();\n}';
+    test(source, newSource, { lineNumber: 1, columnNumber: 0 }, next);
+  },
+
+  function testCheckOnlyLimitedOffsets(next) {
+    var source = 'function foo() {\nboo();\n}';
+    var longString = ';'.repeat(1000);
+    var newSource = `function foo() {\nnewCode();\n${longString};\nboo();\n}`;
+    test(source, newSource, { lineNumber: 1, columnNumber: 0 }, next);
+  }
+]);
+
+var finishedTests = 0;
+async function test(source, newSource, location, next) {
+  var firstBreakpoint = true;
+  Protocol.Debugger.onBreakpointResolved(message => {
+    var lineNumber = message.params.location.lineNumber;
+    var columnNumber = message.params.location.columnNumber;
+    var currentSource = firstBreakpoint ? source : newSource;
+    var lines = currentSource.split('\n');
+    lines = lines.map(line => line.length > 80 ? line.substring(0, 77) + '...' : line);
+    lines[lineNumber] = lines[lineNumber].slice(0, columnNumber) + '#' + lines[lineNumber].slice(columnNumber);
+    InspectorTest.log(lines.join('\n'));
+    firstBreakpoint = false;
+  });
+
+  var sourceURL = `test${++finishedTests}.js`;
+  await Protocol.Debugger.setBreakpointByUrl({
+    url: sourceURL,
+    lineNumber: location.lineNumber,
+    columnNumber: location.columnNumber
+  });
+  await Protocol.Runtime.evaluate({ expression: `${source}\n//# sourceURL=${sourceURL}` });
+  await Protocol.Runtime.evaluate({ expression: `${newSource}\n//# sourceURL=${sourceURL}` });
+  next();
+}
diff --git a/src/v8/test/inspector/debugger/return-break-locations-expected.txt b/src/v8/test/inspector/debugger/return-break-locations-expected.txt
new file mode 100644
index 0000000..688faf8
--- /dev/null
+++ b/src/v8/test/inspector/debugger/return-break-locations-expected.txt
@@ -0,0 +1,29 @@
+Return break locations within function
+
+Running test: testTailCall
+[
+    [0] : {
+        columnNumber : 20
+        lineNumber : 2
+        scriptId : <scriptId>
+        type : return
+    }
+    [1] : {
+        columnNumber : 24
+        lineNumber : 3
+        scriptId : <scriptId>
+        type : return
+    }
+    [2] : {
+        columnNumber : 29
+        lineNumber : 4
+        scriptId : <scriptId>
+        type : return
+    }
+    [3] : {
+        columnNumber : 59
+        lineNumber : 5
+        scriptId : <scriptId>
+        type : return
+    }
+]
diff --git a/src/v8/test/inspector/debugger/return-break-locations.js b/src/v8/test/inspector/debugger/return-break-locations.js
new file mode 100644
index 0000000..b253b88
--- /dev/null
+++ b/src/v8/test/inspector/debugger/return-break-locations.js
@@ -0,0 +1,26 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Return break locations within function');
+
+contextGroup.addScript(`
+function fib(x) {
+  if (x < 0) return;
+  if (x === 0) return 1;
+  if (x === 1) return fib(0);
+  return x > 2 ? fib(x - 1) + fib(x - 2) : fib(1) + fib(0);
+}
+`);
+
+InspectorTest.runAsyncTestSuite([
+  async function testTailCall() {
+    var scriptPromise = Protocol.Debugger.onceScriptParsed();
+    Protocol.Debugger.enable();
+    var scriptId = (await scriptPromise).params.scriptId;
+    var locations = (await Protocol.Debugger.getPossibleBreakpoints({
+      start: { lineNumber: 0, columnNumber: 0, scriptId }
+    })).result.locations;
+    InspectorTest.logMessage(locations.filter(location => location.type === 'return'));
+  }
+]);
diff --git a/src/v8/test/inspector/debugger/schedule-step-into-async-expected.txt b/src/v8/test/inspector/debugger/schedule-step-into-async-expected.txt
new file mode 100644
index 0000000..be3cad1
--- /dev/null
+++ b/src/v8/test/inspector/debugger/schedule-step-into-async-expected.txt
@@ -0,0 +1,191 @@
+Checks Debugger.scheduleStepIntoAsync.
+
+Running test: testScheduleErrors
+paused at:
+function testNoScheduledTask() {
+  #debugger;
+  return 42;
+
+{
+    error : {
+        code : -32000
+        message : Current scheduled step into async was overriden with new one.
+    }
+    id : <messageId>
+}
+{
+    error : {
+        code : -32000
+        message : No async tasks were scheduled before pause.
+    }
+    id : <messageId>
+}
+paused at:
+  debugger;
+  #return 42;
+}
+
+
+Running test: testSimple
+paused at:
+function testSimple() {
+  #debugger;
+  Promise.resolve().then(v => v * 2);
+
+paused at:
+  debugger;
+  #Promise.resolve().then(v => v * 2);
+}
+
+{
+    id : <messageId>
+    result : {
+    }
+}
+paused at:
+  debugger;
+  Promise.resolve().then(#v => v * 2);
+}
+
+
+Running test: testNotResolvedPromise
+paused at:
+  var p = new Promise(resolve => resolveCallback = resolve);
+  #debugger;
+  p.then(v => v * 2);
+
+paused at:
+  debugger;
+  p.#then(v => v * 2);
+  resolveCallback();
+
+{
+    id : <messageId>
+    result : {
+    }
+}
+paused at:
+  debugger;
+  p.then(#v => v * 2);
+  resolveCallback();
+
+
+Running test: testTwoAsyncTasks
+paused at:
+function testTwoAsyncTasks() {
+  #debugger;
+  Promise.resolve().then(v => v * 2);
+
+{
+    id : <messageId>
+    result : {
+    }
+}
+paused at:
+  debugger;
+  Promise.resolve().then(#v => v * 2);
+  Promise.resolve().then(v => v * 4);
+
+
+Running test: testTwoTasksAndGoToSecond
+paused at:
+function testTwoAsyncTasks() {
+  #debugger;
+  Promise.resolve().then(v => v * 2);
+
+paused at:
+  debugger;
+  #Promise.resolve().then(v => v * 2);
+  Promise.resolve().then(v => v * 4);
+
+paused at:
+  Promise.resolve().then(v => v * 2);
+  #Promise.resolve().then(v => v * 4);
+}
+
+{
+    id : <messageId>
+    result : {
+    }
+}
+paused at:
+  Promise.resolve().then(v => v * 2);
+  Promise.resolve().then(#v => v * 4);
+}
+
+
+Running test: testTwoAsyncTasksWithBreak
+paused at:
+function testTwoAsyncTasksWithBreak() {
+  #debugger;
+  Promise.resolve().then(v => v * 2);
+
+paused at:
+  debugger;
+  #Promise.resolve().then(v => v * 2);
+  debugger;
+
+{
+    id : <messageId>
+    result : {
+    }
+}
+paused at:
+  Promise.resolve().then(v => v * 2);
+  #debugger;
+  Promise.resolve().then(v => v * 4);
+
+{
+    id : <messageId>
+    result : {
+    }
+}
+paused at:
+  debugger;
+  Promise.resolve().then(#v => v * 4);
+}
+
+
+Running test: testPromiseAll
+paused at:
+function testPromiseAll() {
+  #debugger;
+  Promise.all([ Promise.resolve(), Promise.resolve() ]).then(v => v * 2);
+
+paused at:
+  debugger;
+  #Promise.all([ Promise.resolve(), Promise.resolve() ]).then(v => v * 2);
+}
+
+{
+    id : <messageId>
+    result : {
+    }
+}
+paused at:
+  debugger;
+  Promise.all([ Promise.resolve(), Promise.resolve() ]).then(#v => v * 2);
+}
+
+
+Running test: testWithBlackboxedCode
+paused at:
+function testBlackboxedCreatePromise() {
+  #debugger;
+  createPromise().then(v => v * 2);
+
+paused at:
+  debugger;
+  #createPromise().then(v => v * 2);
+}
+
+{
+    id : <messageId>
+    result : {
+    }
+}
+paused at:
+  debugger;
+  createPromise().then(#v => v * 2);
+}
+
diff --git a/src/v8/test/inspector/debugger/schedule-step-into-async-set-timeout-expected.txt b/src/v8/test/inspector/debugger/schedule-step-into-async-set-timeout-expected.txt
new file mode 100644
index 0000000..afcc5e3
--- /dev/null
+++ b/src/v8/test/inspector/debugger/schedule-step-into-async-set-timeout-expected.txt
@@ -0,0 +1,45 @@
+Checks Debugger.scheduleStepIntoAsync with setTimeout.
+
+Running test: testSetTimeout
+paused at:
+debugger; #setTimeout(() => 1, 0);
+
+paused at:
+debugger; setTimeout(#() => 1, 0);
+
+
+Running test: testDebuggerStmtBeforeCallback1
+paused at:
+debugger; #setTimeout(() => 1, 0);debugger;
+
+paused at:
+debugger; setTimeout(() => 1, 0);#debugger;
+
+paused at:
+#debugger//should-break-here
+
+
+Running test: testDebuggerStmtBeforeCallback2
+paused at:
+debugger; setTimeout(() => 1#, 0);debugger;
+
+paused at:
+#debugger//should-break-here
+
+
+Running test: testSetTimeoutWithoutJS
+paused at:
+debugger; #setTimeout('}', 0);
+setTimeout('var a = 239;', 0);
+
+paused at:
+#debugger//should-break-here
+
+
+Running test: testResume
+paused at:
+#setTimeout(() => 42, 0)
+
+paused at:
+setTimeout(#() => 42, 0)
+
diff --git a/src/v8/test/inspector/debugger/schedule-step-into-async-set-timeout.js b/src/v8/test/inspector/debugger/schedule-step-into-async-set-timeout.js
new file mode 100644
index 0000000..f2171a5
--- /dev/null
+++ b/src/v8/test/inspector/debugger/schedule-step-into-async-set-timeout.js
@@ -0,0 +1,75 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks Debugger.scheduleStepIntoAsync with setTimeout.');
+session.setupScriptMap();
+Protocol.Debugger.enable();
+InspectorTest.runAsyncTestSuite([
+  async function testSetTimeout() {
+    Protocol.Runtime.evaluate({expression: 'debugger; setTimeout(() => 1, 0);'});
+    await Protocol.Debugger.oncePaused();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testDebuggerStmtBeforeCallback1() {
+    Protocol.Runtime.evaluate({expression: 'debugger; setTimeout(() => 1, 0);debugger;'});
+    Protocol.Runtime.evaluate({expression: 'setTimeout(\'debugger//should-break-here\', 0)'});
+    await Protocol.Debugger.oncePaused();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testDebuggerStmtBeforeCallback2() {
+    Protocol.Runtime.evaluate({expression: 'debugger;\nsetTimeout(\'debugger//should-break-here\', 0);\nsetTimeout(() => 1, 0);'});
+    await Protocol.Debugger.oncePaused();
+    Protocol.Debugger.stepOver();
+    await Protocol.Debugger.oncePaused();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+    await InspectorTest.waitForPendingTasks();
+  },
+
+  async function testSetTimeoutWithoutJS() {
+    Protocol.Runtime.evaluate({expression: 'debugger; setTimeout(\'}\', 0);\nsetTimeout(\'var a = 239;\', 0);\nsetTimeout(\'debugger//should-break-here\', 0);'});
+    await Protocol.Debugger.oncePaused();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testResume() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: 'setTimeout(() => 42, 0)'});
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync();
+    Protocol.Debugger.resume();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+  }
+]);
+
+async function waitPauseAndDumpLocation() {
+  var message = await Protocol.Debugger.oncePaused();
+  InspectorTest.log('paused at:');
+  await session.logSourceLocation(message.params.callFrames[0].location);
+  return message;
+}
diff --git a/src/v8/test/inspector/debugger/schedule-step-into-async.js b/src/v8/test/inspector/debugger/schedule-step-into-async.js
new file mode 100644
index 0000000..c4dfb73
--- /dev/null
+++ b/src/v8/test/inspector/debugger/schedule-step-into-async.js
@@ -0,0 +1,159 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks Debugger.scheduleStepIntoAsync.');
+
+contextGroup.addScript(`
+function testNoScheduledTask() {
+  debugger;
+  return 42;
+}
+
+function testSimple() {
+  debugger;
+  Promise.resolve().then(v => v * 2);
+}
+
+function testNotResolvedPromise() {
+  var resolveCallback;
+  var p = new Promise(resolve => resolveCallback = resolve);
+  debugger;
+  p.then(v => v * 2);
+  resolveCallback();
+}
+
+function testTwoAsyncTasks() {
+  debugger;
+  Promise.resolve().then(v => v * 2);
+  Promise.resolve().then(v => v * 4);
+}
+
+function testTwoAsyncTasksWithBreak() {
+  debugger;
+  Promise.resolve().then(v => v * 2);
+  debugger;
+  Promise.resolve().then(v => v * 4);
+}
+
+function testPromiseAll() {
+  debugger;
+  Promise.all([ Promise.resolve(), Promise.resolve() ]).then(v => v * 2);
+}
+
+function testBlackboxedCreatePromise() {
+  debugger;
+  createPromise().then(v => v * 2);
+}
+//# sourceURL=test.js`);
+
+contextGroup.addScript(`
+
+function createPromise() {
+  return Promise.resolve().then(v => v * 3).then(v => v * 4);
+}
+
+//# sourceURL=framework.js`)
+
+session.setupScriptMap();
+
+Protocol.Debugger.enable();
+InspectorTest.runAsyncTestSuite([
+  async function testScheduleErrors() {
+    Protocol.Runtime.evaluate({ expression: 'testNoScheduledTask()' });
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync().then(InspectorTest.logMessage);
+    Protocol.Debugger.scheduleStepIntoAsync().then(InspectorTest.logMessage);
+    Protocol.Debugger.stepInto();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testSimple() {
+    Protocol.Runtime.evaluate({ expression: 'testSimple()' });
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync().then(InspectorTest.logMessage);
+    Protocol.Debugger.stepInto();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testNotResolvedPromise() {
+    Protocol.Runtime.evaluate({ expression: 'testNotResolvedPromise()' });
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync().then(InspectorTest.logMessage);
+    Protocol.Debugger.stepInto();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testTwoAsyncTasks() {
+    Protocol.Runtime.evaluate({ expression: 'testTwoAsyncTasks()' });
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync().then(InspectorTest.logMessage);
+    Protocol.Debugger.resume();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testTwoTasksAndGoToSecond() {
+    Protocol.Runtime.evaluate({ expression: 'testTwoAsyncTasks()' });
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync().then(InspectorTest.logMessage);
+    Protocol.Debugger.resume();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testTwoAsyncTasksWithBreak() {
+    Protocol.Runtime.evaluate({ expression: 'testTwoAsyncTasksWithBreak()' });
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync().then(InspectorTest.logMessage);
+    Protocol.Debugger.resume();
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync().then(InspectorTest.logMessage);
+    Protocol.Debugger.resume();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testPromiseAll() {
+    Protocol.Runtime.evaluate({ expression: 'testPromiseAll()' });
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.scheduleStepIntoAsync().then(InspectorTest.logMessage);
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+  },
+
+  async function testWithBlackboxedCode() {
+    Protocol.Runtime.evaluate({ expression: 'testBlackboxedCreatePromise()' });
+    await waitPauseAndDumpLocation();
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js'] });
+    Protocol.Debugger.scheduleStepIntoAsync().then(InspectorTest.logMessage);
+    Protocol.Debugger.stepOver();
+    await waitPauseAndDumpLocation();
+    await Protocol.Debugger.resume();
+  }
+]);
+
+async function waitPauseAndDumpLocation() {
+  var message = await Protocol.Debugger.oncePaused();
+  InspectorTest.log('paused at:');
+  session.logSourceLocation(message.params.callFrames[0].location);
+  return message;
+}
diff --git a/src/v8/test/inspector/debugger/scope-skip-variables-with-empty-name-expected.txt b/src/v8/test/inspector/debugger/scope-skip-variables-with-empty-name-expected.txt
new file mode 100644
index 0000000..626f978
--- /dev/null
+++ b/src/v8/test/inspector/debugger/scope-skip-variables-with-empty-name-expected.txt
@@ -0,0 +1,20 @@
+Tests that scopes do not report variables with empty names
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : a
+                value : {
+                    description : 2
+                    type : number
+                    value : 2
+                }
+                writable : true
+            }
+        ]
+    }
+}
diff --git a/src/v8/test/inspector/debugger/scope-skip-variables-with-empty-name.js b/src/v8/test/inspector/debugger/scope-skip-variables-with-empty-name.js
new file mode 100644
index 0000000..72cbeee
--- /dev/null
+++ b/src/v8/test/inspector/debugger/scope-skip-variables-with-empty-name.js
@@ -0,0 +1,44 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that scopes do not report variables with empty names');
+
+contextGroup.addScript(
+`function testFunction()
+{
+    for (var a of [1]) {
+        ++a;
+        debugger;
+    }
+}`);
+
+Protocol.Debugger.enable();
+Protocol.Debugger.oncePaused().then(dumpScopeOnPause);
+Protocol.Runtime.evaluate({ "expression": "testFunction()" });
+
+var waitScopeObjects = 0;
+function dumpScopeOnPause(message)
+{
+  var scopeChain = message.params.callFrames[0].scopeChain;
+  var localScopeObjectIds = [];
+  for (var scope of scopeChain) {
+    if (scope.type === "local")
+      localScopeObjectIds.push(scope.object.objectId);
+  }
+  waitScopeObjects = localScopeObjectIds.length;
+  if (!waitScopeObjects) {
+    InspectorTest.completeTest();
+  } else {
+    for (var objectId of localScopeObjectIds)
+      Protocol.Runtime.getProperties({ "objectId" : objectId }).then(dumpProperties);
+  }
+}
+
+function dumpProperties(message)
+{
+  InspectorTest.logMessage(message);
+  --waitScopeObjects;
+  if (!waitScopeObjects)
+    Protocol.Debugger.resume().then(InspectorTest.completeTest);
+}
diff --git a/src/v8/test/inspector/debugger/script-end-location-expected.txt b/src/v8/test/inspector/debugger/script-end-location-expected.txt
new file mode 100644
index 0000000..3d0b480
--- /dev/null
+++ b/src/v8/test/inspector/debugger/script-end-location-expected.txt
@@ -0,0 +1,91 @@
+Checks that we report correct endLine, endColumn and source for scripts.
+{
+    compiled : {
+        endColumn : 0
+        endLine : 0
+    }
+    returned : {
+        endColumn : 0
+        endLine : 0
+    }
+}
+{
+    compiled : {
+        endColumn : 1
+        endLine : 0
+    }
+    returned : {
+        endColumn : 1
+        endLine : 0
+    }
+}
+{
+    compiled : {
+        endColumn : 2
+        endLine : 0
+    }
+    returned : {
+        endColumn : 2
+        endLine : 0
+    }
+}
+{
+    compiled : {
+        endColumn : 0
+        endLine : 1
+    }
+    returned : {
+        endColumn : 0
+        endLine : 1
+    }
+}
+{
+    compiled : {
+        endColumn : 1
+        endLine : 1
+    }
+    returned : {
+        endColumn : 1
+        endLine : 1
+    }
+}
+{
+    compiled : {
+        endColumn : 3
+        endLine : 1
+    }
+    returned : {
+        endColumn : 3
+        endLine : 1
+    }
+}
+{
+    compiled : {
+        endColumn : 0
+        endLine : 2
+    }
+    returned : {
+        endColumn : 0
+        endLine : 2
+    }
+}
+{
+    compiled : {
+        endColumn : 1
+        endLine : 2
+    }
+    returned : {
+        endColumn : 1
+        endLine : 2
+    }
+}
+{
+    compiled : {
+        endColumn : 2
+        endLine : 2
+    }
+    returned : {
+        endColumn : 2
+        endLine : 2
+    }
+}
diff --git a/src/v8/test/inspector/debugger/script-end-location.js b/src/v8/test/inspector/debugger/script-end-location.js
new file mode 100644
index 0000000..57d1235
--- /dev/null
+++ b/src/v8/test/inspector/debugger/script-end-location.js
@@ -0,0 +1,48 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that we report correct endLine, endColumn and source for scripts.');
+
+var sources = [
+'',
+' ',
+'  ',
+`
+`,
+`
+ `,
+`
+   `,
+`
+
+`,
+`
+
+ `,
+`
+
+  `];
+
+(async function test() {
+  Protocol.Debugger.enable();
+  for (let source of sources) {
+    contextGroup.addScript(source);
+    var message = await Protocol.Debugger.onceScriptParsed();
+    var inspectorSource = (await Protocol.Debugger.getScriptSource({ scriptId: message.params.scriptId })).result.scriptSource;
+    var lines = source.split('\n');
+    var returned = { endLine: message.params.endLine, endColumn: message.params.endColumn };
+    var compiled = { endLine: lines.length - 1, endColumn: lines[lines.length - 1].length };
+    InspectorTest.logObject({ returned, compiled });
+    if (returned.endLine != compiled.endLine) {
+      InspectorTest.log('error: incorrect endLine');
+    }
+    if (returned.endColumn != compiled.endColumn) {
+      InspectorTest.log('error: incorrect endColumn');
+    }
+    if (source !== inspectorSource) {
+      InspectorTest.log('error: incorrect source');
+    }
+  }
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/debugger/script-on-after-compile-expected.txt b/src/v8/test/inspector/debugger/script-on-after-compile-expected.txt
new file mode 100644
index 0000000..53e24c0
--- /dev/null
+++ b/src/v8/test/inspector/debugger/script-on-after-compile-expected.txt
@@ -0,0 +1,753 @@
+Checks that inspector correctly process compiled scripts
+scriptParsed
+{
+    scriptSource : function foo1(){}//# sourceURL=oneline.js<nl>
+}
+{
+    endColumn : 0
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : 2ACD11425BF645075D5696189A7BA7EB4048D6F7
+    isLiveEdit : false
+    isModule : false
+    length : 42
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : oneline.js
+}
+scriptParsed
+{
+    scriptSource : function foo2(){}//# sourceURL=oneline-without-nl.js
+}
+{
+    endColumn : 52
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : 0CD3C4132CE40E415D5696189A7BA7EB4048D6F7
+    isLiveEdit : false
+    isModule : false
+    length : 52
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : oneline-without-nl.js
+}
+scriptParsed
+{
+    scriptSource : function foo3(){}<nl>//# sourceURL=twoline.js<nl>
+}
+{
+    endColumn : 0
+    endLine : 2
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : 0E35E860580550805D5681F7BCD47D855B794EB3
+    isLiveEdit : false
+    isModule : false
+    length : 43
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : twoline.js
+}
+scriptParsed
+{
+    scriptSource : function foo4(){}<nl><nl>//# sourceURL=threeline.js<nl>
+}
+{
+    endColumn : 0
+    endLine : 3
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : AD4760425BF645075D5681F7D1786BD4DA9A86A7
+    isLiveEdit : false
+    isModule : false
+    length : 46
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : threeline.js
+}
+scriptParsed
+{
+    scriptSource : function foo5(){}//# sourceMappingURL=oneline-map<nl>
+}
+{
+    endColumn : 0
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 3E60CE61913387795D5696189A7BA7EB4048B715
+    isLiveEdit : false
+    isModule : false
+    length : 50
+    scriptId : <scriptId>
+    sourceMapURL : oneline-map
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo6(){}//# sourceMappingURL=oneline-without-nl-map
+}
+{
+    endColumn : 60
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 3E60CE617215C621E8825B319A7BA7EB4048B715
+    isLiveEdit : false
+    isModule : false
+    length : 60
+    scriptId : <scriptId>
+    sourceMapURL : oneline-without-nl-map
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo7(){}<nl>//# sourceMappingURL=twoline-map<nl>
+}
+{
+    endColumn : 0
+    endLine : 2
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : F2A32D219EFACBF470C48663BCD47D85864D1A22
+    isLiveEdit : false
+    isModule : false
+    length : 51
+    scriptId : <scriptId>
+    sourceMapURL : twoline-map
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo8(){}<nl><nl>//# sourceMappingURL=threeline-map<nl>
+}
+{
+    endColumn : 0
+    endLine : 3
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 46927EC1BFB78C355D5681F7D1786BD4216D5124
+    isLiveEdit : false
+    isModule : false
+    length : 54
+    scriptId : <scriptId>
+    sourceMapURL : threeline-map
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo9(){}//# sourceMappingURL=source-mapping-url-map<nl>//# sourceURL=source-url.js
+}
+{
+    endColumn : 27
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : 793E2411EDECF405E8825B31460F7CD9A656E096
+    isLiveEdit : false
+    isModule : false
+    length : 88
+    scriptId : <scriptId>
+    sourceMapURL : source-mapping-url-map
+    startColumn : 0
+    startLine : 0
+    url : source-url.js
+}
+scriptParsed
+{
+    scriptSource : function foo10(){}//# sourceURL=source-url.js<nl>//# sourceMappingURL=source-mapping-url-map
+}
+{
+    endColumn : 43
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : DED761235CC24EE21D0E9277CF599B5A292D8053
+    isLiveEdit : false
+    isModule : false
+    length : 89
+    scriptId : <scriptId>
+    sourceMapURL : source-mapping-url-map
+    startColumn : 0
+    startLine : 0
+    url : source-url.js
+}
+scriptParsed
+{
+    scriptSource : function foo11(){}<nl>//# sourceURL=end1.js
+}
+{
+    endColumn : 21
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : 9CF28A415BF64507692D5A84D1786BD4437C3511
+    isLiveEdit : false
+    isModule : false
+    length : 40
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : end1.js
+}
+scriptParsed
+{
+    scriptSource : function foo12(){}<nl>//# sourceURL=end2.js 
+}
+{
+    endColumn : 22
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : BEE49C625BF64507692D5A84D1786BD4437C3511
+    isLiveEdit : false
+    isModule : false
+    length : 41
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : end2.js
+}
+scriptParsed
+{
+    scriptSource : function foo13(){}
+}
+{
+    endColumn : 18
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 9CF28A415BF64507692D5A8443D429DC872EBA18
+    isLiveEdit : false
+    isModule : false
+    length : 18
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo15(){}; eval("function foo14(){}//# sourceURL=eval.js")//# sourceURL=eval-wrapper.js
+}
+{
+    endColumn : 96
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : D26251F019679C792E2B4EF437A20E96134D5C26
+    isLiveEdit : false
+    isModule : false
+    length : 96
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : eval-wrapper.js
+}
+scriptParsed
+{
+    scriptSource : function foo14(){}//# sourceURL=eval.js
+}
+{
+    endColumn : 39
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : 814AEF635BF64507692D5A84BCD47D85C4031CD2
+    isLiveEdit : false
+    isModule : false
+    length : 39
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : eval.js
+}
+scriptParsed
+{
+    scriptSource : function foo16(){}<nl>
+}
+{
+    endColumn : 0
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 9CF28A415BF64507692D5A84A8DC8126872EBA18
+    isLiveEdit : false
+    isModule : false
+    length : 19
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo17(){}<nl><nl>
+}
+{
+    endColumn : 0
+    endLine : 2
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 9CF28A415BF64507692D5A8443D429DC872EBA18
+    isLiveEdit : false
+    isModule : false
+    length : 20
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo18(){}<nl><nl><nl>
+}
+{
+    endColumn : 0
+    endLine : 3
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 9CF28A415BF64507692D5A84A8DC8126872EBA18
+    isLiveEdit : false
+    isModule : false
+    length : 21
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo19(){}<nl><nl><nl><nl>
+}
+{
+    endColumn : 0
+    endLine : 4
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 9CF28A415BF64507692D5A8443D429DC872EBA18
+    isLiveEdit : false
+    isModule : false
+    length : 22
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo1(){}//# sourceURL=oneline.js<nl>
+}
+{
+    endColumn : 0
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : 2ACD11425BF645075D5696189A7BA7EB4048D6F7
+    isLiveEdit : false
+    isModule : false
+    length : 42
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : oneline.js
+}
+scriptParsed
+{
+    scriptSource : function foo2(){}//# sourceURL=oneline-without-nl.js
+}
+{
+    endColumn : 52
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : 0CD3C4132CE40E415D5696189A7BA7EB4048D6F7
+    isLiveEdit : false
+    isModule : false
+    length : 52
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : oneline-without-nl.js
+}
+scriptParsed
+{
+    scriptSource : function foo3(){}<nl>//# sourceURL=twoline.js<nl>
+}
+{
+    endColumn : 0
+    endLine : 2
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : 0E35E860580550805D5681F7BCD47D855B794EB3
+    isLiveEdit : false
+    isModule : false
+    length : 43
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : twoline.js
+}
+scriptParsed
+{
+    scriptSource : function foo4(){}<nl><nl>//# sourceURL=threeline.js<nl>
+}
+{
+    endColumn : 0
+    endLine : 3
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : AD4760425BF645075D5681F7D1786BD4DA9A86A7
+    isLiveEdit : false
+    isModule : false
+    length : 46
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : threeline.js
+}
+scriptParsed
+{
+    scriptSource : function foo5(){}//# sourceMappingURL=oneline-map<nl>
+}
+{
+    endColumn : 0
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 3E60CE61913387795D5696189A7BA7EB4048B715
+    isLiveEdit : false
+    isModule : false
+    length : 50
+    scriptId : <scriptId>
+    sourceMapURL : oneline-map
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo6(){}//# sourceMappingURL=oneline-without-nl-map
+}
+{
+    endColumn : 60
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 3E60CE617215C621E8825B319A7BA7EB4048B715
+    isLiveEdit : false
+    isModule : false
+    length : 60
+    scriptId : <scriptId>
+    sourceMapURL : oneline-without-nl-map
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo7(){}<nl>//# sourceMappingURL=twoline-map<nl>
+}
+{
+    endColumn : 0
+    endLine : 2
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : F2A32D219EFACBF470C48663BCD47D85864D1A22
+    isLiveEdit : false
+    isModule : false
+    length : 51
+    scriptId : <scriptId>
+    sourceMapURL : twoline-map
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo8(){}<nl><nl>//# sourceMappingURL=threeline-map<nl>
+}
+{
+    endColumn : 0
+    endLine : 3
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 46927EC1BFB78C355D5681F7D1786BD4216D5124
+    isLiveEdit : false
+    isModule : false
+    length : 54
+    scriptId : <scriptId>
+    sourceMapURL : threeline-map
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo9(){}//# sourceMappingURL=source-mapping-url-map<nl>//# sourceURL=source-url.js
+}
+{
+    endColumn : 27
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : 793E2411EDECF405E8825B31460F7CD9A656E096
+    isLiveEdit : false
+    isModule : false
+    length : 88
+    scriptId : <scriptId>
+    sourceMapURL : source-mapping-url-map
+    startColumn : 0
+    startLine : 0
+    url : source-url.js
+}
+scriptParsed
+{
+    scriptSource : function foo10(){}//# sourceURL=source-url.js<nl>//# sourceMappingURL=source-mapping-url-map
+}
+{
+    endColumn : 43
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : DED761235CC24EE21D0E9277CF599B5A292D8053
+    isLiveEdit : false
+    isModule : false
+    length : 89
+    scriptId : <scriptId>
+    sourceMapURL : source-mapping-url-map
+    startColumn : 0
+    startLine : 0
+    url : source-url.js
+}
+scriptParsed
+{
+    scriptSource : function foo11(){}<nl>//# sourceURL=end1.js
+}
+{
+    endColumn : 21
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : 9CF28A415BF64507692D5A84D1786BD4437C3511
+    isLiveEdit : false
+    isModule : false
+    length : 40
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : end1.js
+}
+scriptParsed
+{
+    scriptSource : function foo12(){}<nl>//# sourceURL=end2.js 
+}
+{
+    endColumn : 22
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : BEE49C625BF64507692D5A84D1786BD4437C3511
+    isLiveEdit : false
+    isModule : false
+    length : 41
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : end2.js
+}
+scriptParsed
+{
+    scriptSource : function foo13(){}
+}
+{
+    endColumn : 18
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 9CF28A415BF64507692D5A8443D429DC872EBA18
+    isLiveEdit : false
+    isModule : false
+    length : 18
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo15(){}; eval("function foo14(){}//# sourceURL=eval.js")//# sourceURL=eval-wrapper.js
+}
+{
+    endColumn : 96
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : D26251F019679C792E2B4EF437A20E96134D5C26
+    isLiveEdit : false
+    isModule : false
+    length : 96
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : eval-wrapper.js
+}
+scriptParsed
+{
+    scriptSource : function foo14(){}//# sourceURL=eval.js
+}
+{
+    endColumn : 39
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : 814AEF635BF64507692D5A84BCD47D85C4031CD2
+    isLiveEdit : false
+    isModule : false
+    length : 39
+    scriptId : <scriptId>
+    sourceMapURL : 
+    stackTrace : {
+        callFrames : [
+            [0] : {
+                columnNumber : 20
+                functionName : 
+                lineNumber : 0
+                scriptId : <scriptId>
+                url : eval-wrapper.js
+            }
+        ]
+    }
+    startColumn : 0
+    startLine : 0
+    url : eval.js
+}
+scriptFailedToParse
+{
+    scriptSource : }//# sourceURL=failed.js<nl>//# sourceMappingURL=failed-map
+}
+{
+    endColumn : 31
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : true
+    hash : C0C37C619263496792D5CFE7CA6F2911028287A6
+    isModule : false
+    length : 56
+    scriptId : <scriptId>
+    sourceMapURL : failed-map
+    startColumn : 0
+    startLine : 0
+    url : failed.js
+}
+scriptParsed
+{
+    scriptSource : function foo16(){}<nl>
+}
+{
+    endColumn : 0
+    endLine : 1
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 9CF28A415BF64507692D5A84A8DC8126872EBA18
+    isLiveEdit : false
+    isModule : false
+    length : 19
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo17(){}<nl><nl>
+}
+{
+    endColumn : 0
+    endLine : 2
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 9CF28A415BF64507692D5A8443D429DC872EBA18
+    isLiveEdit : false
+    isModule : false
+    length : 20
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo18(){}<nl><nl><nl>
+}
+{
+    endColumn : 0
+    endLine : 3
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 9CF28A415BF64507692D5A84A8DC8126872EBA18
+    isLiveEdit : false
+    isModule : false
+    length : 21
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+scriptParsed
+{
+    scriptSource : function foo19(){}<nl><nl><nl><nl>
+}
+{
+    endColumn : 0
+    endLine : 4
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 9CF28A415BF64507692D5A8443D429DC872EBA18
+    isLiveEdit : false
+    isModule : false
+    length : 22
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : 
+}
+Remove script references and re-enable debugger.
diff --git a/src/v8/test/inspector/debugger/script-on-after-compile.js b/src/v8/test/inspector/debugger/script-on-after-compile.js
new file mode 100644
index 0000000..544dbaa
--- /dev/null
+++ b/src/v8/test/inspector/debugger/script-on-after-compile.js
@@ -0,0 +1,73 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Checks that inspector correctly process compiled scripts");
+
+function addScripts() {
+  // sourceURL in the same line
+  return addScript("function foo1(){}//# sourceURL=oneline.js\n")
+  // sourceURL without end line
+    .then(() => addScript("function foo2(){}//# sourceURL=oneline-without-nl.js"))
+  // other source urls
+    .then(() => addScript("function foo3(){}\n//# sourceURL=twoline.js\n"))
+    .then(() => addScript("function foo4(){}\n\n//# sourceURL=threeline.js\n"))
+
+  // sourceMappingURL in the same line
+    .then(() => addScript("function foo5(){}//# sourceMappingURL=oneline-map\n"))
+  // sourceMappingURL without end line
+    .then(() => addScript("function foo6(){}//# sourceMappingURL=oneline-without-nl-map"))
+  // other sourceMappingURLs
+    .then(() => addScript("function foo7(){}\n//# sourceMappingURL=twoline-map\n"))
+    .then(() => addScript("function foo8(){}\n\n//# sourceMappingURL=threeline-map\n"))
+
+  // sourceURL + sourceMappingURL
+    .then(() => addScript("function foo9(){}//# sourceMappingURL=source-mapping-url-map\n//# sourceURL=source-url.js"))
+    .then(() => addScript("function foo10(){}//# sourceURL=source-url.js\n//# sourceMappingURL=source-mapping-url-map"))
+
+  // non zero endLine and endColumn..
+    .then(() => addScript("function foo11(){}\n//# sourceURL=end1.js"))
+  // .. + 1 character
+    .then(() => addScript("function foo12(){}\n//# sourceURL=end2.js "))
+  // script without sourceURL
+    .then(() => addScript("function foo13(){}"))
+  // script in eval
+    .then(() => addScript("function foo15(){}; eval(\"function foo14(){}//# sourceURL=eval.js\")//# sourceURL=eval-wrapper.js"))
+  // sourceURL and sourceMappingURL works even for script with syntax error
+    .then(() => addScript("}//# sourceURL=failed.js\n//# sourceMappingURL=failed-map"))
+  // empty lines at end
+    .then(() => addScript("function foo16(){}\n"))
+    .then(() => addScript("function foo17(){}\n\n"))
+    .then(() => addScript("function foo18(){}\n\n\n"))
+    .then(() => addScript("function foo19(){}\n\n\n\n"));
+}
+
+Protocol.Debugger.onScriptParsed((message) => requestSourceAndDump(message, true));
+Protocol.Debugger.onScriptFailedToParse((message) => requestSourceAndDump(message, false));
+addScripts()
+  .then(() => Protocol.Debugger.enable())
+  .then(addScripts)
+  .then(() => Protocol.Debugger.disable())
+  .then(() => InspectorTest.log("Remove script references and re-enable debugger."))
+  .then(() => Protocol.Runtime.evaluate(
+      { expression: "for (let i = 1; i < 20; ++i) eval(`foo${i} = undefined`);" }))
+  .then(() => Protocol.HeapProfiler.collectGarbage())
+  .then(() => Protocol.Debugger.enable())
+  .then(InspectorTest.completeTest);
+
+function addScript(source) {
+  return Protocol.Runtime.evaluate({ expression: source });
+}
+
+function requestSourceAndDump(scriptParsedMessage, scriptParsed) {
+  Protocol.Debugger.getScriptSource({ scriptId: scriptParsedMessage.params.scriptId })
+    .then((sourceMessage) => dumpScriptParsed(scriptParsedMessage, sourceMessage, scriptParsed));
+}
+
+function dumpScriptParsed(scriptParsedMessage, sourceMessage, scriptParsed) {
+  var sourceResult = sourceMessage.result;
+  sourceResult.scriptSource = sourceResult.scriptSource.replace(/\n/g, "<nl>");
+  InspectorTest.log(scriptParsed ? "scriptParsed" : "scriptFailedToParse");
+  InspectorTest.logObject(sourceResult);
+  InspectorTest.logMessage(scriptParsedMessage.params);
+}
diff --git a/src/v8/test/inspector/debugger/script-parsed-for-runtime-evaluate-expected.txt b/src/v8/test/inspector/debugger/script-parsed-for-runtime-evaluate-expected.txt
new file mode 100644
index 0000000..75014e1
--- /dev/null
+++ b/src/v8/test/inspector/debugger/script-parsed-for-runtime-evaluate-expected.txt
@@ -0,0 +1,266 @@
+Checks that inspector reports script compiled in Runtime.evaluate, Runtime.callFunctionOn and  Runtime.compileScript
+Runtime.evaluate with valid expression
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 29
+        endLine : 0
+        executionContextId : <executionContextId>
+        hasSourceURL : true
+        hash : 9D04F7335D1661503EAB9AF3EACAF92020803F34
+        isLiveEdit : false
+        isModule : false
+        length : 29
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : evaluate.js
+    }
+}
+Runtime.evaluate with syntax error
+{
+    method : Debugger.scriptFailedToParse
+    params : {
+        endColumn : 39
+        endLine : 0
+        executionContextId : <executionContextId>
+        hasSourceURL : true
+        hash : 9BCA34A10E5386925E74C1716C857BEB02821E15
+        isModule : false
+        length : 39
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : evaluate-syntax-error.js
+    }
+}
+Runtime.callFunctionOn with valid functionDeclaration
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 18
+        endLine : 0
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : 9D04CEA1B54DF92A01A0498543D429DC872EBA18
+        isLiveEdit : false
+        isModule : false
+        length : 18
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : 
+    }
+}
+Runtime.callFunctionOn with syntax error
+{
+    method : Debugger.scriptFailedToParse
+    params : {
+        endColumn : 3
+        endLine : 0
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : 9D04D83251E2B7F64CB5762843D429DC872EBA18
+        isModule : false
+        length : 3
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : 
+    }
+}
+Runtime.compileScript with valid expression
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 4
+        endLine : 0
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : 9D04F733E4E4F1BA4CB5762843D429DC872EBA18
+        isLiveEdit : false
+        isModule : false
+        length : 4
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : compile-script.js
+    }
+}
+Runtime.compileScript with syntax error
+{
+    method : Debugger.scriptFailedToParse
+    params : {
+        endColumn : 1
+        endLine : 0
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : FF746120E4E4F1BA4CB5762843D429DC872EBA18
+        isModule : false
+        length : 1
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : compile-script-syntax-error.js
+    }
+}
+Runtime.compileScript persistScript: false (should be no script events)
+Runtime.evaluate compiled script with stack trace
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 8
+        endLine : 0
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : A2185340E4E4F1BA4CB5762843D429DC872EBA18
+        isLiveEdit : false
+        isModule : false
+        length : 8
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : 
+    }
+}
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 39
+        endLine : 4
+        executionContextId : <executionContextId>
+        hasSourceURL : true
+        hash : 6AF4ED72C355E471C4E94D74464A25541932A242
+        isLiveEdit : false
+        isModule : false
+        length : 86
+        scriptId : <scriptId>
+        sourceMapURL : 
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 2
+                    functionName : fooTop
+                    lineNumber : 10
+                    scriptId : <scriptId>
+                    url : top-frame.js
+                }
+            ]
+        }
+        startColumn : 0
+        startLine : 0
+        url : second-frame.js
+    }
+}
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 4
+        endLine : 0
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : 9D04F733E4E4F1BA4CB5762843D429DC872EBA18
+        isLiveEdit : false
+        isModule : false
+        length : 4
+        scriptId : <scriptId>
+        sourceMapURL : 
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 6
+                    functionName : foo
+                    lineNumber : 2
+                    scriptId : <scriptId>
+                    url : second-frame.js
+                }
+            ]
+        }
+        startColumn : 0
+        startLine : 0
+        url : 
+    }
+}
+Runtime.evaluate compile script error with stack trace
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 12
+        endLine : 0
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : A218534034AA14704CB5762843D429DC872EBA18
+        isLiveEdit : false
+        isModule : false
+        length : 12
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : 
+    }
+}
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 48
+        endLine : 4
+        executionContextId : <executionContextId>
+        hasSourceURL : true
+        hash : 5FD5C8C38F2D44588A4078148B0BC5635152B0C0
+        isLiveEdit : false
+        isModule : false
+        length : 98
+        scriptId : <scriptId>
+        sourceMapURL : 
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 2
+                    functionName : fooTopFail
+                    lineNumber : 20
+                    scriptId : <scriptId>
+                    url : top-frame-fail.js
+                }
+            ]
+        }
+        startColumn : 0
+        startLine : 0
+        url : second-frame-fail.js
+    }
+}
+{
+    method : Debugger.scriptFailedToParse
+    params : {
+        endColumn : 3
+        endLine : 0
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : 9D04F7336C348CA34CB5762843D429DC872EBA18
+        isModule : false
+        length : 3
+        scriptId : <scriptId>
+        sourceMapURL : 
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 6
+                    functionName : fooFail
+                    lineNumber : 2
+                    scriptId : <scriptId>
+                    url : second-frame-fail.js
+                }
+            ]
+        }
+        startColumn : 0
+        startLine : 0
+        url : 
+    }
+}
diff --git a/src/v8/test/inspector/debugger/script-parsed-for-runtime-evaluate.js b/src/v8/test/inspector/debugger/script-parsed-for-runtime-evaluate.js
new file mode 100644
index 0000000..bebf64b
--- /dev/null
+++ b/src/v8/test/inspector/debugger/script-parsed-for-runtime-evaluate.js
@@ -0,0 +1,79 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Checks that inspector reports script compiled in Runtime.evaluate, " +
+  "Runtime.callFunctionOn and  Runtime.compileScript");
+
+contextGroup.addScript(`
+function fooTop() {
+  eval(\`
+    function foo() {
+      eval("({})")
+    }
+    foo() //# sourceURL=second-frame.js\`);
+}
+//# sourceURL=top-frame.js`, 8, 26);
+
+contextGroup.addScript(`
+function fooTopFail() {
+  eval(\`
+    function fooFail() {
+      eval("({}")
+    }
+    fooFail() //# sourceURL=second-frame-fail.js\`);
+}
+//# sourceURL=top-frame-fail.js`, 18, 26);
+
+Promise.prototype.thenLog = function log(message) {
+  return this.then(() => InspectorTest.log(message));
+}
+
+var objectId;
+Protocol.Runtime.enable();
+Protocol.Debugger.enable()
+  .then(() => Protocol.Debugger.onScriptParsed(InspectorTest.logMessage))
+  .then(() => Protocol.Debugger.onScriptFailedToParse(InspectorTest.logMessage))
+
+  .thenLog('Runtime.evaluate with valid expression')
+  .then(() => Protocol.Runtime.evaluate({
+    expression: "({})//# sourceURL=evaluate.js"}))
+  .then(msg => objectId = msg.result.result.objectId)
+
+  .thenLog('Runtime.evaluate with syntax error')
+  .then(() => Protocol.Runtime.evaluate({
+    expression: "}//# sourceURL=evaluate-syntax-error.js"}))
+
+  .thenLog('Runtime.callFunctionOn with valid functionDeclaration')
+  .then(() => Protocol.Runtime.callFunctionOn({ objectId: objectId,
+    functionDeclaration: "function foo(){}"}))
+
+  .thenLog('Runtime.callFunctionOn with syntax error')
+  .then(() => Protocol.Runtime.callFunctionOn({ objectId: objectId,
+    functionDeclaration: "}"}))
+
+  .thenLog('Runtime.compileScript with valid expression')
+  .then(() => Protocol.Runtime.compileScript({ expression: "({})",
+    sourceURL: "compile-script.js", persistScript: true }))
+
+  .thenLog('Runtime.compileScript with syntax error')
+  .then(() => Protocol.Runtime.compileScript({ expression: "}",
+    sourceURL: "compile-script-syntax-error.js", persistScript: true }))
+
+  .thenLog('Runtime.compileScript persistScript: false (should be no script events)')
+  .then(() => Protocol.Runtime.compileScript({ expression: "({})",
+    sourceURL: "compile-script-syntax-error.js", persistScript: false }))
+  .then(() => Protocol.Runtime.compileScript({ expression: "}",
+    sourceURL: "compile-script-syntax-error.js", persistScript: false }))
+
+  .thenLog('Runtime.evaluate compiled script with stack trace')
+  .then(() => Protocol.Runtime.evaluate({
+    expression: "fooTop()"}))
+  .then(msg => objectId = msg.result.result.objectId)
+
+  .thenLog('Runtime.evaluate compile script error with stack trace')
+  .then(() => Protocol.Runtime.evaluate({
+    expression: "fooTopFail()"}))
+  .then(msg => objectId = msg.result.result.objectId)
+
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/script-parsed-hash-expected.txt b/src/v8/test/inspector/debugger/script-parsed-hash-expected.txt
new file mode 100644
index 0000000..88cb394
--- /dev/null
+++ b/src/v8/test/inspector/debugger/script-parsed-hash-expected.txt
@@ -0,0 +1,46 @@
+Tests scripts hasing
+{
+    endColumn : 1
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 1C6D2E82E4E4F1BA4CB5762843D429DC872EBA18
+    isLiveEdit : false
+    isModule : false
+    length : 1
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : foo1.js
+}
+{
+    endColumn : 3
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : EBF1ECD351E7A3294CB5762843D429DC872EBA18
+    isLiveEdit : false
+    isModule : false
+    length : 3
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : foo2.js
+}
+{
+    endColumn : 8106
+    endLine : 0
+    executionContextId : <executionContextId>
+    hasSourceURL : false
+    hash : 885818413D7FC3E2220B3E367FF57CB1D1572095
+    isLiveEdit : false
+    isModule : false
+    length : 8106
+    scriptId : <scriptId>
+    sourceMapURL : 
+    startColumn : 0
+    startLine : 0
+    url : foo3.js
+}
diff --git a/src/v8/test/inspector/debugger/script-parsed-hash.js b/src/v8/test/inspector/debugger/script-parsed-hash.js
new file mode 100644
index 0000000..05d0ed6
--- /dev/null
+++ b/src/v8/test/inspector/debugger/script-parsed-hash.js
@@ -0,0 +1,29 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} =
+    InspectorTest.start('Tests scripts hasing');
+
+(async function test() {
+  await Protocol.Debugger.enable();
+  await Protocol.Runtime.enable();
+  Protocol.Runtime.compileScript({
+    expression: "1", sourceURL: "foo1.js", persistScript: true});
+  let {params} = await Protocol.Debugger.onceScriptParsed();
+  InspectorTest.logMessage(params);
+  Protocol.Runtime.compileScript({
+    expression: "239", sourceURL: "foo2.js", persistScript: true});
+  ({params} = await Protocol.Debugger.onceScriptParsed());
+  InspectorTest.logMessage(params);
+  var script = "var b = 1;";
+  for (var i = 0; i < 2024; ++i) {
+    script += "++b;";
+  }
+  Protocol.Runtime.compileScript({
+    expression: script, sourceURL: "foo3.js",
+    persistScript: true});
+  ({params} = await Protocol.Debugger.onceScriptParsed());
+  InspectorTest.logMessage(params);
+  InspectorTest.completeTest();
+})()
diff --git a/src/v8/test/inspector/debugger/set-async-call-stack-depth-expected.txt b/src/v8/test/inspector/debugger/set-async-call-stack-depth-expected.txt
new file mode 100644
index 0000000..98fcceb
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-async-call-stack-depth-expected.txt
@@ -0,0 +1,37 @@
+Checks that we report not more then maxDepth call chains.
+
+Running test: testPaused
+Actual call chain length: 8
+setAsyncCallStackDepth(maxDepth): 16
+reported: 1
+
+Actual call chain length: 8
+setAsyncCallStackDepth(maxDepth): 8
+reported: 1
+
+Actual call chain length: 8
+setAsyncCallStackDepth(maxDepth): 7
+reported: 1
+
+Actual call chain length: 8
+setAsyncCallStackDepth(maxDepth): 0
+reported: 0
+
+
+Running test: testConsoleTrace
+Actual call chain length: 8
+setAsyncCallStackDepth(maxDepth): 16
+reported: 1
+
+Actual call chain length: 8
+setAsyncCallStackDepth(maxDepth): 8
+reported: 1
+
+Actual call chain length: 8
+setAsyncCallStackDepth(maxDepth): 7
+reported: 1
+
+Actual call chain length: 8
+setAsyncCallStackDepth(maxDepth): 0
+reported: 0
+
diff --git a/src/v8/test/inspector/debugger/set-async-call-stack-depth.js b/src/v8/test/inspector/debugger/set-async-call-stack-depth.js
new file mode 100644
index 0000000..0c7567f
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-async-call-stack-depth.js
@@ -0,0 +1,79 @@
+// Copyright 2017 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.
+
+// TODO(kozyatinskiy): fix or remove it later with new stack traces it's almost
+// imposible to hit limit.
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that we report not more then maxDepth call chains.');
+
+contextGroup.addScript(`
+function promisesChain(num) {
+  var p = Promise.resolve();
+  for (var i = 0; i < num - 1; ++i) {
+    p = p.then(() => 42);
+  }
+  return p;
+}
+`);
+
+Protocol.Debugger.enable();
+InspectorTest.runAsyncTestSuite([
+  async function testPaused() {
+    let callback = '() => { debugger; }';
+    startTest({ generated: 8, limit: 16, callback});
+    dumpCaptured((await Protocol.Debugger.oncePaused()).params.asyncStackTrace);
+    await Protocol.Debugger.resume();
+
+    startTest({ generated: 8, limit: 8, callback});
+    dumpCaptured((await Protocol.Debugger.oncePaused()).params.asyncStackTrace);
+    await Protocol.Debugger.resume();
+
+    startTest({ generated: 8, limit: 7, callback});
+    dumpCaptured((await Protocol.Debugger.oncePaused()).params.asyncStackTrace);
+    await Protocol.Debugger.resume();
+
+    startTest({ generated: 8, limit: 0, callback});
+    dumpCaptured((await Protocol.Debugger.oncePaused()).params.asyncStackTrace);
+    await Protocol.Debugger.resume();
+  },
+
+  async function testConsoleTrace() {
+    await Protocol.Runtime.enable();
+    let callback = '() => { console.trace(42); }';
+    startTest({ generated: 8, limit: 16, callback});
+    let msg = await Protocol.Runtime.onceConsoleAPICalled();
+    dumpCaptured(msg.params.stackTrace.parent);
+
+    startTest({ generated: 8, limit: 8, callback});
+    msg = await Protocol.Runtime.onceConsoleAPICalled();
+    dumpCaptured(msg.params.stackTrace.parent);
+
+    startTest({ generated: 8, limit: 7, callback});
+    msg = await Protocol.Runtime.onceConsoleAPICalled();
+    dumpCaptured(msg.params.stackTrace.parent);
+
+    startTest({ generated: 8, limit: 0, callback});
+    msg = await Protocol.Runtime.onceConsoleAPICalled();
+    dumpCaptured(msg.params.stackTrace.parent);
+
+    await Protocol.Runtime.disable();
+  }
+]);
+
+function startTest(params) {
+  InspectorTest.log('Actual call chain length: ' + params.generated);
+  InspectorTest.log('setAsyncCallStackDepth(maxDepth): ' + params.limit);
+
+  Protocol.Debugger.setAsyncCallStackDepth({maxDepth: params.limit});
+  Protocol.Runtime.evaluate({expression:
+      `promisesChain(${params.generated}).then(${params.callback})`});
+}
+
+function dumpCaptured(stack) {
+  let count = 0;
+  while (stack) {
+    ++count;
+    stack = stack.parent;
+  }
+  InspectorTest.log('reported: ' + count + '\n');
+}
diff --git a/src/v8/test/inspector/debugger/set-blackbox-patterns-expected.txt b/src/v8/test/inspector/debugger/set-blackbox-patterns-expected.txt
new file mode 100644
index 0000000..cd1f11e
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-blackbox-patterns-expected.txt
@@ -0,0 +1,26 @@
+Tests blackboxing by patterns
+Pattern parser error: Uncaught SyntaxError: Invalid regular expression: /(foo([)/: Unterminated character class
+Paused in
+(...):1
+Paused in
+(...):1
+Paused in
+qwe:3
+baz:3
+(...):1
+Paused in
+bar:3
+foo:3
+qwe:3
+baz:3
+(...):1
+Paused in
+qwe:4
+baz:3
+(...):1
+Paused in
+qwe:4
+baz:3
+(...):1
+Paused in
+(...):1
diff --git a/src/v8/test/inspector/debugger/set-blackbox-patterns.js b/src/v8/test/inspector/debugger/set-blackbox-patterns.js
new file mode 100644
index 0000000..d060c90
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-blackbox-patterns.js
@@ -0,0 +1,61 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests blackboxing by patterns');
+
+contextGroup.addScript(
+`function bar()
+{
+    return 42;
+}`);
+
+contextGroup.addScript(
+`function foo()
+{
+    var a = bar();
+    return a + 1;
+}
+//# sourceURL=foo.js`);
+
+contextGroup.addScript(
+`function qwe()
+{
+    var a = foo();
+    return a + 1;
+}
+//# sourceURL=qwe.js`);
+
+contextGroup.addScript(
+`function baz()
+{
+    var a = qwe();
+    return a + 1;
+}
+//# sourceURL=baz.js`);
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setBlackboxPatterns({ patterns: [ "foo([" ] }).then(dumpError);
+
+function dumpError(message)
+{
+  InspectorTest.log(message.error.message);
+  Protocol.Debugger.onPaused(dumpStackAndRunNextCommand);
+  Protocol.Debugger.setBlackboxPatterns({ patterns: [ "baz\.js", "foo\.js" ] });
+  Protocol.Runtime.evaluate({ "expression": "debugger;baz()" });
+}
+
+var commands = [ "stepInto", "stepInto", "stepInto", "stepOut", "stepInto", "stepInto" ];
+function dumpStackAndRunNextCommand(message)
+{
+  InspectorTest.log("Paused in");
+  var callFrames = message.params.callFrames;
+  for (var callFrame of callFrames)
+    InspectorTest.log((callFrame.functionName || "(...)") + ":" + (callFrame.location.lineNumber + 1));
+  var command = commands.shift();
+  if (!command) {
+    InspectorTest.completeTest();
+    return;
+  }
+  Protocol.Debugger[command]();
+}
diff --git a/src/v8/test/inspector/debugger/set-breakpoint-before-enabling-expected.txt b/src/v8/test/inspector/debugger/set-breakpoint-before-enabling-expected.txt
new file mode 100644
index 0000000..2601734
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-breakpoint-before-enabling-expected.txt
@@ -0,0 +1,7 @@
+Tests that setting breakpoint before enabling debugger produces an error
+setBreakpointByUrl error: undefined
+setBreakpoint error: {
+  "code": -32602,
+  "message": "Invalid parameters",
+  "data": "location: object expected"
+}
diff --git a/src/v8/test/inspector/debugger/set-breakpoint-before-enabling.js b/src/v8/test/inspector/debugger/set-breakpoint-before-enabling.js
new file mode 100644
index 0000000..84541be
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-breakpoint-before-enabling.js
@@ -0,0 +1,19 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that setting breakpoint before enabling debugger produces an error');
+
+Protocol.Debugger.setBreakpointByUrl({ url: "http://example.com", lineNumber: 10  }).then(didSetBreakpointByUrlBeforeEnable);
+
+function didSetBreakpointByUrlBeforeEnable(message)
+{
+  InspectorTest.log("setBreakpointByUrl error: " + JSON.stringify(message.error, null, 2));
+  Protocol.Debugger.setBreakpoint().then(didSetBreakpointBeforeEnable);
+}
+
+function didSetBreakpointBeforeEnable(message)
+{
+  InspectorTest.log("setBreakpoint error: " + JSON.stringify(message.error, null, 2));
+  InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/debugger/set-script-source-2-expected.txt b/src/v8/test/inspector/debugger/set-script-source-2-expected.txt
new file mode 100644
index 0000000..683381b
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-script-source-2-expected.txt
@@ -0,0 +1,73 @@
+Tests Debugger.setScriptSource
+
+Running test: addLineAfter
+var x = 1;
+#debugger;
+return x + 2;
+
+---
+Break location after LiveEdit:
+var x = 1;
+#debugger;
+var x = 3;
+
+stackChanged: true
+Protocol.Debugger.stepInto
+function foo() {
+var x = #1;
+debugger;
+
+
+Running test: addLineBefore
+var x = 1;
+#debugger;
+return x + 2;
+
+---
+Break location after LiveEdit:
+var x = 1;
+var x = #3;
+debugger;
+
+stackChanged: true
+Protocol.Debugger.stepInto
+function foo() {
+var x = #1;
+var x = 3;
+
+
+Running test: breakAtFirstLineAddLineAfter
+function boo() {
+#debugger;
+var x = 1;
+
+---
+Break location after LiveEdit:
+function boo() {
+#debugger;
+var x = 3;
+
+stackChanged: true
+Protocol.Debugger.stepInto
+function boo() {
+#debugger;
+var x = 3;
+
+
+Running test: breakAtFirstLineAddLineBefore
+function boo() {
+#debugger;
+var x = 1;
+
+---
+Break location after LiveEdit:
+function boo() {
+var x = #3;
+debugger;
+
+stackChanged: true
+Protocol.Debugger.stepInto
+var x = 3;
+#debugger;
+var x = 1;
+
diff --git a/src/v8/test/inspector/debugger/set-script-source-2.js b/src/v8/test/inspector/debugger/set-script-source-2.js
new file mode 100644
index 0000000..053ccee
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-script-source-2.js
@@ -0,0 +1,97 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+    InspectorTest.start('Tests Debugger.setScriptSource');
+
+session.setupScriptMap();
+
+function foo() {
+var x = 1;
+debugger;
+return x + 2;
+}
+
+function boo() {
+debugger;
+var x = 1;
+return x + 2;
+}
+
+InspectorTest.runAsyncTestSuite([
+  async function addLineAfter() {
+    await Protocol.Debugger.enable();
+    Protocol.Runtime.evaluate({expression: foo.toString()});
+    let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
+    Protocol.Runtime.evaluate({
+      expression: 'setTimeout(foo, 0)//# sourceURL=test.js'});
+    let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+    await session.logSourceLocation(callFrames[0].location);
+    await replaceInSource(scriptId, 'debugger;', 'debugger;\nvar x = 3;');
+
+    Protocol.Debugger.resume();
+    await Protocol.Debugger.oncePaused();
+    await Protocol.Debugger.disable();
+  },
+
+  async function addLineBefore() {
+    await Protocol.Debugger.enable();
+    Protocol.Runtime.evaluate({expression: foo.toString()});
+    let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
+    Protocol.Runtime.evaluate({
+      expression: 'setTimeout(foo, 0)//# sourceURL=test.js'});
+    let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+    await session.logSourceLocation(callFrames[0].location);
+    await replaceInSource(scriptId, 'debugger;', 'var x = 3;\ndebugger;');
+
+    Protocol.Debugger.resume();
+    await Protocol.Debugger.oncePaused();
+    await Protocol.Debugger.disable();
+  },
+
+  async function breakAtFirstLineAddLineAfter() {
+    await Protocol.Debugger.enable();
+    Protocol.Runtime.evaluate({expression: boo.toString()});
+    let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
+    Protocol.Runtime.evaluate({
+      expression: 'setTimeout(boo, 0)//# sourceURL=test.js'});
+    let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+    await session.logSourceLocation(callFrames[0].location);
+    await replaceInSource(scriptId, 'debugger;', 'debugger;\nvar x = 3;');
+
+    await Protocol.Debugger.disable();
+  },
+
+  async function breakAtFirstLineAddLineBefore() {
+    await Protocol.Debugger.enable();
+    Protocol.Runtime.evaluate({expression: boo.toString()});
+    let {params:{scriptId}} = await Protocol.Debugger.onceScriptParsed();
+    Protocol.Runtime.evaluate({
+      expression: 'setTimeout(boo, 0)//# sourceURL=test.js'});
+    let {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+    await session.logSourceLocation(callFrames[0].location);
+    await replaceInSource(scriptId, 'debugger;', 'var x = 3;\ndebugger;');
+
+    await Protocol.Debugger.disable();
+  }
+]);
+
+async function replaceInSource(scriptId, oldString, newString) {
+  InspectorTest.log('---');
+  let {result:{scriptSource}} =
+      await Protocol.Debugger.getScriptSource({scriptId});
+  let {result} = await Protocol.Debugger.setScriptSource({
+    scriptId,
+    scriptSource: scriptSource.replace(oldString, newString)
+  });
+  InspectorTest.log('Break location after LiveEdit:');
+  await session.logSourceLocation(result.callFrames[0].location, true);
+  InspectorTest.log('stackChanged: ' + result.stackChanged);
+  if (result.stackChanged) {
+    InspectorTest.log('Protocol.Debugger.stepInto');
+    Protocol.Debugger.stepInto();
+    var {params:{callFrames}} = await Protocol.Debugger.oncePaused();
+    await session.logSourceLocation(callFrames[0].location);
+  }
+}
diff --git a/src/v8/test/inspector/debugger/set-script-source-exception-expected.txt b/src/v8/test/inspector/debugger/set-script-source-exception-expected.txt
new file mode 100644
index 0000000..376c11d
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-script-source-exception-expected.txt
@@ -0,0 +1,23 @@
+Check that setScriptSource completes correctly when an exception is thrown.
+
+Running test: testIncorrectScriptId
+{
+    error : {
+        code : -32000
+        message : No script with given id found
+    }
+    id : <messageId>
+}
+
+Running test: testSourceWithSyntaxError
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 2
+            exceptionId : <exceptionId>
+            lineNumber : 0
+            text : Invalid or unexpected token
+        }
+    }
+}
diff --git a/src/v8/test/inspector/debugger/set-script-source-exception.js b/src/v8/test/inspector/debugger/set-script-source-exception.js
new file mode 100644
index 0000000..627aa7e
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-script-source-exception.js
@@ -0,0 +1,23 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Check that setScriptSource completes correctly when an exception is thrown.');
+
+Protocol.Debugger.enable();
+
+InspectorTest.runTestSuite([
+  function testIncorrectScriptId(next) {
+    Protocol.Debugger.setScriptSource({ scriptId: '-1', scriptSource: '0' })
+      .then(InspectorTest.logMessage)
+      .then(next);
+  },
+
+  function testSourceWithSyntaxError(next) {
+    Protocol.Debugger.onceScriptParsed()
+      .then(message => Protocol.Debugger.setScriptSource({ scriptId: message.params.scriptId, scriptSource: 'a # b' }))
+      .then(InspectorTest.logMessage)
+      .then(next);
+    contextGroup.addScript('function foo() {}');
+  }
+]);
diff --git a/src/v8/test/inspector/debugger/set-script-source-expected.txt b/src/v8/test/inspector/debugger/set-script-source-expected.txt
new file mode 100644
index 0000000..e77aafd
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-script-source-expected.txt
@@ -0,0 +1,8 @@
+Tests Debugger.setScriptSource
+Function evaluate: {"type":"number","value":6,"description":"6"}
+PASS, result value: 6
+Function evaluate: {"type":"number","value":8,"description":"8"}
+PASS, result value: 8
+Has error reported: PASS
+Reported error is a compile error: PASS
+PASS, result value: 1
diff --git a/src/v8/test/inspector/debugger/set-script-source.js b/src/v8/test/inspector/debugger/set-script-source.js
new file mode 100644
index 0000000..f13a3a3
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-script-source.js
@@ -0,0 +1,154 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests Debugger.setScriptSource');
+
+contextGroup.addScript(
+`function TestExpression(a, b) {
+    return a + b;
+}`);
+
+// A general-purpose engine for sending a sequence of protocol commands.
+// The clients provide requests and response handlers, while the engine catches
+// errors and makes sure that once there's nothing to do completeTest() is called.
+// @param step is an object with command, params and callback fields
+function runRequestSeries(step) {
+  processStep(step);
+
+  function processStep(currentStep) {
+    try {
+      processStepOrFail(currentStep);
+    } catch (e) {
+      InspectorTest.log(e.stack);
+      InspectorTest.completeTest();
+    }
+  }
+
+  function processStepOrFail(currentStep) {
+    if (!currentStep) {
+      InspectorTest.completeTest();
+      return;
+    }
+    if (!currentStep.command) {
+      // A simple loopback step.
+      var next = currentStep.callback();
+      processStep(next);
+      return;
+    }
+
+    var innerCallback = function(response) {
+      var next;
+      if ("error" in response) {
+        if (!("errorHandler" in currentStep)) {
+          // Error message is not logged intentionally, it may be platform-specific.
+          InspectorTest.log("Protocol command '" + currentStep.command + "' failed");
+          InspectorTest.completeTest();
+          return;
+        }
+        try {
+          next = currentStep.errorHandler(response.error);
+        } catch (e) {
+          InspectorTest.log(e.stack);
+          InspectorTest.completeTest();
+          return;
+        }
+      } else {
+        try {
+          next = currentStep.callback(response.result);
+        } catch (e) {
+          InspectorTest.log(e.stack);
+          InspectorTest.completeTest();
+          return;
+        }
+      }
+      processStep(next);
+    }
+    var command = currentStep.command.split(".");
+    Protocol[command[0]][command[1]](currentStep.params).then(innerCallback);
+  }
+}
+
+function logEqualsCheck(actual, expected)
+{
+  if (actual === expected) {
+    InspectorTest.log("PASS, result value: " + actual);
+  } else {
+    InspectorTest.log("FAIL, actual value: " + actual + ", expected: " + expected);
+  }
+}
+function logCheck(description, success)
+{
+  InspectorTest.log(description + ": " + (success ? "PASS" : "FAIL"));
+}
+
+var firstStep = { callback: enableDebugger };
+
+runRequestSeries(firstStep);
+
+function enableDebugger() {
+  return { command: "Debugger.enable", params: {}, callback: evalFunction };
+}
+
+function evalFunction(response) {
+  var expression = "TestExpression(2, 4)";
+  return { command: "Runtime.evaluate", params: { expression: expression }, callback: callbackEvalFunction };
+}
+
+function callbackEvalFunction(result) {
+  InspectorTest.log("Function evaluate: " + JSON.stringify(result.result));
+  logEqualsCheck(result.result.value, 6);
+
+  return { command: "Runtime.evaluate", params: { expression: "TestExpression" }, callback: callbackEvalFunctionObject };
+}
+
+function callbackEvalFunctionObject(result) {
+  return { command: "Runtime.getProperties", params: { objectId: result.result.objectId }, callback: callbackFunctionDetails };
+}
+
+function callbackFunctionDetails(result)
+{
+  var scriptId;
+  for (var prop of result.internalProperties) {
+    if (prop.name === "[[FunctionLocation]]")
+      scriptId = prop.value.value.scriptId;
+  }
+  return createScriptManipulationArc(scriptId, null);
+}
+
+// Several steps with scriptId in context.
+function createScriptManipulationArc(scriptId, next) {
+  return { command: "Debugger.getScriptSource", params: { scriptId: scriptId }, callback: callbackGetScriptSource };
+
+  var originalText;
+
+  function callbackGetScriptSource(result) {
+    originalText = result.scriptSource;
+    var patched = originalText.replace("a + b", "a * b");
+
+    return { command: "Debugger.setScriptSource", params: { scriptId: scriptId, scriptSource: patched }, callback: callbackSetScriptSource };
+  }
+
+  function callbackSetScriptSource(result) {
+    var expression = "TestExpression(2, 4)";
+    return { command: "Runtime.evaluate", params: { expression: expression }, callback: callbackEvalFunction2 };
+  }
+
+  function callbackEvalFunction2(result) {
+    InspectorTest.log("Function evaluate: " + JSON.stringify(result.result));
+    logEqualsCheck(result.result.value, 8);
+
+    var patched = originalText.replace("a + b", "a # b");
+
+    return { command: "Debugger.setScriptSource", params: { scriptId: scriptId, scriptSource: patched }, callback: errorCallbackSetScriptSource2 };
+  }
+
+  function errorCallbackSetScriptSource2(result) {
+    var exceptionDetails = result.exceptionDetails;
+    logCheck("Has error reported", !!exceptionDetails);
+    logCheck("Reported error is a compile error", !!exceptionDetails);
+    if (exceptionDetails)
+      logEqualsCheck(exceptionDetails.lineNumber, 1);
+    return next;
+  }
+}
diff --git a/src/v8/test/inspector/debugger/set-skip-all-pauses-expected.txt b/src/v8/test/inspector/debugger/set-skip-all-pauses-expected.txt
new file mode 100644
index 0000000..1ef5fec
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-skip-all-pauses-expected.txt
@@ -0,0 +1,7 @@
+Tests that Debugger.setSkipAllPauses skips breaks and does not block resumed notifications
+paused at:
+#debugger;
+
+paused at:
+#debugger
+
diff --git a/src/v8/test/inspector/debugger/set-skip-all-pauses.js b/src/v8/test/inspector/debugger/set-skip-all-pauses.js
new file mode 100644
index 0000000..c361487
--- /dev/null
+++ b/src/v8/test/inspector/debugger/set-skip-all-pauses.js
@@ -0,0 +1,31 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that Debugger.setSkipAllPauses skips breaks and does not block resumed notifications');
+session.setupScriptMap();
+
+(async function test() {
+  await Protocol.Debugger.enable();
+  Protocol.Runtime.evaluate({expression: 'debugger;'});
+  await waitForPause();
+  await Protocol.Debugger.resume();
+
+  await Protocol.Debugger.setSkipAllPauses({skip: true});
+  await Protocol.Runtime.evaluate({expression: 'debugger'});
+
+  await Protocol.Debugger.setSkipAllPauses({skip: false});
+  Protocol.Runtime.evaluate({expression: 'debugger'});
+  await waitForPause();
+  Protocol.Debugger.setSkipAllPauses({skip: true});
+  Protocol.Debugger.resume();
+  await Protocol.Debugger.onceResumed();
+
+  InspectorTest.completeTest();
+})();
+
+async function waitForPause() {
+  var message = await Protocol.Debugger.oncePaused();
+  InspectorTest.log('paused at:');
+  session.logSourceLocation(message.params.callFrames[0].location);
+}
diff --git a/src/v8/test/inspector/debugger/side-effect-free-debug-evaluate-expected.txt b/src/v8/test/inspector/debugger/side-effect-free-debug-evaluate-expected.txt
new file mode 100644
index 0000000..6d11386
--- /dev/null
+++ b/src/v8/test/inspector/debugger/side-effect-free-debug-evaluate-expected.txt
@@ -0,0 +1,6 @@
+Tests side-effect-free evaluation
+Paused on 'debugger;'
+f() returns 1
+g() returns 2
+f() returns 1
+g() throws EvalError
diff --git a/src/v8/test/inspector/debugger/side-effect-free-debug-evaluate.js b/src/v8/test/inspector/debugger/side-effect-free-debug-evaluate.js
new file mode 100644
index 0000000..4e7d9e9
--- /dev/null
+++ b/src/v8/test/inspector/debugger/side-effect-free-debug-evaluate.js
@@ -0,0 +1,56 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests side-effect-free evaluation');
+
+contextGroup.addScript(`
+function testFunction()
+{
+  var o = 0;
+  function f() { return 1; }
+  function g() { o = 2; return o; }
+  debugger;
+}
+//# sourceURL=foo.js`);
+
+Protocol.Debugger.enable();
+
+Protocol.Debugger.oncePaused().then(debuggerPaused);
+
+Protocol.Runtime.evaluate({ "expression": "setTimeout(testFunction, 0)" });
+
+var topFrameId;
+
+function debuggerPaused(messageObject)
+{
+  InspectorTest.log("Paused on 'debugger;'");
+
+  topFrameId = messageObject.params.callFrames[0].callFrameId;
+  Protocol.Debugger.evaluateOnCallFrame({ callFrameId: topFrameId, expression: "f()"}).then(evaluatedFirst);
+}
+
+function evaluatedFirst(response)
+{
+  InspectorTest.log("f() returns " + response.result.result.value);
+  Protocol.Debugger.evaluateOnCallFrame({ callFrameId: topFrameId, expression: "g()"}).then(evaluatedSecond);
+}
+
+function evaluatedSecond(response)
+{
+  InspectorTest.log("g() returns " + response.result.result.value);
+  Protocol.Debugger.evaluateOnCallFrame({ callFrameId: topFrameId, expression: "f()", throwOnSideEffect: true}).then(evaluatedThird);
+}
+
+function evaluatedThird(response)
+{
+  InspectorTest.log("f() returns " + response.result.result.value);
+  Protocol.Debugger.evaluateOnCallFrame({ callFrameId: topFrameId, expression: "g()", throwOnSideEffect: true}).then(evaluatedFourth);
+  InspectorTest.completeTest();
+}
+
+function evaluatedFourth(response)
+{
+  InspectorTest.log("g() throws " + response.result.result.className);
+  InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/debugger/step-into-expected.txt b/src/v8/test/inspector/debugger/step-into-expected.txt
new file mode 100644
index 0000000..30ba7e7
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-into-expected.txt
@@ -0,0 +1,1024 @@
+Checks possible break locations.
+
+Running test: testEval
+break at:
+function testEval() {
+  #eval('// comment only');
+  eval('// comment only\n');
+
+break at:
+// comment onl#y
+
+break at:
+  eval('// comment only');
+  #eval('// comment only\n');
+}
+
+break at:
+// comment only#
+
+
+break at:
+  eval('// comment only\n');
+#}
+
+
+
+Running test: testProcedure
+break at:
+function testProcedure() {
+  #procedure();
+}
+
+break at:
+function procedure() {
+  var a = #1;
+  var b = 2;
+
+break at:
+  var a = 1;
+  var b = #2;
+}
+
+break at:
+  var b = 2;
+#}
+
+
+break at:
+  procedure();
+#}
+
+
+
+Running test: testIf
+break at:
+  var a;
+  if (true) #a = true;
+  if (!a) {
+
+break at:
+  if (true) a = true;
+  #if (!a) {
+    a = true;
+
+break at:
+  } else {
+    #a = false;
+  }
+
+break at:
+  }
+  #if (returnTrue()) {
+    a = false;
+
+break at:
+function returnTrue() {
+  #return true;
+}
+
+break at:
+function returnTrue() {
+  return true;#
+}
+
+break at:
+  if (returnTrue()) {
+    #a = false;
+  } else {
+
+break at:
+  }
+#}
+
+
+
+Running test: testEmptyFunction
+break at:
+function testEmptyFunction() {
+  #emptyFunction();
+}
+
+break at:
+
+function emptyFunction() {#}
+
+
+break at:
+  emptyFunction();
+#}
+
+
+
+Running test: testCallArguments
+break at:
+function testCallArguments() {
+  #twoArguments(emptyFunction(), emptyFunction());
+}
+
+break at:
+
+function emptyFunction() {#}
+
+
+break at:
+function testCallArguments() {
+  twoArguments(emptyFunction(), #emptyFunction());
+}
+
+break at:
+
+function emptyFunction() {#}
+
+
+break at:
+function testCallArguments() {
+  #twoArguments(emptyFunction(), emptyFunction());
+}
+
+break at:
+function twoArguments(a1, a2) {
+#}
+
+
+break at:
+  twoArguments(emptyFunction(), emptyFunction());
+#}
+
+
+
+Running test: testNested
+break at:
+  }
+  #nested1();
+}
+
+break at:
+    }
+    return #nested2();
+  }
+
+break at:
+      }
+      #nested3();
+      return;
+
+break at:
+      function nested3() {
+      #}
+      nested3();
+
+break at:
+      nested3();
+      #return;
+    }
+
+break at:
+      nested3();
+      return;#
+    }
+
+break at:
+    }
+    return nested2();#
+  }
+
+break at:
+  nested1();
+#}
+
+
+
+Running test: testCallAtReturn
+break at:
+function testCallAtReturn() {
+  #return returnCall();
+}
+
+break at:
+function returnCall() {
+  #return return42();
+}
+
+break at:
+function return42() {
+  #return 42;
+}
+
+break at:
+function return42() {
+  return 42;#
+}
+
+break at:
+function returnCall() {
+  return return42();#
+}
+
+break at:
+function testCallAtReturn() {
+  return returnCall();#
+}
+
+
+Running test: testWith
+break at:
+function testWith() {
+  #with (returnObject()) {
+    foo();
+
+break at:
+function returnObject() {
+  #return ({ foo: () => 42 });
+}
+
+break at:
+function returnObject() {
+  return ({ foo: () => 42 });#
+}
+
+break at:
+  with (returnObject()) {
+    #foo();
+  }
+
+break at:
+function returnObject() {
+  return ({ foo: () => #42 });
+}
+
+break at:
+function returnObject() {
+  return ({ foo: () => 42# });
+}
+
+break at:
+  }
+  #with({}) {
+    return;
+
+break at:
+  with({}) {
+    #return;
+  }
+
+break at:
+  with({}) {
+    return;#
+  }
+
+
+Running test: testForLoop
+break at:
+function testForLoop() {
+  for (var i = #0; i < 1; ++i) {}
+  for (var i = 0; i < 1; ++i) i;
+
+break at:
+function testForLoop() {
+  for (var i = 0; i #< 1; ++i) {}
+  for (var i = 0; i < 1; ++i) i;
+
+break at:
+function testForLoop() {
+  for (var i = 0; i < 1; ++#i) {}
+  for (var i = 0; i < 1; ++i) i;
+
+break at:
+function testForLoop() {
+  for (var i = 0; i #< 1; ++i) {}
+  for (var i = 0; i < 1; ++i) i;
+
+break at:
+  for (var i = 0; i < 1; ++i) {}
+  for (var i = #0; i < 1; ++i) i;
+  for (var i = 0; i < 0; ++i) {}
+
+break at:
+  for (var i = 0; i < 1; ++i) {}
+  for (var i = 0; i #< 1; ++i) i;
+  for (var i = 0; i < 0; ++i) {}
+
+break at:
+  for (var i = 0; i < 1; ++i) {}
+  for (var i = 0; i < 1; ++#i) i;
+  for (var i = 0; i < 0; ++i) {}
+
+break at:
+  for (var i = 0; i < 1; ++i) {}
+  for (var i = 0; i #< 1; ++i) i;
+  for (var i = 0; i < 0; ++i) {}
+
+break at:
+  for (var i = 0; i < 1; ++i) i;
+  for (var i = #0; i < 0; ++i) {}
+}
+
+break at:
+  for (var i = 0; i < 1; ++i) i;
+  for (var i = 0; i #< 0; ++i) {}
+}
+
+break at:
+  for (var i = 0; i < 0; ++i) {}
+#}
+
+
+
+Running test: testForOfLoop
+break at:
+function testForOfLoop() {
+  for (var k of #[]) {}
+  for (var k of [1]) k;
+
+break at:
+function testForOfLoop() {
+  for (var #k of []) {}
+  for (var k of [1]) k;
+
+break at:
+  for (var k of []) {}
+  for (var k of #[1]) k;
+  var a = [];
+
+break at:
+  for (var k of []) {}
+  for (var #k of [1]) k;
+  var a = [];
+
+break at:
+  for (var k of []) {}
+  for (var k of [1]) #k;
+  var a = [];
+
+break at:
+  for (var k of []) {}
+  for (var #k of [1]) k;
+  var a = [];
+
+break at:
+  for (var k of [1]) k;
+  var a = #[];
+  for (var k of a) {}
+
+break at:
+  var a = [];
+  for (var k of #a) {}
+}
+
+break at:
+  var a = [];
+  for (var #k of a) {}
+}
+
+break at:
+  for (var k of a) {}
+#}
+
+
+
+Running test: testForInLoop
+break at:
+function testForInLoop() {
+  var o = #{};
+  for (var k in o) {}
+
+break at:
+  var o = {};
+  for (var k in #o) {}
+  for (var k in o) k;
+
+break at:
+  var o = {};
+  for (var #k in o) {}
+  for (var k in o) k;
+
+break at:
+  for (var k in o) {}
+  for (var k in #o) k;
+  for (var k in { a:1 }) {}
+
+break at:
+  for (var k in o) {}
+  for (var #k in o) k;
+  for (var k in { a:1 }) {}
+
+break at:
+  for (var k in o) k;
+  for (var k in #{ a:1 }) {}
+  for (var k in { a:1 }) k;
+
+break at:
+  for (var k in o) k;
+  for (var #k in { a:1 }) {}
+  for (var k in { a:1 }) k;
+
+break at:
+  for (var k in { a:1 }) {}
+  for (var k in #{ a:1 }) k;
+}
+
+break at:
+  for (var k in { a:1 }) {}
+  for (var #k in { a:1 }) k;
+}
+
+break at:
+  for (var k in { a:1 }) {}
+  for (var k in { a:1 }) #k;
+}
+
+break at:
+  for (var k in { a:1 }) {}
+  for (var #k in { a:1 }) k;
+}
+
+break at:
+  for (var k in { a:1 }) k;
+#}
+
+
+
+Running test: testSimpleExpressions
+break at:
+  1 + 2 + 3;
+  var a = #1;
+  ++a;
+
+break at:
+  var a = 1;
+  #++a;
+  a--;
+
+break at:
+  ++a;
+  #a--;
+}
+
+break at:
+  a--;
+#}
+
+
+
+Running test: testGetter
+break at:
+function testGetter() {
+  #getterFoo();
+}
+
+break at:
+Object.defineProperty(this, 'getterFoo', {
+  get: () => #return42
+});
+
+break at:
+Object.defineProperty(this, 'getterFoo', {
+  get: () => return42#
+});
+
+break at:
+function testGetter() {
+  #getterFoo();
+}
+
+break at:
+function return42() {
+  #return 42;
+}
+
+break at:
+function return42() {
+  return 42;#
+}
+
+break at:
+  getterFoo();
+#}
+
+
+
+Running test: testChainedCalls
+break at:
+function testChainedCalls() {
+  #obj.foo().boo()();
+}
+
+break at:
+var obj = {
+  foo: () => (#{
+    boo: () => return42
+
+break at:
+    boo: () => return42
+  })#
+};
+
+break at:
+function testChainedCalls() {
+  obj.foo().#boo()();
+}
+
+break at:
+  foo: () => ({
+    boo: () => #return42
+  })
+
+break at:
+  foo: () => ({
+    boo: () => return42#
+  })
+
+break at:
+function testChainedCalls() {
+  obj.foo().boo()#();
+}
+
+break at:
+function return42() {
+  #return 42;
+}
+
+break at:
+function return42() {
+  return 42;#
+}
+
+break at:
+  obj.foo().boo()();
+#}
+
+
+
+Running test: testChainedWithNative
+break at:
+function testChainedWithNative() {
+  #Array.from([1]).concat([2]).map(v => v * 2);
+}
+
+break at:
+function testChainedWithNative() {
+  Array.from([1]).concat([2]).map(v => v #* 2);
+}
+
+break at:
+function testChainedWithNative() {
+  Array.from([1]).concat([2]).map(v => v * 2#);
+}
+
+break at:
+function testChainedWithNative() {
+  Array.from([1]).concat([2]).map(v => v #* 2);
+}
+
+break at:
+function testChainedWithNative() {
+  Array.from([1]).concat([2]).map(v => v * 2#);
+}
+
+break at:
+  Array.from([1]).concat([2]).map(v => v * 2);
+#}
+
+
+
+Running test: testPromiseThen
+break at:
+function testPromiseThen() {
+  #return Promise.resolve().then(v => v * 2).then(v => v * 2);
+}
+
+break at:
+function testPromiseThen() {
+  return Promise.resolve().then(v => v * 2).then(v => v * 2);#
+}
+
+
+Running test: testSwitch
+break at:
+function testSwitch() {
+  for (var i = #0; i < 3; ++i) {
+    switch(i) {
+
+break at:
+function testSwitch() {
+  for (var i = 0; i #< 3; ++i) {
+    switch(i) {
+
+break at:
+  for (var i = 0; i < 3; ++i) {
+    #switch(i) {
+      case 0: continue;
+
+break at:
+    switch(i) {
+      case 0: #continue;
+      case 1: return42(); break;
+
+break at:
+function testSwitch() {
+  for (var i = 0; i < 3; ++#i) {
+    switch(i) {
+
+break at:
+function testSwitch() {
+  for (var i = 0; i #< 3; ++i) {
+    switch(i) {
+
+break at:
+  for (var i = 0; i < 3; ++i) {
+    #switch(i) {
+      case 0: continue;
+
+break at:
+      case 0: continue;
+      case 1: #return42(); break;
+      default: return;
+
+break at:
+function return42() {
+  #return 42;
+}
+
+break at:
+function return42() {
+  return 42;#
+}
+
+break at:
+      case 0: continue;
+      case 1: return42(); #break;
+      default: return;
+
+break at:
+function testSwitch() {
+  for (var i = 0; i < 3; ++#i) {
+    switch(i) {
+
+break at:
+function testSwitch() {
+  for (var i = 0; i #< 3; ++i) {
+    switch(i) {
+
+break at:
+  for (var i = 0; i < 3; ++i) {
+    #switch(i) {
+      case 0: continue;
+
+break at:
+      case 1: return42(); break;
+      default: #return;
+    }
+
+break at:
+      case 1: return42(); break;
+      default: return;#
+    }
+
+
+Running test: testGenerator
+break at:
+function testGenerator() {
+  var gen = #idMaker();
+  return42();
+
+break at:
+function* idMaker() {
+  #yield 1;
+  yield 2;
+
+break at:
+  gen.next().value;
+  #debugger;
+  gen.next().value;
+
+break at:
+  debugger;
+  gen.#next().value;
+  return42();
+
+break at:
+  yield 1;
+  #yield 2;
+  yield 3;
+
+break at:
+  yield 2;
+  #yield 3;
+}
+
+break at:
+  yield 3;
+#}
+
+
+break at:
+  gen.next().value;
+#}
+
+
+
+Running test: testCaughtException
+break at:
+  try {
+    #throwException()
+  } catch (e) {
+
+break at:
+function throwException() {
+  #throw new Error();
+}
+
+break at:
+  } catch (e) {
+    #return;
+  }
+
+break at:
+  } catch (e) {
+    return;#
+  }
+
+
+Running test: testClasses
+break at:
+  }
+  #new Lion().speak();
+}
+
+break at:
+    constructor(name) {
+      #super(name);
+    }
+
+break at:
+    constructor(name) {
+      #this.name = name;
+    }
+
+break at:
+      this.name = name;
+    #}
+
+
+break at:
+      super(name);
+    #}
+
+
+break at:
+  }
+  new Lion().#speak();
+}
+
+break at:
+    speak() {
+      #super.speak();
+    }
+
+break at:
+    speak() {
+    #}
+  }
+
+break at:
+      super.speak();
+    #}
+  }
+
+break at:
+  new Lion().speak();
+#}
+
+
+
+Running test: testAsyncAwait
+break at:
+async function testAsyncAwait() {
+  #await asyncFoo();
+  await awaitBoo();
+
+break at:
+async function asyncFoo() {
+  #await Promise.resolve().then(v => v * 2);
+  return42();
+
+break at:
+function return42() {
+  #return 42;
+}
+
+break at:
+function return42() {
+  return 42;#
+}
+
+break at:
+async function asyncBoo() {
+  #await Promise.resolve();
+}
+
+
+Running test: testPromiseAsyncWithCode
+break at:
+  var nextTest;
+  var testPromise = #new Promise(resolve => nextTest = resolve);
+  async function main() {
+
+break at:
+  var nextTest;
+  var testPromise = new Promise(resolve => nextTest #= resolve);
+  async function main() {
+
+break at:
+  var nextTest;
+  var testPromise = new Promise(resolve => nextTest = resolve#);
+  async function main() {
+
+break at:
+  }
+  #main();
+  return testPromise;
+
+break at:
+    }
+    #setTimeout(returnCall, 0);
+    await foo();
+
+break at:
+    setTimeout(returnCall, 0);
+    await #foo();
+    await foo();
+
+break at:
+      var resolveNested;
+      var p = #new Promise(resolve => resolveNested = resolve);
+      setTimeout(resolveNested, 0);
+
+break at:
+      var resolveNested;
+      var p = new Promise(resolve => resolveNested #= resolve);
+      setTimeout(resolveNested, 0);
+
+break at:
+      var resolveNested;
+      var p = new Promise(resolve => resolveNested = resolve#);
+      setTimeout(resolveNested, 0);
+
+break at:
+      var p = new Promise(resolve => resolveNested = resolve);
+      #setTimeout(resolveNested, 0);
+      await p;
+
+break at:
+      setTimeout(resolveNested, 0);
+      #await p;
+    }
+
+break at:
+      var resolveNested;
+      var p = #new Promise(resolve => resolveNested = resolve);
+      setTimeout(resolveNested, 0);
+
+break at:
+      var resolveNested;
+      var p = new Promise(resolve => resolveNested #= resolve);
+      setTimeout(resolveNested, 0);
+
+break at:
+      var resolveNested;
+      var p = new Promise(resolve => resolveNested = resolve#);
+      setTimeout(resolveNested, 0);
+
+break at:
+      var p = new Promise(resolve => resolveNested = resolve);
+      #setTimeout(resolveNested, 0);
+      await p;
+
+break at:
+      setTimeout(resolveNested, 0);
+      #await p;
+    }
+
+
+Running test: testPromiseComplex
+break at:
+  var nextTest;
+  var testPromise = #new Promise(resolve => nextTest = resolve);
+  async function main() {
+
+break at:
+  var nextTest;
+  var testPromise = new Promise(resolve => nextTest #= resolve);
+  async function main() {
+
+break at:
+  var nextTest;
+  var testPromise = new Promise(resolve => nextTest = resolve#);
+  async function main() {
+
+break at:
+  }
+  #main();
+  return testPromise;
+
+break at:
+    }
+    var x = #1;
+    var y = 2;
+
+break at:
+    var x = 1;
+    var y = #2;
+    returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 *a)(5));
+
+break at:
+    var y = 2;
+    #returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 *a)(5));
+    nextTest();
+
+break at:
+
+function emptyFunction() {#}
+
+
+break at:
+    var y = 2;
+    returnFunction(emptyFunction(), x++, --y, x => 2 * x, #returnCall())().a = await foo((a => 2 *a)(5));
+    nextTest();
+
+break at:
+function returnCall() {
+  #return return42();
+}
+
+break at:
+function return42() {
+  #return 42;
+}
+
+break at:
+function return42() {
+  return 42;#
+}
+
+break at:
+function returnCall() {
+  return return42();#
+}
+
+break at:
+    var y = 2;
+    #returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 *a)(5));
+    nextTest();
+
+break at:
+function returnFunction() {
+  #return returnObject;
+}
+
+break at:
+function returnFunction() {
+  return returnObject;#
+}
+
+break at:
+    var y = 2;
+    returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())#().a = await foo((a => 2 *a)(5));
+    nextTest();
+
+break at:
+function returnObject() {
+  #return ({ foo: () => 42 });
+}
+
+break at:
+function returnObject() {
+  return ({ foo: () => 42 });#
+}
+
+break at:
+    var y = 2;
+    returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 *a)#(5));
+    nextTest();
+
+break at:
+    var y = 2;
+    returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 #*a)(5));
+    nextTest();
+
+break at:
+    var y = 2;
+    returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await foo((a => 2 *a#)(5));
+    nextTest();
+
+break at:
+    var y = 2;
+    returnFunction(emptyFunction(), x++, --y, x => 2 * x, returnCall())().a = await #foo((a => 2 *a)(5));
+    nextTest();
+
+break at:
+    async function foo() {
+      #await Promise.resolve();
+      return 42;
+
diff --git a/src/v8/test/inspector/debugger/step-into-nested-arrow-expected.txt b/src/v8/test/inspector/debugger/step-into-nested-arrow-expected.txt
new file mode 100644
index 0000000..5061a96
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-into-nested-arrow-expected.txt
@@ -0,0 +1,17 @@
+Checks that stepInto nested arrow function doesn't produce crash.
+paused
+(anonymous) (test.js:2:0)
+(anonymous) (:0:6)
+paused
+rec (test.js:1:19)
+(anonymous) (test.js:2:0)
+(anonymous) (:0:6)
+paused
+rec (test.js:2:5)
+(anonymous) (test.js:2:0)
+(anonymous) (:0:6)
+paused
+(anonymous) (test.js:2:5)
+(anonymous) (:0:6)
+paused
+(anonymous) (:0:8)
diff --git a/src/v8/test/inspector/debugger/step-into-nested-arrow.js b/src/v8/test/inspector/debugger/step-into-nested-arrow.js
new file mode 100644
index 0000000..3057967
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-into-nested-arrow.js
@@ -0,0 +1,23 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start(
+    'Checks that stepInto nested arrow function doesn\'t produce crash.');
+
+session.setupScriptMap();
+contextGroup.addScript(`
+const rec = (x) => (y) =>
+rec();
+//# sourceURL=test.js`);
+
+Protocol.Debugger.onPaused(message => {
+  InspectorTest.log("paused");
+  session.logCallFrames(message.params.callFrames);
+  Protocol.Debugger.stepInto();
+})
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setBreakpointByUrl({ url: 'test.js', lineNumber: 2 })
+  .then(() => Protocol.Runtime.evaluate({ expression: 'rec(5)(4)' }))
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/step-into-next-script-expected.txt b/src/v8/test/inspector/debugger/step-into-next-script-expected.txt
new file mode 100644
index 0000000..5fbd13e
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-into-next-script-expected.txt
@@ -0,0 +1,71 @@
+Debugger breaks in next script after stepOut from previous one.
+
+Running test: testStepOut
+test (foo.js:12:2)
+(anonymous) (:0:0)
+
+(anonymous) (:0:5)
+
+(anonymous) (timeout1.js:0:8)
+
+foo (timeout2.js:2:2)
+
+(anonymous) (timeout3.js:0:8)
+
+
+Running test: testStepOver
+(anonymous) (:0:0)
+
+test (foo.js:12:2)
+(anonymous) (:0:0)
+
+test (foo.js:13:0)
+(anonymous) (:0:0)
+
+(anonymous) (:0:5)
+
+(anonymous) (timeout1.js:0:8)
+
+(anonymous) (timeout1.js:0:34)
+
+foo (timeout2.js:2:2)
+
+foo (timeout2.js:2:12)
+
+(anonymous) (timeout3.js:0:8)
+
+(anonymous) (timeout3.js:0:34)
+
+
+Running test: testStepInto
+(anonymous) (:0:0)
+
+test (foo.js:9:2)
+(anonymous) (:0:0)
+
+test (foo.js:10:2)
+(anonymous) (:0:0)
+
+test (foo.js:11:2)
+(anonymous) (:0:0)
+
+test (foo.js:12:2)
+(anonymous) (:0:0)
+
+test (foo.js:13:0)
+(anonymous) (:0:0)
+
+(anonymous) (:0:5)
+
+(anonymous) (timeout1.js:0:8)
+
+(anonymous) (timeout1.js:0:34)
+
+foo (timeout2.js:2:2)
+
+foo (timeout2.js:2:12)
+
+(anonymous) (timeout3.js:0:8)
+
+(anonymous) (timeout3.js:0:34)
+
diff --git a/src/v8/test/inspector/debugger/step-into-next-script.js b/src/v8/test/inspector/debugger/step-into-next-script.js
new file mode 100644
index 0000000..80e9a91
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-into-next-script.js
@@ -0,0 +1,51 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Debugger breaks in next script after stepOut from previous one.');
+
+contextGroup.addScript(`
+function test() {
+  setTimeout('var a = 1;//# sourceURL=timeout1.js', 0);
+  setTimeout(foo, 0);
+  setTimeout('var a = 3;//# sourceURL=timeout3.js', 0);
+  debugger;
+}
+//# sourceURL=foo.js`, 7, 26);
+
+contextGroup.addScript(`
+function foo() {
+  return 42;
+}
+//# sourceURL=timeout2.js`)
+
+session.setupScriptMap();
+var stepAction;
+Protocol.Debugger.onPaused(message => {
+  session.logCallFrames(message.params.callFrames);
+  InspectorTest.log('');
+  Protocol.Debugger[stepAction]();
+});
+Protocol.Debugger.enable()
+InspectorTest.runTestSuite([
+  function testStepOut(next) {
+    stepAction = 'stepOut';
+    Protocol.Runtime.evaluate({ expression: 'test()' })
+      .then(() => InspectorTest.waitForPendingTasks())
+      .then(next);
+  },
+
+  function testStepOver(next) {
+    stepAction = 'stepOver';
+    Protocol.Runtime.evaluate({ expression: 'test()' })
+      .then(() => InspectorTest.waitForPendingTasks())
+      .then(next);
+  },
+
+  function testStepInto(next) {
+    stepAction = 'stepInto';
+    Protocol.Runtime.evaluate({ expression: 'test()' })
+      .then(() => InspectorTest.waitForPendingTasks())
+      .then(next);
+  }
+]);
diff --git a/src/v8/test/inspector/debugger/step-into.js b/src/v8/test/inspector/debugger/step-into.js
new file mode 100644
index 0000000..0c15d8a
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-into.js
@@ -0,0 +1,32 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks possible break locations.');
+
+session.setupScriptMap();
+Protocol.Debugger.onPaused(message => {
+  var frames = message.params.callFrames;
+  if (frames.length === 1) {
+    Protocol.Debugger.stepInto();
+    return;
+  }
+  var scriptId = frames[0].location.scriptId;
+  InspectorTest.log('break at:');
+  session.logSourceLocation(frames[0].location)
+    .then(() => Protocol.Debugger.stepInto());
+});
+
+contextGroup.loadScript('test/inspector/debugger/resources/break-locations.js');
+
+Protocol.Debugger.enable();
+Protocol.Runtime.evaluate({ expression: 'Object.keys(this).filter(name => name.indexOf(\'test\') === 0)', returnByValue: true })
+  .then(runTests);
+
+function runTests(message) {
+  var tests = message.result.result.value;
+  InspectorTest.runTestSuite(tests.map(test => eval(`(function ${test}(next) {
+    Protocol.Runtime.evaluate({ expression: 'debugger; ${test}()', awaitPromise: ${test.indexOf('testPromise') === 0}})
+      .then(next);
+  })`)));
+}
diff --git a/src/v8/test/inspector/debugger/step-out-async-await-expected.txt b/src/v8/test/inspector/debugger/step-out-async-await-expected.txt
new file mode 100644
index 0000000..7b58576
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-out-async-await-expected.txt
@@ -0,0 +1,67 @@
+StepOut from return position of async function.
+
+Running test: testStepInto
+      p.then(() => 1);
+      #debugger;
+      return p;
+
+      debugger;
+      #return p;
+    }
+
+      return p;
+    #}
+    await foo();
+
+      await p;
+      p.then(() => #1);
+      debugger;
+
+
+Running test: testStepOver
+      p.then(() => 1);
+      #debugger;
+      return p;
+
+      debugger;
+      #return p;
+    }
+
+      return p;
+    #}
+    await foo();
+
+      await p;
+      p.then(() => #1);
+      debugger;
+
+      await p;
+      p.then(() => 1#);
+      debugger;
+
+    await foo();
+  #}
+
+
+
+Running test: testStepOut
+      p.then(() => 1);
+      #debugger;
+      return p;
+
+      debugger;
+      #return p;
+    }
+
+      return p;
+    #}
+    await foo();
+
+      await p;
+      p.then(() => #1);
+      debugger;
+
+    await foo();
+  #}
+
+
diff --git a/src/v8/test/inspector/debugger/step-out-async-await.js b/src/v8/test/inspector/debugger/step-out-async-await.js
new file mode 100644
index 0000000..ff83b82
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-out-async-await.js
@@ -0,0 +1,72 @@
+// Copyright 2017 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.
+
+// TODO(kozyatinskiy): on StepOut and probably StepNext at return position
+// of async generator we should break at next instruction of resumed generator
+// instead of next scheduled microtask.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('StepOut from return position of async function.');
+
+contextGroup.addScript(`
+  async function testFunction() {
+    async function foo() {
+      var p = Promise.resolve();
+      await p;
+      p.then(() => 1);
+      debugger;
+      return p;
+    }
+    await foo();
+  }
+`);
+
+session.setupScriptMap();
+Protocol.Debugger.enable();
+InspectorTest.runAsyncTestSuite([
+  async function testStepInto() {
+    Protocol.Runtime.evaluate({expression: 'testFunction()'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.resume();
+  },
+
+  async function testStepOver() {
+    Protocol.Runtime.evaluate({expression: 'testFunction()'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.resume();
+  },
+
+  async function testStepOut() {
+    Protocol.Runtime.evaluate({expression: 'testFunction()'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.resume();
+  },
+]);
+
+function logPauseLocation(message) {
+  return session.logSourceLocation(message.params.callFrames[0].location);
+}
diff --git a/src/v8/test/inspector/debugger/step-over-another-context-group-expected.txt b/src/v8/test/inspector/debugger/step-over-another-context-group-expected.txt
new file mode 100644
index 0000000..c403c15
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-over-another-context-group-expected.txt
@@ -0,0 +1,7 @@
+Checks stepping with more then one context group.
+paused at:
+#debugger
+
+paused at:
+setTimeout(() => #42, 0)
+
diff --git a/src/v8/test/inspector/debugger/step-over-another-context-group.js b/src/v8/test/inspector/debugger/step-over-another-context-group.js
new file mode 100644
index 0000000..758ff84
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-over-another-context-group.js
@@ -0,0 +1,36 @@
+// Copyright 2017 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.
+
+InspectorTest.log('Checks stepping with more then one context group.');
+
+var contextGroup1 = new InspectorTest.ContextGroup();
+var session1 = contextGroup1.connect();
+session1.setupScriptMap();
+
+let contextGroup2 = new InspectorTest.ContextGroup();
+let session2 = contextGroup2.connect();
+session2.setupScriptMap();
+
+(async function test() {
+  await session1.Protocol.Debugger.enable();
+  await session2.Protocol.Debugger.enable({});
+  session1.Protocol.Runtime.evaluate({expression: 'debugger'});
+  session2.Protocol.Runtime.evaluate({expression: 'setTimeout(() => { debugger }, 0)'});
+  session1.Protocol.Runtime.evaluate({expression: 'setTimeout(() => 42, 0)'});
+  await waitPauseAndDumpLocation(session1);
+  session1.Protocol.Debugger.stepOver();
+  await session1.Protocol.Debugger.oncePaused();
+  session1.Protocol.Debugger.stepOver();
+  await waitPauseAndDumpLocation(session1);
+  await session2.Protocol.Debugger.disable({});
+  await session1.Protocol.Debugger.disable();
+  InspectorTest.completeTest();
+})();
+
+async function waitPauseAndDumpLocation(session) {
+  var message = await session.Protocol.Debugger.oncePaused();
+  InspectorTest.log('paused at:');
+  await session.logSourceLocation(message.params.callFrames[0].location);
+  return message;
+}
diff --git a/src/v8/test/inspector/debugger/step-over-caught-exception-expected.txt b/src/v8/test/inspector/debugger/step-over-caught-exception-expected.txt
new file mode 100644
index 0000000..5b72d4c
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-over-caught-exception-expected.txt
@@ -0,0 +1,5 @@
+Tests that stepping over caught exception will pause when asked for
+testFunction:9
+testFunction:11
+testFunction:9
+testFunction:11
diff --git a/src/v8/test/inspector/debugger/step-over-caught-exception.js b/src/v8/test/inspector/debugger/step-over-caught-exception.js
new file mode 100644
index 0000000..c8e711b
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-over-caught-exception.js
@@ -0,0 +1,78 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that stepping over caught exception will pause when asked for');
+
+contextGroup.addScript(
+`function testFunction()
+{
+  function foo()
+  {
+    try {
+      throw new Error();
+    } catch (e) {
+    }
+  }
+  debugger;
+  foo();
+  console.log("completed");
+}`);
+
+Protocol.Debugger.enable();
+Protocol.Runtime.enable();
+step1();
+
+function step1()
+{
+  Protocol.Runtime.evaluate({ "expression": "setTimeout(testFunction, 0);"});
+  var commands = [ "Print", "stepOver", "stepOver", "Print", "resume" ];
+  Protocol.Debugger.onPaused(function(messageObject)
+  {
+    var command = commands.shift();
+    if (command === "Print") {
+      var callFrames = messageObject.params.callFrames;
+      for (var callFrame of callFrames)
+        InspectorTest.log(callFrame.functionName + ":" + callFrame.location.lineNumber);
+      command = commands.shift();
+    }
+    if (command)
+      Protocol.Debugger[command]();
+  });
+
+  Protocol.Runtime.onConsoleAPICalled(function(messageObject)
+  {
+    if (messageObject.params.args[0].value === "completed") {
+      if (commands.length)
+        InspectorTest.log("[FAIL]: execution was resumed too earlier.")
+      step2();
+    }
+  });
+}
+
+function step2()
+{
+  Protocol.Runtime.evaluate({ "expression": "setTimeout(testFunction, 0);"});
+  var commands = [ "Print", "stepOver", "stepInto", "stepOver", "stepOver", "Print", "resume" ];
+  Protocol.Debugger.onPaused(function(messageObject)
+  {
+    var command = commands.shift();
+    if (command === "Print") {
+      var callFrames = messageObject.params.callFrames;
+      for (var callFrame of callFrames)
+        InspectorTest.log(callFrame.functionName + ":" + callFrame.location.lineNumber);
+      command = commands.shift();
+    }
+    if (command)
+      Protocol.Debugger[command]();
+  });
+
+  Protocol.Runtime.onConsoleAPICalled(function(messageObject)
+  {
+    if (messageObject.params.args[0].value === "completed") {
+      if (commands.length)
+        InspectorTest.log("[FAIL]: execution was resumed too earlier.")
+      InspectorTest.completeTest();
+    }
+  });
+}
diff --git a/src/v8/test/inspector/debugger/step-snapshot-expected.txt b/src/v8/test/inspector/debugger/step-snapshot-expected.txt
new file mode 100644
index 0000000..911ca71
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-snapshot-expected.txt
@@ -0,0 +1,35 @@
+Embedding script 'function c(f, ...args) { return f(...args); }'
+Tests that stepping works on snapshotted function
+paused
+  }
+  #debugger;
+  c(f, 2);
+
+paused
+  debugger;
+  #c(f, 2);
+}
+
+paused
+function c(f, ...args) { #return f(...args); }
+
+paused
+  function f(x) {
+    #return x * 2;
+  }
+
+paused
+  function f(x) {
+    return x * 2;#
+  }
+
+paused
+function c(f, ...args) { return f(...args);# }
+
+paused
+  c(f, 2);
+#}
+
+paused
+test(#)
+
diff --git a/src/v8/test/inspector/debugger/step-snapshot.js b/src/v8/test/inspector/debugger/step-snapshot.js
new file mode 100644
index 0000000..a4ecbf2
--- /dev/null
+++ b/src/v8/test/inspector/debugger/step-snapshot.js
@@ -0,0 +1,31 @@
+// Copyright 2017 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.
+
+// Embed a user function in the snapshot and step through it.
+
+// Flags: --embed 'function c(f, ...args) { return f(...args); }'
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that stepping works on snapshotted function');
+session.setupScriptMap();
+
+contextGroup.addScript(`
+function test() {
+  function f(x) {
+    return x * 2;
+  }
+  debugger;
+  c(f, 2);
+}
+//# sourceURL=test.js`);
+
+Protocol.Debugger.onPaused(message => {
+  InspectorTest.log("paused");
+  var frames = message.params.callFrames;
+  session.logSourceLocation(frames[0].location);
+  Protocol.Debugger.stepInto();
+})
+
+Protocol.Debugger.enable()
+  .then(() => Protocol.Runtime.evaluate({ expression: 'test()' }))
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/stepping-after-get-possible-breakpoints-expected.txt b/src/v8/test/inspector/debugger/stepping-after-get-possible-breakpoints-expected.txt
new file mode 100644
index 0000000..67f3830
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-after-get-possible-breakpoints-expected.txt
@@ -0,0 +1,11 @@
+Tests that stepping works after calling getPossibleBreakpoints
+-- call boo:
+(top)
+(top)
+boo
+(top)
+-- call foo:
+(top)
+(top)
+foo
+(top)
diff --git a/src/v8/test/inspector/debugger/stepping-after-get-possible-breakpoints.js b/src/v8/test/inspector/debugger/stepping-after-get-possible-breakpoints.js
new file mode 100644
index 0000000..c36a36c
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-after-get-possible-breakpoints.js
@@ -0,0 +1,28 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that stepping works after calling getPossibleBreakpoints');
+
+contextGroup.addScript(`
+function boo() {}
+boo();
+function foo() {}
+//# sourceURL=foo.js`);
+
+Protocol.Debugger.onPaused((message) => {
+  InspectorTest.logMessage(message.params.callFrames[0].functionName || "(top)");
+  Protocol.Debugger.stepInto();
+});
+var scriptId;
+Protocol.Debugger.onScriptParsed(message => {
+  if (message.params.url === 'foo.js')
+    scriptId = message.params.scriptId;
+});
+Protocol.Debugger.enable()
+  .then(() => Protocol.Debugger.getPossibleBreakpoints({start: {scriptId, lineNumber:0,columnNumber:0}}))
+  .then(() => InspectorTest.log('-- call boo:'))
+  .then(() => Protocol.Runtime.evaluate({ expression: 'debugger; boo();'}))
+  .then(() => InspectorTest.log('-- call foo:'))
+  .then(() => Protocol.Runtime.evaluate({ expression: 'debugger; foo();'}))
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/stepping-and-break-program-api-expected.txt b/src/v8/test/inspector/debugger/stepping-and-break-program-api-expected.txt
new file mode 100644
index 0000000..438177a
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-and-break-program-api-expected.txt
@@ -0,0 +1,19 @@
+Checks that stepping is cleared after breakProgram.
+paused at:
+function callBreakProgram() {
+  #debugger;
+  inspector.breakProgram('reason', '');
+
+paused at:
+  debugger;
+  #inspector.breakProgram('reason', '');
+}
+
+paused at:
+  debugger;
+  inspector.#breakProgram('reason', '');
+}
+
+paused at:
+#debugger;
+
diff --git a/src/v8/test/inspector/debugger/stepping-and-break-program-api.js b/src/v8/test/inspector/debugger/stepping-and-break-program-api.js
new file mode 100644
index 0000000..f54bad8
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-and-break-program-api.js
@@ -0,0 +1,34 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that stepping is cleared after breakProgram.');
+
+contextGroup.addScript(`
+function callBreakProgram() {
+  debugger;
+  inspector.breakProgram('reason', '');
+}`);
+
+session.setupScriptMap();
+(async function test() {
+  Protocol.Debugger.enable();
+  Protocol.Runtime.evaluate({expression: 'callBreakProgram();'});
+  // Should break at this debugger statement, not at end of callBreakProgram.
+  Protocol.Runtime.evaluate({expression: 'setTimeout(\'debugger;\', 0);'});
+  await waitPauseAndDumpLocation();
+  Protocol.Debugger.stepOver();
+  await waitPauseAndDumpLocation();
+  Protocol.Debugger.stepOver();
+  await waitPauseAndDumpLocation();
+  Protocol.Debugger.resume();
+  await waitPauseAndDumpLocation();
+  InspectorTest.completeTest();
+})();
+
+async function waitPauseAndDumpLocation() {
+  var message = await Protocol.Debugger.oncePaused();
+  InspectorTest.log('paused at:');
+  session.logSourceLocation(message.params.callFrames[0].location);
+  return message;
+}
diff --git a/src/v8/test/inspector/debugger/stepping-ignores-injected-script-expected.txt b/src/v8/test/inspector/debugger/stepping-ignores-injected-script-expected.txt
new file mode 100644
index 0000000..5a63493
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-ignores-injected-script-expected.txt
@@ -0,0 +1,2 @@
+Tests that stepping ignores injected script
+InjectedSciptSource was not reached
diff --git a/src/v8/test/inspector/debugger/stepping-ignores-injected-script.js b/src/v8/test/inspector/debugger/stepping-ignores-injected-script.js
new file mode 100644
index 0000000..9021664
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-ignores-injected-script.js
@@ -0,0 +1,21 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that stepping ignores injected script');
+
+Protocol.Debugger.onPaused(message => {
+  let url = session._scriptMap.get(message.params.callFrames[0].location.scriptId).url;
+  if (url !== 'test.js') {
+    InspectorTest.log('InjectedSciptSource on stack.');
+    InspectorTest.completeTest();
+  }
+  Protocol.Debugger.stepInto();
+});
+
+session.setupScriptMap();
+Protocol.Debugger.enable();
+Protocol.Debugger.pause();
+Protocol.Runtime.evaluate({expression: 'console.log(42)//# sourceURL=test.js'})
+  .then(() => InspectorTest.log('InjectedSciptSource was not reached'))
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/stepping-tail-call-expected.txt b/src/v8/test/inspector/debugger/stepping-tail-call-expected.txt
new file mode 100644
index 0000000..95b21b4
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-tail-call-expected.txt
@@ -0,0 +1,177 @@
+Checks stepping over tail calls.
+
+Running test: testStepOver
+f (:2:14)
+f (:3:22)
+f (:3:22)
+f (:3:22)
+(anonymous) (:5:0)
+function f(x) {
+  if (x == 2) #debugger;
+  if (x-- > 0) return f(x);
+
+Debugger.stepOver called
+f (:3:2)
+f (:3:22)
+f (:3:22)
+f (:3:22)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  #if (x-- > 0) return f(x);
+}
+
+Debugger.stepOver called
+f (:3:15)
+f (:3:22)
+f (:3:22)
+f (:3:22)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  if (x-- > 0) #return f(x);
+}
+
+Debugger.stepOver called
+f (:3:27)
+f (:3:22)
+f (:3:22)
+f (:3:22)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  if (x-- > 0) return f(x);#
+}
+
+Debugger.stepOver called
+f (:3:27)
+f (:3:22)
+f (:3:22)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  if (x-- > 0) return f(x);#
+}
+
+Debugger.stepOver called
+f (:3:27)
+f (:3:22)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  if (x-- > 0) return f(x);#
+}
+
+Debugger.stepOver called
+f (:3:27)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  if (x-- > 0) return f(x);#
+}
+
+Debugger.stepOver called
+(anonymous) (:5:5)
+}
+f(5);#
+
+
+Debugger.resume called
+
+Running test: testStepOut
+f (:2:14)
+f (:3:22)
+f (:3:22)
+f (:3:22)
+(anonymous) (:5:0)
+function f(x) {
+  if (x == 2) #debugger;
+  if (x-- > 0) return f(x);
+
+Debugger.stepOut called
+f (:3:27)
+f (:3:22)
+f (:3:22)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  if (x-- > 0) return f(x);#
+}
+
+Debugger.stepOut called
+f (:3:27)
+f (:3:22)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  if (x-- > 0) return f(x);#
+}
+
+Debugger.stepOut called
+f (:3:27)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  if (x-- > 0) return f(x);#
+}
+
+Debugger.stepOut called
+(anonymous) (:5:5)
+}
+f(5);#
+
+
+Debugger.resume called
+
+Running test: testStepOutFromReturn
+f (:2:14)
+f (:3:22)
+f (:3:22)
+f (:3:22)
+(anonymous) (:5:0)
+function f(x) {
+  if (x == 2) #debugger;
+  if (x-- > 0) return f(x);
+
+Debugger.stepOver called
+f (:3:2)
+f (:3:22)
+f (:3:22)
+f (:3:22)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  #if (x-- > 0) return f(x);
+}
+
+Debugger.stepOver called
+f (:3:15)
+f (:3:22)
+f (:3:22)
+f (:3:22)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  if (x-- > 0) #return f(x);
+}
+
+Debugger.stepOut called
+f (:3:27)
+f (:3:22)
+f (:3:22)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  if (x-- > 0) return f(x);#
+}
+
+Debugger.stepOut called
+f (:3:27)
+f (:3:22)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  if (x-- > 0) return f(x);#
+}
+
+Debugger.stepOut called
+f (:3:27)
+(anonymous) (:5:0)
+  if (x == 2) debugger;
+  if (x-- > 0) return f(x);#
+}
+
+Debugger.stepOut called
+(anonymous) (:5:5)
+}
+f(5);#
+
+
+Debugger.resume called
diff --git a/src/v8/test/inspector/debugger/stepping-tail-call.js b/src/v8/test/inspector/debugger/stepping-tail-call.js
new file mode 100644
index 0000000..797df7d
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-tail-call.js
@@ -0,0 +1,81 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks stepping over tail calls.');
+
+session.setupScriptMap();
+InspectorTest.logProtocolCommandCalls('Debugger.pause');
+InspectorTest.logProtocolCommandCalls('Debugger.stepInto');
+InspectorTest.logProtocolCommandCalls('Debugger.stepOver');
+InspectorTest.logProtocolCommandCalls('Debugger.stepOut');
+InspectorTest.logProtocolCommandCalls('Debugger.resume');
+
+let source = `
+function f(x) {
+  if (x == 2) debugger;
+  if (x-- > 0) return f(x);
+}
+f(5);
+`;
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js']});
+InspectorTest.runAsyncTestSuite([
+  async function testStepOver() {
+    Protocol.Runtime.evaluate({expression: source});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testStepOut() {
+    Protocol.Runtime.evaluate({expression: source});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testStepOutFromReturn() {
+    Protocol.Runtime.evaluate({expression: source});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  }
+]);
+
+function logPauseLocation(message) {
+  session.logCallFrames(message.params.callFrames);
+  return session.logSourceLocation(message.params.callFrames[0].location);
+}
diff --git a/src/v8/test/inspector/debugger/stepping-with-blackboxed-ranges-expected.txt b/src/v8/test/inspector/debugger/stepping-with-blackboxed-ranges-expected.txt
new file mode 100644
index 0000000..4c7af7e
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-with-blackboxed-ranges-expected.txt
@@ -0,0 +1,56 @@
+Tests that blackboxed ranges are respected while stepping
+foo: 8:4
+blackboxedBoo: 3:12
+notBlackboxedFoo: 3:12
+blackboxedFoo: 10:12
+notBlackboxedBoo: 17:12
+testFunction: 2:4
+
+Try to set positions: [{"lineNumber":0,"columnNumber":0},{"lineNumber":0,"columnNumber":0}]
+Input positions array is not sorted or contains duplicate values.
+Try to set positions: [{"lineNumber":0,"columnNumber":1},{"lineNumber":0,"columnNumber":0}]
+Input positions array is not sorted or contains duplicate values.
+Try to set positions: [{"lineNumber":0,"columnNumber":-1}]
+Position missing 'column' or 'column' < 0.
+action: stepOut
+notBlackboxedFoo: 4:4
+blackboxedFoo: 10:12
+notBlackboxedBoo: 17:12
+testFunction: 2:4
+
+action: stepOut
+notBlackboxedBoo: 18:4
+testFunction: 2:4
+
+action: stepOut
+testFunction: 3:4
+
+action: stepInto
+notBlackboxedBoo: 16:12
+testFunction: 3:4
+
+action: stepOver
+action: stepInto
+notBlackboxedFoo: 2:12
+blackboxedFoo: 10:12
+notBlackboxedBoo: 17:12
+testFunction: 3:4
+
+action: stepOver
+action: stepInto
+foo: 8:4
+blackboxedBoo: 3:12
+notBlackboxedFoo: 3:12
+blackboxedFoo: 10:12
+notBlackboxedBoo: 17:12
+testFunction: 3:4
+
+action: stepOver
+action: stepInto
+foo: 9:15
+blackboxedBoo: 3:12
+notBlackboxedFoo: 3:12
+blackboxedFoo: 10:12
+notBlackboxedBoo: 17:12
+testFunction: 3:4
+
diff --git a/src/v8/test/inspector/debugger/stepping-with-blackboxed-ranges.js b/src/v8/test/inspector/debugger/stepping-with-blackboxed-ranges.js
new file mode 100644
index 0000000..c1029a8
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-with-blackboxed-ranges.js
@@ -0,0 +1,135 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that blackboxed ranges are respected while stepping');
+
+contextGroup.addScript(
+`function blackboxedBoo()
+{
+    var a = 42;
+    var b = foo();
+    return a + b;
+}
+//# sourceURL=blackboxed-script.js`);
+
+contextGroup.addScript(
+`function notBlackboxedFoo()
+{
+    var a = 42;
+    var b = blackboxedBoo();
+    return a + b;
+}
+
+function blackboxedFoo()
+{
+    var a = 42;
+    var b = notBlackboxedFoo();
+    return a + b;
+}
+
+function notBlackboxedBoo()
+{
+    var a = 42;
+    var b = blackboxedFoo();
+    return a + b;
+}
+//# sourceURL=mixed-source.js`);
+
+contextGroup.addScript(
+`function testFunction()
+{
+    notBlackboxedBoo(); // for setup ranges and stepOut
+    notBlackboxedBoo(); // for stepIn
+}
+
+function foo()
+{
+    debugger;
+    return 239;
+}`);
+
+Protocol.Debugger.oncePaused().then(setBlackboxedScriptRanges);
+Protocol.Debugger.enable().then(callTestFunction);
+
+function callTestFunction(response)
+{
+  Protocol.Runtime.evaluate({ expression: "setTimeout(testFunction, 0);"});
+}
+
+function setBlackboxedScriptRanges(response)
+{
+  var callFrames = response.params.callFrames;
+  printCallFrames(callFrames);
+  Protocol.Debugger.setBlackboxedRanges({
+    scriptId: callFrames[1].location.scriptId,
+    positions: [ { lineNumber: 0, columnNumber: 0 } ] // blackbox ranges for blackboxed.js
+  }).then(setIncorrectRanges.bind(null, callFrames[2].location.scriptId));
+}
+
+var incorrectPositions = [
+    [ { lineNumber: 0, columnNumber: 0 }, { lineNumber: 0, columnNumber: 0 } ],
+    [ { lineNumber: 0, columnNumber: 1 }, { lineNumber: 0, columnNumber: 0 } ],
+    [ { lineNumber: 0, columnNumber: -1 } ],
+];
+
+function setIncorrectRanges(scriptId, response)
+{
+  if (response.error)
+    InspectorTest.log(response.error.message);
+  var positions = incorrectPositions.shift();
+  if (!positions) {
+    setMixedSourceRanges(scriptId);
+    return;
+  }
+  InspectorTest.log("Try to set positions: " + JSON.stringify(positions));
+  Protocol.Debugger.setBlackboxedRanges({
+    scriptId: scriptId,
+    positions: positions
+  }).then(setIncorrectRanges.bind(null, scriptId));
+}
+
+function setMixedSourceRanges(scriptId)
+{
+  Protocol.Debugger.onPaused(runAction);
+  Protocol.Debugger
+      .setBlackboxedRanges({
+        scriptId: scriptId,
+        positions: [
+          {lineNumber: 6, columnNumber: 0},
+          {lineNumber: 14, columnNumber: 0}
+        ]  // blackbox ranges for mixed.js
+      })
+      .then(runAction);
+}
+
+var actions = [ "stepOut", "print", "stepOut", "print", "stepOut", "print",
+    "stepInto", "print", "stepOver", "stepInto", "print", "stepOver", "stepInto", "print",
+    "stepOver", "stepInto", "print" ];
+
+function runAction(response)
+{
+  var action = actions.shift();
+  if (!action) {
+    InspectorTest.completeTest();
+    return;
+  }
+
+  if (action === "print") {
+    printCallFrames(response.params.callFrames);
+    runAction({});
+  } else {
+    InspectorTest.log("action: " + action);
+    Protocol.Debugger[action]();
+  }
+}
+
+function printCallFrames(callFrames)
+{
+  var topCallFrame = callFrames[0];
+  if (topCallFrame.functionName.startsWith("blackboxed"))
+    InspectorTest.log("FAIL: blackboxed function in top call frame");
+  for (var callFrame of callFrames)
+    InspectorTest.log(callFrame.functionName + ": " + callFrame.location.lineNumber + ":" + callFrame.location.columnNumber);
+  InspectorTest.log("");
+}
diff --git a/src/v8/test/inspector/debugger/stepping-with-exposed-injected-script-expected.txt b/src/v8/test/inspector/debugger/stepping-with-exposed-injected-script-expected.txt
new file mode 100644
index 0000000..65c32c3
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-with-exposed-injected-script-expected.txt
@@ -0,0 +1,2 @@
+Tests that stepping does not ignore injected script when passed a flag
+InjectedSciptSource on stack.
diff --git a/src/v8/test/inspector/debugger/stepping-with-exposed-injected-script.js b/src/v8/test/inspector/debugger/stepping-with-exposed-injected-script.js
new file mode 100644
index 0000000..d608137
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-with-exposed-injected-script.js
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+// Flags: --expose-inspector-scripts
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that stepping does not ignore injected script when passed a flag');
+
+Protocol.Debugger.onPaused(message => {
+  let url = session._scriptMap.get(message.params.callFrames[0].location.scriptId).url;
+  if (url !== 'test.js') {
+    InspectorTest.log('InjectedSciptSource on stack.');
+    InspectorTest.completeTest();
+  }
+  Protocol.Debugger.stepInto();
+});
+
+session.setupScriptMap();
+Protocol.Debugger.enable();
+Protocol.Debugger.pause();
+Protocol.Runtime.evaluate({expression: 'console.log(42)//# sourceURL=test.js'})
+  .then(() => InspectorTest.log('InjectedSciptSource was not reached'))
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/debugger/stepping-with-natives-and-frameworks-expected.txt b/src/v8/test/inspector/debugger/stepping-with-natives-and-frameworks-expected.txt
new file mode 100644
index 0000000..ac26a16
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-with-natives-and-frameworks-expected.txt
@@ -0,0 +1,310 @@
+Stepping with natives and frameworks.
+
+Running test: testNativeCodeStepOut
+Debugger.pause called
+#[1,2].map(v => v);
+
+Debugger.stepInto called
+[1,2].map(v => #v);
+
+Debugger.stepOut called
+[1,2].map(v => v)#;
+
+Debugger.resume called
+
+Running test: testNativeCodeStepOver
+Debugger.pause called
+#[1,2].map(v => v);
+
+Debugger.stepInto called
+[1,2].map(v => #v);
+
+Debugger.stepOver called
+[1,2].map(v => v#);
+
+Debugger.stepOver called
+[1,2].map(v => #v);
+
+Debugger.stepOver called
+[1,2].map(v => v#);
+
+Debugger.stepOver called
+[1,2].map(v => v)#;
+
+Debugger.resume called
+
+Running test: testNativeCodeStepInto
+Debugger.pause called
+#[1,2].map(v => v);
+
+Debugger.stepInto called
+[1,2].map(v => #v);
+
+Debugger.stepInto called
+[1,2].map(v => v#);
+
+Debugger.stepInto called
+[1,2].map(v => #v);
+
+Debugger.stepInto called
+[1,2].map(v => v#);
+
+Debugger.stepInto called
+[1,2].map(v => v)#;
+
+Debugger.resume called
+
+Running test: testFrameworkCodeStepInto
+Debugger.pause called
+#callAll(() => 1, () => 2);
+
+Debugger.stepInto called
+callAll(() => #1, () => 2);
+
+Debugger.stepInto called
+callAll(() => 1#, () => 2);
+
+Debugger.stepInto called
+callAll(() => 1, () => #2);
+
+Debugger.stepInto called
+callAll(() => 1, () => 2#);
+
+Debugger.stepInto called
+callAll(() => 1, () => 2)#;
+
+Debugger.resume called
+
+Running test: testFrameworkCodeStepOver
+Debugger.pause called
+#callAll(() => 1, () => 2);
+
+Debugger.stepInto called
+callAll(() => #1, () => 2);
+
+Debugger.stepOver called
+callAll(() => 1#, () => 2);
+
+Debugger.stepOver called
+callAll(() => 1, () => #2);
+
+Debugger.stepOver called
+callAll(() => 1, () => 2#);
+
+Debugger.stepOver called
+callAll(() => 1, () => 2)#;
+
+Debugger.resume called
+
+Running test: testFrameworkCodeStepOut
+Debugger.pause called
+#callAll(() => 1, () => 2);
+
+Debugger.stepInto called
+callAll(() => #1, () => 2);
+
+Debugger.stepOut called
+callAll(() => 1, () => #2);
+
+Debugger.stepOut called
+callAll(() => 1, () => 2)#;
+
+Debugger.resume called
+
+Running test: testFrameworkNextCallDeeperStepOut
+Debugger.pause called
+#callAll(() => 1, callAll.bind(null, () => 2));
+
+Debugger.stepInto called
+callAll(() => #1, callAll.bind(null, () => 2));
+
+Debugger.stepOut called
+callAll(() => 1, callAll.bind(null, () => #2));
+
+Debugger.stepOut called
+callAll(() => 1, callAll.bind(null, () => 2))#;
+
+Debugger.resume called
+
+Running test: testFrameworkNextCallDeeperStepOutSameFunction
+Debugger.pause called
+#callAll(foo, callAll.bind(null, foo));
+
+Debugger.stepInto called
+foo = () => #1
+
+Debugger.stepOut called
+callAll(foo, callAll.bind(null, foo))#;
+
+Debugger.resume called
+
+Running test: testFrameworkNextCallDeeperStepInto
+Debugger.pause called
+#callAll(() => 1, callAll.bind(null, () => 2));
+
+Debugger.stepInto called
+callAll(() => #1, callAll.bind(null, () => 2));
+
+Debugger.stepOver called
+callAll(() => 1#, callAll.bind(null, () => 2));
+
+Debugger.stepOver called
+callAll(() => 1, callAll.bind(null, () => #2));
+
+Debugger.stepOver called
+callAll(() => 1, callAll.bind(null, () => 2#));
+
+Debugger.stepOver called
+callAll(() => 1, callAll.bind(null, () => 2))#;
+
+Debugger.resume called
+
+Running test: testFrameworkNextCallDeeperStepOver
+Debugger.pause called
+#callAll(() => 1, callAll.bind(null, () => 2));
+
+Debugger.stepInto called
+callAll(() => #1, callAll.bind(null, () => 2));
+
+Debugger.stepOver called
+callAll(() => 1#, callAll.bind(null, () => 2));
+
+Debugger.stepOver called
+callAll(() => 1, callAll.bind(null, () => #2));
+
+Debugger.stepOver called
+callAll(() => 1, callAll.bind(null, () => 2#));
+
+Debugger.stepOver called
+callAll(() => 1, callAll.bind(null, () => 2))#;
+
+Debugger.resume called
+
+Running test: testFrameworkCurrentCallDeeperStepOut
+Debugger.pause called
+#callAll(callAll.bind(null, () => 1), () => 2);
+
+Debugger.stepInto called
+callAll(callAll.bind(null, () => #1), () => 2);
+
+Debugger.stepOut called
+callAll(callAll.bind(null, () => 1), () => #2);
+
+Debugger.stepOut called
+callAll(callAll.bind(null, () => 1), () => 2)#;
+
+Debugger.resume called
+
+Running test: testFrameworkCurrentCallDeeperStepOutSameFunction
+Debugger.pause called
+#callAll(callAll.bind(null, foo), foo);
+
+Debugger.stepInto called
+foo = () => #1
+
+Debugger.stepOut called
+callAll(callAll.bind(null, foo), foo)#;
+
+Debugger.resume called
+
+Running test: testFrameworkCurrentCallDeeperStepOver
+Debugger.pause called
+#callAll(callAll.bind(null, () => 1), () => 2);
+
+Debugger.stepInto called
+callAll(callAll.bind(null, () => #1), () => 2);
+
+Debugger.stepOver called
+callAll(callAll.bind(null, () => 1#), () => 2);
+
+Debugger.stepOver called
+callAll(callAll.bind(null, () => 1), () => #2);
+
+Debugger.stepOver called
+callAll(callAll.bind(null, () => 1), () => 2#);
+
+Debugger.stepOver called
+callAll(callAll.bind(null, () => 1), () => 2)#;
+
+Debugger.resume called
+
+Running test: testFrameworkCurrentCallDeeperStepInto
+Debugger.pause called
+#callAll(callAll.bind(null, () => 1), () => 2);
+
+Debugger.stepInto called
+callAll(callAll.bind(null, () => #1), () => 2);
+
+Debugger.stepInto called
+callAll(callAll.bind(null, () => 1#), () => 2);
+
+Debugger.stepInto called
+callAll(callAll.bind(null, () => 1), () => #2);
+
+Debugger.stepInto called
+callAll(callAll.bind(null, () => 1), () => 2#);
+
+Debugger.stepInto called
+callAll(callAll.bind(null, () => 1), () => 2)#;
+
+Debugger.resume called
+
+Running test: testFrameworkStepOverMixed
+Debugger.pause called
+#callAll(foo, foo, () => 2);
+
+Debugger.stepInto called
+foo = () => #1
+
+Debugger.stepOver called
+foo = () => 1#
+
+Debugger.stepOver called
+foo = () => #1
+
+Debugger.stepOver called
+foo = () => 1#
+
+Debugger.stepOver called
+callAll(foo, foo, () => #2);
+
+Debugger.stepOver called
+callAll(foo, foo, () => 2#);
+
+Debugger.stepOver called
+callAll(foo, foo, () => 2)#;
+
+Debugger.resume called
+
+Running test: testFrameworkStepOutMixed
+Debugger.pause called
+#callAll(foo, foo, () => 2);
+
+Debugger.stepInto called
+foo = () => #1
+
+Debugger.stepOut called
+callAll(foo, foo, () => #2);
+
+Debugger.stepOut called
+callAll(foo, foo, () => 2)#;
+
+Debugger.resume called
+
+Running test: testStepOutFrameworkSameFunctionAtReturn
+Debugger.pause called
+#callAll(foo, foo, () => 2);
+
+Debugger.stepInto called
+foo = () => #1
+
+Debugger.stepOver called
+foo = () => 1#
+
+Debugger.stepOut called
+callAll(foo, foo, () => #2);
+
+Debugger.stepOut called
+callAll(foo, foo, () => 2)#;
+
+Debugger.resume called
diff --git a/src/v8/test/inspector/debugger/stepping-with-natives-and-frameworks.js b/src/v8/test/inspector/debugger/stepping-with-natives-and-frameworks.js
new file mode 100644
index 0000000..c6648ec
--- /dev/null
+++ b/src/v8/test/inspector/debugger/stepping-with-natives-and-frameworks.js
@@ -0,0 +1,300 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Stepping with natives and frameworks.');
+
+contextGroup.addScript(`
+function callAll() {
+  for (var f of arguments)
+    f();
+}
+//# sourceURL=framework.js`);
+
+session.setupScriptMap();
+InspectorTest.logProtocolCommandCalls('Debugger.pause');
+InspectorTest.logProtocolCommandCalls('Debugger.stepInto');
+InspectorTest.logProtocolCommandCalls('Debugger.stepOver');
+InspectorTest.logProtocolCommandCalls('Debugger.stepOut');
+InspectorTest.logProtocolCommandCalls('Debugger.resume');
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js']});
+InspectorTest.runAsyncTestSuite([
+  async function testNativeCodeStepOut() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: '[1,2].map(v => v);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testNativeCodeStepOver() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: '[1,2].map(v => v);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testNativeCodeStepInto() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: '[1,2].map(v => v);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkCodeStepInto() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: 'callAll(() => 1, () => 2);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkCodeStepOver() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: 'callAll(() => 1, () => 2);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkCodeStepOut() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({expression: 'callAll(() => 1, () => 2);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkNextCallDeeperStepOut() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({
+      expression: 'callAll(() => 1, callAll.bind(null, () => 2));'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkNextCallDeeperStepOutSameFunction() {
+    await Protocol.Runtime.evaluate({expression: 'foo = () => 1'});
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({
+      expression: 'callAll(foo, callAll.bind(null, foo));'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkNextCallDeeperStepInto() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({
+      expression: 'callAll(() => 1, callAll.bind(null, () => 2));'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkNextCallDeeperStepOver() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({
+      expression: 'callAll(() => 1, callAll.bind(null, () => 2));'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkCurrentCallDeeperStepOut() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({
+      expression: 'callAll(callAll.bind(null, () => 1), () => 2);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkCurrentCallDeeperStepOutSameFunction() {
+    await Protocol.Runtime.evaluate({expression: 'foo = () => 1'});
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({
+      expression: 'callAll(callAll.bind(null, foo), foo);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkCurrentCallDeeperStepOver() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({
+      expression: 'callAll(callAll.bind(null, () => 1), () => 2);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkCurrentCallDeeperStepInto() {
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({
+      expression: 'callAll(callAll.bind(null, () => 1), () => 2);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkStepOverMixed() {
+    await Protocol.Runtime.evaluate({expression: 'foo = () => 1'});
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({
+      expression: 'callAll(foo, foo, () => 2);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testFrameworkStepOutMixed() {
+    await Protocol.Runtime.evaluate({expression: 'foo = () => 1'});
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({
+      expression: 'callAll(foo, foo, () => 2);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  },
+
+  async function testStepOutFrameworkSameFunctionAtReturn() {
+    await Protocol.Runtime.evaluate({expression: 'foo = () => 1'});
+    Protocol.Debugger.pause();
+    Protocol.Runtime.evaluate({
+      expression: 'callAll(foo, foo, () => 2);'});
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepInto();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOver();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    Protocol.Debugger.stepOut();
+    await logPauseLocation(await Protocol.Debugger.oncePaused());
+    await Protocol.Debugger.resume();
+  }
+]);
+
+function logPauseLocation(message) {
+  return session.logSourceLocation(message.params.callFrames[0].location);
+}
diff --git a/src/v8/test/inspector/debugger/suspended-generator-scopes-expected.txt b/src/v8/test/inspector/debugger/suspended-generator-scopes-expected.txt
new file mode 100644
index 0000000..57dc2aa
--- /dev/null
+++ b/src/v8/test/inspector/debugger/suspended-generator-scopes-expected.txt
@@ -0,0 +1,55 @@
+Tests that suspended generators produce scopes
+
+Running test: testScopesPaused
+[
+    [0] : {
+        configurable : true
+        enumerable : true
+        isOwn : true
+        name : b
+        value : {
+            description : 42
+            type : number
+            value : 42
+        }
+        writable : true
+    }
+    [1] : {
+        configurable : true
+        enumerable : true
+        isOwn : true
+        name : a
+        value : {
+            description : 420
+            type : number
+            value : 420
+        }
+        writable : true
+    }
+]
+
+Running test: testScopesNonPaused
+[
+    [0] : {
+        configurable : true
+        enumerable : true
+        isOwn : true
+        name : b
+        value : {
+            type : undefined
+        }
+        writable : true
+    }
+    [1] : {
+        configurable : true
+        enumerable : true
+        isOwn : true
+        name : a
+        value : {
+            description : 430
+            type : number
+            value : 430
+        }
+        writable : true
+    }
+]
diff --git a/src/v8/test/inspector/debugger/suspended-generator-scopes.js b/src/v8/test/inspector/debugger/suspended-generator-scopes.js
new file mode 100644
index 0000000..55a1fd5
--- /dev/null
+++ b/src/v8/test/inspector/debugger/suspended-generator-scopes.js
@@ -0,0 +1,69 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that suspended generators produce scopes');
+
+contextGroup.addScript(`
+function *gen(a) {
+  var b = 42;
+  yield a;
+  return b;
+}
+
+function testSuspendedGenerator() {
+  var g = gen(420);
+  g.next();
+  debugger;
+  return g;
+}`);
+
+InspectorTest.runAsyncTestSuite([
+  async function testScopesPaused() {
+    Protocol.Debugger.enable();
+    Protocol.Runtime.evaluate({expression: 'testSuspendedGenerator()'});
+    let {params:{callFrames:[callFrame]}} = await Protocol.Debugger.oncePaused();
+    // Current local scope.
+    let localScope = callFrame.scopeChain.find(scope => scope.type === 'local');
+    let variables = (await Protocol.Runtime.getProperties({
+      objectId: localScope.object.objectId
+    })).result.result;
+    let genObjectId =
+      variables.find(variable => variable.name === 'g').value.objectId;
+    let {result:{internalProperties}} = await Protocol.Runtime.getProperties({
+      objectId: genObjectId
+    });
+    // Generator [[Scopes]].
+    let scopes = internalProperties.find(prop => prop.name === '[[Scopes]]');
+    let {result:{result}} = await Protocol.Runtime.getProperties({
+      objectId: scopes.value.objectId
+    });
+    // Locals from generator.
+    let scope = result.find(scope => scope.value.description === 'Local (gen)');
+    ({result:{result}} = await Protocol.Runtime.getProperties({
+      objectId: scope.value.objectId
+    }));
+    InspectorTest.logMessage(result);
+    await Protocol.Debugger.disable();
+  },
+
+  async function testScopesNonPaused() {
+    let {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({
+      expression: 'gen(430)'
+    });
+    let {result:{internalProperties}} = await Protocol.Runtime.getProperties({
+      objectId
+    });
+    // Generator [[Scopes]].
+    let scopes = internalProperties.find(prop => prop.name === '[[Scopes]]');
+    let {result:{result}} = await Protocol.Runtime.getProperties({
+      objectId: scopes.value.objectId
+    });
+    // Locals from generator.
+    let scope = result.find(scope => scope.value.description === 'Local (gen)');
+    ({result:{result}} = await Protocol.Runtime.getProperties({
+      objectId: scope.value.objectId
+    }));
+    InspectorTest.logMessage(result);
+  }
+]);
diff --git a/src/v8/test/inspector/debugger/update-call-frame-scopes-expected.txt b/src/v8/test/inspector/debugger/update-call-frame-scopes-expected.txt
new file mode 100644
index 0000000..acad9ce
--- /dev/null
+++ b/src/v8/test/inspector/debugger/update-call-frame-scopes-expected.txt
@@ -0,0 +1,7 @@
+Tests updating call frame scopes
+Paused on 'debugger;'
+Variable value changed
+Stacktrace re-read again
+Scope variables downloaded anew
+New variable is 55, expected is 55, old was: 2
+SUCCESS
diff --git a/src/v8/test/inspector/debugger/update-call-frame-scopes.js b/src/v8/test/inspector/debugger/update-call-frame-scopes.js
new file mode 100644
index 0000000..e0b7307
--- /dev/null
+++ b/src/v8/test/inspector/debugger/update-call-frame-scopes.js
@@ -0,0 +1,65 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests updating call frame scopes');
+
+contextGroup.addScript(
+`function TestFunction()
+{
+    var a = 2;
+    debugger;
+    debugger;
+}`);
+
+var newVariableValue = 55;
+
+Protocol.Debugger.enable();
+
+Protocol.Debugger.oncePaused().then(handleDebuggerPaused);
+
+Protocol.Runtime.evaluate({ "expression": "setTimeout(TestFunction, 0)" });
+
+function handleDebuggerPaused(messageObject)
+{
+  InspectorTest.log("Paused on 'debugger;'");
+
+  var topFrame = messageObject.params.callFrames[0];
+  var topFrameId = topFrame.callFrameId;
+  Protocol.Debugger.evaluateOnCallFrame({ "callFrameId": topFrameId, "expression": "a = " + newVariableValue }).then(callbackChangeValue);
+}
+
+function callbackChangeValue(response)
+{
+  InspectorTest.log("Variable value changed");
+  Protocol.Debugger.oncePaused().then(callbackGetBacktrace);
+  Protocol.Debugger.resume();
+}
+
+function callbackGetBacktrace(response)
+{
+  InspectorTest.log("Stacktrace re-read again");
+  var localScope = response.params.callFrames[0].scopeChain[0];
+  Protocol.Runtime.getProperties({ "objectId": localScope.object.objectId }).then(callbackGetProperties);
+}
+
+function callbackGetProperties(response)
+{
+  InspectorTest.log("Scope variables downloaded anew");
+  var varNamedA;
+  var propertyList = response.result.result;
+  for (var i = 0; i < propertyList.length; i++) {
+    if (propertyList[i].name === "a") {
+      varNamedA = propertyList[i];
+      break;
+    }
+  }
+  if (varNamedA) {
+    var actualValue = varNamedA.value.value;
+    InspectorTest.log("New variable is " + actualValue + ", expected is " + newVariableValue + ", old was: 2");
+    InspectorTest.log(actualValue === newVariableValue ? "SUCCESS" : "FAIL");
+  } else {
+    InspectorTest.log("Failed to find variable in scope");
+  }
+  InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/debugger/wasm-get-breakable-locations-expected.txt b/src/v8/test/inspector/debugger/wasm-get-breakable-locations-expected.txt
new file mode 100644
index 0000000..96c7a64
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-get-breakable-locations-expected.txt
@@ -0,0 +1,88 @@
+Tests breakable locations in wasm
+Running testFunction...
+Script nr 0 parsed. URL: v8://test/setup
+Script nr 1 parsed. URL: v8://test/runTestFunction
+Script nr 2 parsed. URL: wasm://wasm/wasm-354ada0e/wasm-354ada0e-0
+This is a wasm script (nr 0).
+Script nr 3 parsed. URL: wasm://wasm/wasm-354ada0e/wasm-354ada0e-1
+This is a wasm script (nr 1).
+Querying breakable locations for all wasm scripts now...
+Requesting all breakable locations in wasm script 0
+4 breakable location(s):
+[0] 2:2 ||   >nop
+[1] 3:2 ||   >i32.const 12
+[2] 4:2 ||   >set_local 0
+[3] 5:0 || >end
+Requesting breakable locations in lines [0,3)
+1 breakable location(s):
+[0] 2:2 ||   >nop
+Requesting breakable locations in lines [4,6)
+2 breakable location(s):
+[0] 4:2 ||   >set_local 0
+[1] 5:0 || >end
+Requesting all breakable locations in wasm script 1
+7 breakable location(s):
+[0] 1:2 ||   >get_local 0
+[1] 2:2 ||   >if
+[2] 3:4 ||     >block
+[3] 4:6 ||       >call 0
+[4] 5:4 ||     >end
+[5] 6:2 ||   >end
+[6] 7:0 || >end
+Requesting breakable locations in lines [0,3)
+2 breakable location(s):
+[0] 1:2 ||   >get_local 0
+[1] 2:2 ||   >if
+Requesting breakable locations in lines [4,6)
+2 breakable location(s):
+[0] 4:6 ||       >call 0
+[1] 5:4 ||     >end
+Setting a breakpoint on each breakable location...
+Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:2:2
+Success!
+Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:3:2
+Success!
+Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:4:2
+Success!
+Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:5:0
+Success!
+Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:1:2
+Success!
+Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:2:2
+Success!
+Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:3:4
+Success!
+Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:4:6
+Success!
+Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:5:4
+Success!
+Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:6:2
+Success!
+Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:7:0
+Success!
+Running wasm code...
+Missing breakpoints: 11
+Script nr 4 parsed. URL: v8://test/runWasm
+Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:1:2
+Missing breakpoints: 10
+Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:2:2
+Missing breakpoints: 9
+Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:3:4
+Missing breakpoints: 8
+Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:4:6
+Missing breakpoints: 7
+Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:2:2
+Missing breakpoints: 6
+Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:3:2
+Missing breakpoints: 5
+Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:4:2
+Missing breakpoints: 4
+Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:5:0
+Missing breakpoints: 3
+Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:5:4
+Missing breakpoints: 2
+Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:6:2
+Missing breakpoints: 1
+Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:7:0
+Missing breakpoints: 0
+Finished!
diff --git a/src/v8/test/inspector/debugger/wasm-get-breakable-locations.js b/src/v8/test/inspector/debugger/wasm-get-breakable-locations.js
new file mode 100644
index 0000000..ea2a116
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-get-breakable-locations.js
@@ -0,0 +1,210 @@
+// Copyright 2016 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.
+
+// Flags: --expose-wasm
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests breakable locations in wasm');
+
+utils.load('test/mjsunit/wasm/wasm-constants.js');
+utils.load('test/mjsunit/wasm/wasm-module-builder.js');
+
+var builder = new WasmModuleBuilder();
+
+// clang-format off
+var func_idx = builder.addFunction('helper', kSig_v_v)
+    .addLocals({i32_count: 1})
+    .addBody([
+        kExprNop,
+        kExprI32Const, 12,
+        kExprSetLocal, 0,
+    ]).index;
+
+builder.addFunction('main', kSig_v_i)
+    .addBody([
+        kExprGetLocal, 0,
+        kExprIf, kWasmStmt,
+          kExprBlock, kWasmStmt,
+            kExprCallFunction, func_idx,
+          kExprEnd,
+        kExprEnd
+    ]).exportAs('main');
+// clang-format on
+
+var module_bytes = builder.toArray();
+
+function testFunction(bytes) {
+  var buffer = new ArrayBuffer(bytes.length);
+  var view = new Uint8Array(buffer);
+  for (var i = 0; i < bytes.length; i++) {
+    view[i] = bytes[i] | 0;
+  }
+
+  var module = new WebAssembly.Module(buffer);
+  // Set global variable.
+  instance = new WebAssembly.Instance(module);
+}
+
+var evalWithUrl = (code, url) => Protocol.Runtime.evaluate(
+    {'expression': code + '\n//# sourceURL=v8://test/' + url});
+
+var setupCode = testFunction.toString() + ';\nvar module_bytes = ' +
+    JSON.stringify(module_bytes) + ';\nvar instance;';
+
+Protocol.Debugger.enable();
+Protocol.Debugger.onScriptParsed(handleScriptParsed);
+InspectorTest.log('Running testFunction...');
+evalWithUrl(setupCode, 'setup')
+    .then(() => evalWithUrl('testFunction(module_bytes)', 'runTestFunction'))
+    .then(getBreakableLocationsForAllWasmScripts)
+    .then(setAllBreakableLocations)
+    .then(() => InspectorTest.log('Running wasm code...'))
+    .then(() => (evalWithUrl('instance.exports.main(1)', 'runWasm'), 0))
+    .then(waitForAllPauses)
+    .then(() => InspectorTest.log('Finished!'))
+    .then(InspectorTest.completeTest);
+
+var allBreakableLocations = [];
+
+var urls = {};
+var numScripts = 0;
+var wasmScripts = [];
+function handleScriptParsed(messageObject) {
+  var scriptId = messageObject.params.scriptId;
+  var url = messageObject.params.url;
+  urls[scriptId] = url;
+  InspectorTest.log('Script nr ' + numScripts + ' parsed. URL: ' + url);
+  ++numScripts;
+
+  if (url.startsWith('wasm://')) {
+    InspectorTest.log('This is a wasm script (nr ' + wasmScripts.length + ').');
+    wasmScripts.push(scriptId);
+  }
+}
+
+function printFailure(message) {
+  if (!message.result) {
+    InspectorTest.logMessage(message);
+  }
+  return message;
+}
+
+function printBreakableLocations(message, expectedScriptId, source) {
+  var lines = source.split('\n');
+  var locations = message.result.locations;
+  InspectorTest.log(locations.length + ' breakable location(s):');
+  for (var i = 0; i < locations.length; ++i) {
+    if (locations[i].scriptId != expectedScriptId) {
+      InspectorTest.log(
+          'SCRIPT ID MISMATCH!! ' + locations[i].scriptId + ' != ' +
+          expectedScriptId);
+    }
+    var line = '<illegal line number>';
+    if (locations[i].lineNumber < lines.length) {
+      line = lines[locations[i].lineNumber];
+      if (locations[i].columnNumber < line.length) {
+        line = line.substr(0, locations[i].columnNumber) + '>' +
+            line.substr(locations[i].columnNumber);
+      }
+    }
+    InspectorTest.log(
+        '[' + i + '] ' + locations[i].lineNumber + ':' +
+        locations[i].columnNumber + ' || ' + line);
+  }
+}
+
+function checkGetBreakableLocations(wasmScriptNr) {
+  InspectorTest.log(
+      'Requesting all breakable locations in wasm script ' + wasmScriptNr);
+  var scriptId = wasmScripts[wasmScriptNr];
+  var source;
+  return Protocol.Debugger.getScriptSource({scriptId: scriptId})
+      .then(msg => source = msg.result.scriptSource)
+      .then(
+          () => Protocol.Debugger.getPossibleBreakpoints(
+              {start: {lineNumber: 0, columnNumber: 0, scriptId: scriptId}}))
+      .then(printFailure)
+      .then(msg => (allBreakableLocations.push(...msg.result.locations), msg))
+      .then(msg => printBreakableLocations(msg, scriptId, source))
+      .then(
+          () => InspectorTest.log(
+              'Requesting breakable locations in lines [0,3)'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({
+        start: {lineNumber: 0, columnNumber: 0, scriptId: scriptId},
+        end: {lineNumber: 3, columnNumber: 0, scriptId: scriptId}
+      }))
+      .then(printFailure)
+      .then(msg => printBreakableLocations(msg, scriptId, source))
+      .then(
+          () => InspectorTest.log(
+              'Requesting breakable locations in lines [4,6)'))
+      .then(() => Protocol.Debugger.getPossibleBreakpoints({
+        start: {lineNumber: 4, columnNumber: 0, scriptId: scriptId},
+        end: {lineNumber: 6, columnNumber: 0, scriptId: scriptId}
+      }))
+      .then(printFailure)
+      .then(msg => printBreakableLocations(msg, scriptId, source));
+}
+
+function getBreakableLocationsForAllWasmScripts() {
+  InspectorTest.log('Querying breakable locations for all wasm scripts now...');
+  var promise = Promise.resolve();
+  for (var wasmScriptNr = 0; wasmScriptNr < wasmScripts.length;
+       ++wasmScriptNr) {
+    promise = promise.then(checkGetBreakableLocations.bind(null, wasmScriptNr));
+  }
+  return promise;
+}
+
+function locationMatches(loc1, loc2) {
+  return loc1.scriptId == loc2.scriptId && loc1.lineNumber == loc2.lineNumber &&
+      loc1.columnNumber == loc2.columnNumber;
+}
+
+function locationStr(loc) {
+  return urls[loc.scriptId] + ':' + loc.lineNumber + ':' + loc.columnNumber;
+}
+
+function setBreakpoint(loc) {
+  InspectorTest.log('Setting at ' + locationStr(loc));
+  function check(msg) {
+    if (locationMatches(loc, msg.result.actualLocation)) {
+      InspectorTest.log("Success!");
+    } else {
+      InspectorTest.log("Mismatch!");
+      InspectorTest.logMessage(msg);
+    }
+  }
+  return Protocol.Debugger.setBreakpoint({'location': loc})
+      .then(printFailure)
+      .then(check);
+}
+
+function setAllBreakableLocations() {
+  InspectorTest.log('Setting a breakpoint on each breakable location...');
+  var promise = Promise.resolve();
+  for (var loc of allBreakableLocations) {
+    promise = promise.then(setBreakpoint.bind(null, loc));
+  }
+  return promise;
+}
+
+function removePausedLocation(msg) {
+  var topLocation = msg.params.callFrames[0].location;
+  InspectorTest.log('Stopped at ' + locationStr(topLocation));
+  for (var i = 0; i < allBreakableLocations.length; ++i) {
+    if (locationMatches(topLocation, allBreakableLocations[i])) {
+      allBreakableLocations.splice(i, 1);
+      --i;
+    }
+  }
+}
+
+function waitForAllPauses() {
+  InspectorTest.log('Missing breakpoints: ' + allBreakableLocations.length);
+  if (allBreakableLocations.length == 0) return;
+  return Protocol.Debugger.oncePaused()
+      .then(removePausedLocation)
+      .then(Protocol.Debugger.resume())
+      .then(waitForAllPauses);
+}
diff --git a/src/v8/test/inspector/debugger/wasm-imports-expected.txt b/src/v8/test/inspector/debugger/wasm-imports-expected.txt
new file mode 100644
index 0000000..073c8af
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-imports-expected.txt
@@ -0,0 +1,25 @@
+Tests imports in wasm
+Installing code and global variable.
+Calling instantiate function for module A.
+Waiting for wasm script to be parsed.
+Got wasm script!
+Setting breakpoint in line 1:
+func $func
+  #nop
+end
+
+Calling instantiate function for module B.
+Calling main function on module B.
+Paused at 1:2.
+func $func
+  #nop
+end
+
+Getting current stack trace via "new Error().stack".
+Error
+    at v8://test/getStack:1:1
+    at func (wasm-function[0]:1)
+    at main (wasm-function[1]:1)
+    at v8://test/runWasm:1:22
+exports.main returned.
+Finished.
diff --git a/src/v8/test/inspector/debugger/wasm-imports.js b/src/v8/test/inspector/debugger/wasm-imports.js
new file mode 100644
index 0000000..dbe96ce
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-imports.js
@@ -0,0 +1,110 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests imports in wasm');
+
+utils.load('test/mjsunit/wasm/wasm-constants.js');
+utils.load('test/mjsunit/wasm/wasm-module-builder.js');
+
+// Build two modules A and B. A defines function func, which contains a
+// breakpoint. This function is then imported by B and called via main. The
+// breakpoint must be hit.
+// This failed before (http://crbug.com/v8/5971).
+
+var builder_a = new WasmModuleBuilder();
+var func_idx = builder_a.addFunction('func', kSig_v_v)
+                   .addBody([kExprNop])
+                   .exportFunc()
+                   .index;
+var module_a_bytes = builder_a.toArray();
+
+var builder_b = new WasmModuleBuilder();
+var import_idx = builder_b.addImport('imp', 'f', kSig_v_v);
+builder_b.addFunction('main', kSig_v_v)
+    .addBody([kExprCallFunction, import_idx])
+    .exportFunc();
+var module_b_bytes = builder_b.toArray();
+
+function instantiate(bytes, imp) {
+  var buffer = new ArrayBuffer(bytes.length);
+  var view = new Uint8Array(buffer);
+  for (var i = 0; i < bytes.length; ++i) {
+    view[i] = bytes[i] | 0;
+  }
+
+  var module = new WebAssembly.Module(buffer);
+  // Add to global instances array.
+  instances.push(new WebAssembly.Instance(module, imp));
+}
+
+var evalWithUrl = (code, url) => Protocol.Runtime.evaluate(
+    {'expression': code + '\n//# sourceURL=v8://test/' + url});
+
+session.setupScriptMap();
+
+// Main promise chain:
+Protocol.Debugger.enable()
+    .then(() => InspectorTest.log('Installing code and global variable.'))
+    .then(
+        () => evalWithUrl(
+            'var instances = [];\n' + instantiate.toString(), 'setup'))
+    .then(() => InspectorTest.log('Calling instantiate function for module A.'))
+    .then(
+        () =>
+            (evalWithUrl(
+                 'instantiate(' + JSON.stringify(module_a_bytes) + ')',
+                 'instantiateA'),
+             0))
+    .then(() => InspectorTest.log('Waiting for wasm script to be parsed.'))
+    .then(waitForWasmScript)
+    .then(url => (InspectorTest.log('Setting breakpoint in line 1:'), url))
+    .then(
+        url =>
+            Protocol.Debugger.setBreakpointByUrl({lineNumber: 1, url: url}))
+    .then(printFailure)
+    .then(msg => session.logSourceLocations(msg.result.locations))
+    .then(() => InspectorTest.log('Calling instantiate function for module B.'))
+    .then(
+        () =>
+            (evalWithUrl(
+                 'instantiate(' + JSON.stringify(module_b_bytes) +
+                     ', {imp: {f: instances[0].exports.func}})',
+                 'instantiateB'),
+             0))
+    .then(() => InspectorTest.log('Calling main function on module B.'))
+    .then(() => evalWithUrl('instances[1].exports.main()', 'runWasm'))
+    .then(() => InspectorTest.log('exports.main returned.'))
+    .then(() => InspectorTest.log('Finished.'))
+    .then(InspectorTest.completeTest);
+
+// Separate promise chain for the asynchronous pause:
+Protocol.Debugger.oncePaused()
+    .then(msg => msg.params.callFrames[0].location)
+    .then(
+        loc =>
+            (InspectorTest.log(
+                 'Paused at ' + loc.lineNumber + ':' + loc.columnNumber + '.'),
+             loc))
+    .then(session.logSourceLocation.bind(session))
+    .then(
+        () => InspectorTest.log(
+            'Getting current stack trace via "new Error().stack".'))
+    .then(() => evalWithUrl('new Error().stack', 'getStack'))
+    .then(msg => InspectorTest.log(msg.result.result.value))
+    .then(Protocol.Debugger.resume);
+
+function printFailure(message) {
+  if (!message.result) {
+    InspectorTest.logMessage(message);
+  }
+  return message;
+}
+
+function waitForWasmScript(msg) {
+  if (!msg || !msg.params.url.startsWith('wasm://')) {
+    return Protocol.Debugger.onceScriptParsed().then(waitForWasmScript);
+  }
+  InspectorTest.log('Got wasm script!');
+  return Promise.resolve(msg.params.url);
+}
diff --git a/src/v8/test/inspector/debugger/wasm-scope-info-expected.txt b/src/v8/test/inspector/debugger/wasm-scope-info-expected.txt
new file mode 100644
index 0000000..7701468
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-scope-info-expected.txt
@@ -0,0 +1,166 @@
+Test retrieving scope information when pausing in wasm functions
+Installing code and global variable.
+Calling instantiate function.
+Waiting for wasm script to be parsed.
+Got wasm script!
+Setting breakpoint on line 2 (first instruction)
+{
+    columnNumber : 2
+    lineNumber : 2
+    scriptId : <scriptId>
+}
+Paused:
+(local i32 f64)
+  #i32.const 11
+  set_local 0
+
+at func (2:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: "i32Arg": 4 (number), "local#1": 0 (number), "unicode☼f64": 0 (number)
+   stack: 
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Paused:
+  i32.const 11
+  #set_local 0
+  i32.const 47
+
+at func (3:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: "i32Arg": 4 (number), "local#1": 0 (number), "unicode☼f64": 0 (number)
+   stack: "0": 11 (number)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Paused:
+  set_local 0
+  #i32.const 47
+  set_local 1
+
+at func (4:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: "i32Arg": 11 (number), "local#1": 0 (number), "unicode☼f64": 0 (number)
+   stack: 
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Paused:
+  i32.const 47
+  #set_local 1
+  i32.const 1
+
+at func (5:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: "i32Arg": 11 (number), "local#1": 0 (number), "unicode☼f64": 0 (number)
+   stack: "0": 47 (number)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Paused:
+  set_local 1
+  #i32.const 1
+  f64.convert_u/i32
+
+at func (6:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: "i32Arg": 11 (number), "local#1": 47 (number), "unicode☼f64": 0 (number)
+   stack: 
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Paused:
+  i32.const 1
+  #f64.convert_u/i32
+  i32.const 7
+
+at func (7:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: "i32Arg": 11 (number), "local#1": 47 (number), "unicode☼f64": 0 (number)
+   stack: "0": 1 (number)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Paused:
+  f64.convert_u/i32
+  #i32.const 7
+  f64.convert_u/i32
+
+at func (8:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: "i32Arg": 11 (number), "local#1": 47 (number), "unicode☼f64": 0 (number)
+   stack: "0": 1 (number)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Paused:
+  i32.const 7
+  #f64.convert_u/i32
+  f64.div
+
+at func (9:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: "i32Arg": 11 (number), "local#1": 47 (number), "unicode☼f64": 0 (number)
+   stack: "0": 1 (number), "1": 7 (number)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Paused:
+  f64.convert_u/i32
+  #f64.div
+  set_local 2
+
+at func (10:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: "i32Arg": 11 (number), "local#1": 47 (number), "unicode☼f64": 0 (number)
+   stack: "0": 1 (number), "1": 7 (number)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Paused:
+  f64.div
+  #set_local 2
+end
+
+at func (11:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: "i32Arg": 11 (number), "local#1": 47 (number), "unicode☼f64": 0 (number)
+   stack: "0": 0.14285714285714285 (number)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Paused:
+  set_local 2
+#end
+
+
+at func (12:0):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: "i32Arg": 11 (number), "local#1": 47 (number), "unicode☼f64": 0.14285714285714285 (number)
+   stack: 
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+exports.main returned. Test finished.
diff --git a/src/v8/test/inspector/debugger/wasm-scope-info.js b/src/v8/test/inspector/debugger/wasm-scope-info.js
new file mode 100644
index 0000000..9a20d6a
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-scope-info.js
@@ -0,0 +1,137 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start(
+    'Test retrieving scope information when pausing in wasm functions');
+session.setupScriptMap();
+Protocol.Debugger.enable();
+
+let evaluate = code => Protocol.Runtime.evaluate({expression: code});
+
+(async function test() {
+  let scriptId = await instantiateWasm();
+  await setBreakpoint(scriptId);
+  printPauseLocationsAndContinue();
+  await evaluate('instance.exports.main(4)');
+  InspectorTest.log('exports.main returned. Test finished.');
+  InspectorTest.completeTest();
+})();
+
+async function printPauseLocationsAndContinue() {
+  while (true) {
+    let msg = await Protocol.Debugger.oncePaused();
+    let loc = msg.params.callFrames[0].location;
+    InspectorTest.log('Paused:');
+    await session.logSourceLocation(loc);
+    await dumpScopeChainsOnPause(msg);
+    Protocol.Debugger.stepOver();
+  }
+}
+
+async function instantiateWasm() {
+  utils.load('test/mjsunit/wasm/wasm-constants.js');
+  utils.load('test/mjsunit/wasm/wasm-module-builder.js');
+
+  var builder = new WasmModuleBuilder();
+
+  builder.addFunction('func', kSig_v_i)
+      .addLocals(
+          {i32_count: 1, f64_count: 1}, ['i32Arg', undefined, 'unicode☼f64'])
+      .addBody([
+        // Set param 0 to 11.
+        kExprI32Const, 11, kExprSetLocal, 0,
+        // Set local 1 to 47.
+        kExprI32Const, 47, kExprSetLocal, 1,
+        // Set local 2 to 1/7.
+        kExprI32Const, 1, kExprF64UConvertI32, kExprI32Const, 7,
+        kExprF64UConvertI32, kExprF64Div, kExprSetLocal, 2
+      ])
+      .exportAs('main');
+
+  var module_bytes = builder.toArray();
+
+  function instantiate(bytes) {
+    var buffer = new ArrayBuffer(bytes.length);
+    var view = new Uint8Array(buffer);
+    for (var i = 0; i < bytes.length; ++i) {
+      view[i] = bytes[i] | 0;
+    }
+
+    var module = new WebAssembly.Module(buffer);
+    // Set global variable.
+    instance = new WebAssembly.Instance(module);
+  }
+
+  InspectorTest.log('Installing code and global variable.');
+  await evaluate('var instance;\n' + instantiate.toString());
+  InspectorTest.log('Calling instantiate function.');
+  evaluate('instantiate(' + JSON.stringify(module_bytes) + ')');
+  return waitForWasmScript();
+}
+
+async function setBreakpoint(scriptId) {
+  InspectorTest.log('Setting breakpoint on line 2 (first instruction)');
+  let breakpoint = await Protocol.Debugger.setBreakpoint(
+      {'location': {'scriptId': scriptId, 'lineNumber': 2}});
+  printFailure(breakpoint);
+  InspectorTest.logMessage(breakpoint.result.actualLocation);
+}
+
+function printFailure(message) {
+  if (!message.result) {
+    InspectorTest.logMessage(message);
+  }
+  return message;
+}
+
+async function waitForWasmScript() {
+  InspectorTest.log('Waiting for wasm script to be parsed.');
+  while (true) {
+    let script_msg = await Protocol.Debugger.onceScriptParsed();
+    let url = script_msg.params.url;
+    if (!url.startsWith('wasm://')) {
+      continue;
+    }
+    InspectorTest.log('Got wasm script!');
+    return script_msg.params.scriptId;
+  }
+}
+
+async function getValueString(value) {
+  if (value.type == 'object') {
+    var msg = await Protocol.Runtime.getProperties({objectId: value.objectId});
+    printFailure(msg);
+    let printProperty = elem => '"' + elem.name + '"' +
+        ': ' + elem.value.description + ' (' + elem.value.type + ')';
+    return msg.result.result.map(printProperty).join(', ');
+  }
+  return JSON.stringify(value.value) + ' (' + value.type + ')';
+}
+
+async function dumpProperties(message) {
+  printFailure(message);
+  for (var value of message.result.result) {
+    var value_str = await getValueString(value.value);
+    InspectorTest.log('   ' + value.name + ': ' + value_str);
+  }
+}
+
+async function dumpScopeChainsOnPause(message) {
+  for (var frame of message.params.callFrames) {
+    var functionName = frame.functionName || '(anonymous)';
+    var lineNumber = frame.location ? frame.location.lineNumber : frame.lineNumber;
+    var columnNumber = frame.location ? frame.location.columnNumber : frame.columnNumber;
+    InspectorTest.log(`at ${functionName} (${lineNumber}:${columnNumber}):`);
+    for (var scope of frame.scopeChain) {
+      InspectorTest.logObject(' - scope (' + scope.type + '):');
+      if (scope.type == 'global') {
+        InspectorTest.logObject('   -- skipped');
+      } else {
+        var properties = await Protocol.Runtime.getProperties(
+            {'objectId': scope.object.objectId});
+        await dumpProperties(properties);
+      }
+    }
+  }
+}
diff --git a/src/v8/test/inspector/debugger/wasm-scripts-expected.txt b/src/v8/test/inspector/debugger/wasm-scripts-expected.txt
new file mode 100644
index 0000000..5d23605
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-scripts-expected.txt
@@ -0,0 +1,19 @@
+Tests how wasm scripts are reported
+Check that inspector gets two wasm scripts at module creation time.
+Script #0 parsed. URL: v8://test/testFunction
+Script #1 parsed. URL: v8://test/runTestRunction
+Script #2 parsed. URL: wasm://wasm/wasm-7b04570e/wasm-7b04570e-0
+Script #3 parsed. URL: wasm://wasm/wasm-7b04570e/wasm-7b04570e-1
+Source for wasm://wasm/wasm-7b04570e/wasm-7b04570e-0:
+func $nopFunction
+  nop
+end
+
+Source for wasm://wasm/wasm-7b04570e/wasm-7b04570e-1:
+func $main
+  block
+    i32.const 2
+    drop
+  end
+end
+
diff --git a/src/v8/test/inspector/debugger/wasm-scripts.js b/src/v8/test/inspector/debugger/wasm-scripts.js
new file mode 100644
index 0000000..0993f11
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-scripts.js
@@ -0,0 +1,72 @@
+// Copyright 2016 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.
+
+// Flags: --expose-wasm
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests how wasm scripts are reported');
+
+utils.load('test/mjsunit/wasm/wasm-constants.js');
+utils.load('test/mjsunit/wasm/wasm-module-builder.js');
+
+// Add two empty functions. Both should be registered as individual scripts at
+// module creation time.
+var builder = new WasmModuleBuilder();
+builder.addFunction('nopFunction', kSig_v_v).addBody([kExprNop]);
+builder.addFunction('main', kSig_v_v)
+    .addBody([kExprBlock, kWasmStmt, kExprI32Const, 2, kExprDrop, kExprEnd])
+    .exportAs('main');
+var module_bytes = builder.toArray();
+
+function testFunction(bytes) {
+  var buffer = new ArrayBuffer(bytes.length);
+  var view = new Uint8Array(buffer);
+  for (var i = 0; i < bytes.length; i++) {
+    view[i] = bytes[i] | 0;
+  }
+
+  // Compilation triggers registration of wasm scripts.
+  new WebAssembly.Module(buffer);
+}
+
+contextGroup.addScript(testFunction.toString(), 0, 0, 'v8://test/testFunction');
+contextGroup.addScript('var module_bytes = ' + JSON.stringify(module_bytes));
+
+Protocol.Debugger.enable();
+Protocol.Debugger.onScriptParsed(handleScriptParsed);
+InspectorTest.log(
+    'Check that inspector gets two wasm scripts at module creation time.');
+Protocol.Runtime
+    .evaluate({
+      'expression': '//# sourceURL=v8://test/runTestRunction\n' +
+          'testFunction(module_bytes)'
+    })
+    .then(checkFinished);
+
+var num_scripts = 0;
+var missing_sources = 0;
+
+function checkFinished() {
+  if (missing_sources == 0)
+    InspectorTest.completeTest();
+}
+
+function handleScriptParsed(messageObject)
+{
+  var url = messageObject.params.url;
+  InspectorTest.log("Script #" + num_scripts + " parsed. URL: " + url);
+  ++num_scripts;
+
+  if (url.startsWith("wasm://")) {
+    ++missing_sources;
+    function dumpScriptSource(message) {
+      InspectorTest.log("Source for " + url + ":");
+      InspectorTest.log(message.result.scriptSource);
+      --missing_sources;
+    }
+
+    Protocol.Debugger.getScriptSource({scriptId: messageObject.params.scriptId})
+        .then(dumpScriptSource.bind(null))
+        .then(checkFinished);
+  }
+}
diff --git a/src/v8/test/inspector/debugger/wasm-source-expected.txt b/src/v8/test/inspector/debugger/wasm-source-expected.txt
new file mode 100644
index 0000000..b140be0
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-source-expected.txt
@@ -0,0 +1,10 @@
+Tests how wasm scrips report the source
+Check that inspector gets disassembled wasm code
+Paused on debugger!
+Number of frames: 5
+[0]     debugger;
+[1]   call 0
+[2]     call_indirect 2
+[3]   instance.exports.main();
+[4] testFunction(module_bytes)
+Finished.
diff --git a/src/v8/test/inspector/debugger/wasm-source.js b/src/v8/test/inspector/debugger/wasm-source.js
new file mode 100644
index 0000000..bf7bab7
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-source.js
@@ -0,0 +1,81 @@
+// Copyright 2016 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.
+
+// Flags: --expose-wasm
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests how wasm scrips report the source');
+
+utils.load('test/mjsunit/wasm/wasm-constants.js');
+utils.load('test/mjsunit/wasm/wasm-module-builder.js');
+
+var builder = new WasmModuleBuilder();
+
+var imported_idx = builder.addImport("xxx", "func", kSig_v_v);
+
+var call_imported_idx = builder.addFunction("call_func", kSig_v_v)
+    .addBody([kExprCallFunction, imported_idx])
+    .index;
+
+var sig_index = builder.addType(kSig_v_v);
+
+builder.addFunction('main', kSig_v_v)
+    .addBody([
+      kExprBlock, kWasmStmt, kExprI32Const, 0, kExprCallIndirect, sig_index,
+      kTableZero, kExprEnd
+    ])
+    .exportAs('main');
+
+builder.appendToTable([call_imported_idx]);
+
+var module_bytes = builder.toArray();
+
+function testFunction(bytes) {
+  function call_debugger() {
+    debugger;
+  }
+
+  var buffer = new ArrayBuffer(bytes.length);
+  var view = new Uint8Array(buffer);
+  for (var i = 0; i < bytes.length; i++) {
+    view[i] = bytes[i] | 0;
+  }
+
+  var module = new WebAssembly.Module(buffer);
+  var instance = new WebAssembly.Instance(module, {xxx: {func: call_debugger}});
+
+  instance.exports.main();
+}
+
+contextGroup.addScript(testFunction.toString());
+contextGroup.addScript('var module_bytes = ' + JSON.stringify(module_bytes));
+
+Protocol.Debugger.enable();
+Protocol.Debugger.onPaused(handleDebuggerPaused);
+InspectorTest.log('Check that inspector gets disassembled wasm code');
+Protocol.Runtime.evaluate({'expression': 'testFunction(module_bytes)'});
+
+function handleDebuggerPaused(message) {
+  InspectorTest.log('Paused on debugger!');
+  var frames = message.params.callFrames;
+  InspectorTest.log('Number of frames: ' + frames.length);
+  function dumpSourceLine(frameId, sourceMessage) {
+    if (sourceMessage.error) InspectorTest.logObject(sourceMessage);
+    var text = sourceMessage.result.scriptSource;
+    var lineNr = frames[frameId].location.lineNumber;
+    var line = text.split('\n')[lineNr];
+    InspectorTest.log('[' + frameId + '] ' + line);
+  }
+  function next(frameId) {
+    if (frameId == frames.length) return Promise.resolve();
+    return Protocol.Debugger
+        .getScriptSource({scriptId: frames[frameId].location.scriptId})
+        .then(dumpSourceLine.bind(null, frameId))
+        .then(() => next(frameId + 1));
+  }
+  function finished() {
+    InspectorTest.log('Finished.');
+    InspectorTest.completeTest();
+  }
+  next(0).then(finished);
+}
diff --git a/src/v8/test/inspector/debugger/wasm-stack-expected.txt b/src/v8/test/inspector/debugger/wasm-stack-expected.txt
new file mode 100644
index 0000000..bba3009
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-stack-expected.txt
@@ -0,0 +1,19 @@
+Tests call stack in wasm scripts
+Running testFunction with generated wasm bytes...
+Paused on 'debugger;'
+Number of frames: 5
+  - [0] {"functionName":"call_debugger","function_lineNumber":1,"function_columnNumber":24,"lineNumber":2,"columnNumber":4}
+  - [1] {"functionName":"call_func","lineNumber":1,"columnNumber":2}
+  - [2] {"functionName":"main","lineNumber":2,"columnNumber":4}
+  - [3] {"functionName":"testFunction","function_lineNumber":0,"function_columnNumber":21,"lineNumber":14,"columnNumber":19}
+  - [4] {"functionName":"","function_lineNumber":0,"function_columnNumber":0,"lineNumber":0,"columnNumber":0}
+Getting v8-generated stack trace...
+Result of evaluate (string):
+Error: this is your stack trace:
+    -- skipped --
+    at call_debugger (<anonymous>:3:5)
+    at call_func (wasm-function[1]:1)
+    at main (wasm-function[2]:3)
+    at testFunction (<anonymous>:15:20)
+    at <anonymous>:1:1
+Finished!
diff --git a/src/v8/test/inspector/debugger/wasm-stack.js b/src/v8/test/inspector/debugger/wasm-stack.js
new file mode 100644
index 0000000..0234dab
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-stack.js
@@ -0,0 +1,98 @@
+// Copyright 2016 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.
+
+// Flags: --expose-wasm
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests call stack in wasm scripts');
+
+utils.load('test/mjsunit/wasm/wasm-constants.js');
+utils.load('test/mjsunit/wasm/wasm-module-builder.js');
+
+var builder = new WasmModuleBuilder();
+
+var imported_idx = builder.addImport("mode", "func", kSig_v_v);
+
+var call_imported_idx = builder.addFunction('call_func', kSig_v_v)
+  .addBody([kExprCallFunction, imported_idx])
+  .index;
+
+// Open a block in order to make the positions more interesting...
+builder.addFunction('main', kSig_v_v)
+  .addBody(
+    [kExprBlock, kWasmStmt, kExprCallFunction, call_imported_idx, kExprEnd])
+  .exportAs('main');
+
+var module_bytes = builder.toArray();
+
+function testFunction(bytes) {
+  function call_debugger() {
+    debugger;
+  }
+
+  var buffer = new ArrayBuffer(bytes.length);
+  var view = new Uint8Array(buffer);
+  for (var i = 0; i < bytes.length; i++) {
+    view[i] = bytes[i] | 0;
+  }
+
+  var module = new WebAssembly.Module(buffer);
+  var instance = new WebAssembly.Instance(module, {mode: {func: call_debugger}});
+
+  instance.exports.main();
+}
+
+contextGroup.addScript(testFunction.toString());
+
+Protocol.Debugger.enable();
+Protocol.Debugger.onPaused(handleDebuggerPaused);
+InspectorTest.log('Running testFunction with generated wasm bytes...');
+Protocol.Runtime.evaluate(
+    {'expression': 'testFunction(' + JSON.stringify(module_bytes) + ')'});
+
+function locationToString(callFrame) {
+  var res = {functionName: callFrame.functionName};
+  for (var attr in callFrame.functionLocation) {
+    if (attr == 'scriptId') continue;
+    res['function_'+attr] = callFrame.functionLocation[attr];
+  }
+  for (var attr in callFrame.location) {
+    if (attr == 'scriptId') continue;
+    res[attr] = callFrame.location[attr];
+  }
+  return JSON.stringify(res);
+}
+
+function logStackTrace(messageObject) {
+  var frames = messageObject.params.callFrames;
+  InspectorTest.log('Number of frames: ' + frames.length);
+  for (var i = 0; i < frames.length; ++i) {
+    InspectorTest.log('  - [' + i + '] ' + locationToString(frames[i]));
+  }
+}
+
+function handleDebuggerPaused(messageObject)
+{
+  InspectorTest.log('Paused on \'debugger;\'');
+  logStackTrace(messageObject);
+  InspectorTest.log('Getting v8-generated stack trace...');
+  var topFrameId = messageObject.params.callFrames[0].callFrameId;
+  Protocol.Debugger
+      .evaluateOnCallFrame({
+        callFrameId: topFrameId,
+        expression: '(new Error("this is your stack trace:")).stack'
+      })
+      .then(callbackEvaluate);
+}
+
+function callbackEvaluate(response)
+{
+  InspectorTest.log(
+      'Result of evaluate (' + response.result.result.type + '):');
+  var result_lines = response.result.result.value.split('\n');
+  // Skip the second line, containing the 'evaluate' position.
+  result_lines[1] = '    -- skipped --';
+  InspectorTest.log(result_lines.join('\n'));
+  InspectorTest.log('Finished!');
+  InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/debugger/wasm-stepping-expected.txt b/src/v8/test/inspector/debugger/wasm-stepping-expected.txt
new file mode 100644
index 0000000..7af75aa
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-stepping-expected.txt
@@ -0,0 +1,330 @@
+Tests stepping through wasm scripts
+Installing code an global variable.
+Calling instantiate function.
+Waiting for two wasm scripts to be parsed.
+Ignoring script with url v8://test/callInstantiate
+Got wasm script: wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0
+Requesting source for wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0...
+Got wasm script: wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1
+Requesting source for wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1...
+func $wasm_A
+  nop
+  nop
+end
+
+func $wasm_B (param i32)
+  loop
+    get_local 0
+    if
+      get_local 0
+      i32.const 1
+      i32.sub
+      set_local 0
+      call 0
+      br 1
+    end
+  end
+end
+
+Setting breakpoint on line 7 (on the setlocal before the call), url wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1
+{
+    columnNumber : 6
+    lineNumber : 7
+    scriptId : <scriptId>
+}
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6:       >set_local 0
+at wasm_B (7:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":4} (Object)
+   stack: {"0":3} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6:       >call 0
+at wasm_B (8:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":3} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:1:2:   >nop
+at wasm_A (1:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   stack: {} (Object)
+at wasm_B (8:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":3} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepOver called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:2:2:   >nop
+at wasm_A (2:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   stack: {} (Object)
+at wasm_B (8:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":3} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepOut called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6:       >br 1
+at wasm_B (9:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":3} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepOut called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6:       >set_local 0
+at wasm_B (7:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":3} (Object)
+   stack: {"0":2} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepOver called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6:       >call 0
+at wasm_B (8:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":2} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepOver called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6:       >br 1
+at wasm_B (9:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":2} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.resume called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6:       >set_local 0
+at wasm_B (7:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":2} (Object)
+   stack: {"0":1} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6:       >call 0
+at wasm_B (8:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":1} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:1:2:   >nop
+at wasm_A (1:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   stack: {} (Object)
+at wasm_B (8:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":1} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepOut called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6:       >br 1
+at wasm_B (9:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":1} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:1:2:   >loop
+at wasm_B (1:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":1} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:2:4:     >get_local 0
+at wasm_B (2:4):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":1} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:3:4:     >if
+at wasm_B (3:4):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":1} (Object)
+   stack: {"0":1} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:4:6:       >get_local 0
+at wasm_B (4:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":1} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:5:6:       >i32.const 1
+at wasm_B (5:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":1} (Object)
+   stack: {"0":1} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:6:6:       >i32.sub
+at wasm_B (6:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":1} (Object)
+   stack: {"0":1,"1":1} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6:       >set_local 0
+at wasm_B (7:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":1} (Object)
+   stack: {"0":0} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6:       >call 0
+at wasm_B (8:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":0} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:1:2:   >nop
+at wasm_A (1:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   stack: {} (Object)
+at wasm_B (8:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":0} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:2:2:   >nop
+at wasm_A (2:2):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   stack: {} (Object)
+at wasm_B (8:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":0} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:3:0: >end
+at wasm_A (3:0):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   stack: {} (Object)
+at wasm_B (8:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":0} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.stepInto called
+Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6:       >br 1
+at wasm_B (9:6):
+ - scope (global):
+   -- skipped
+ - scope (local):
+   locals: {"arg#0":0} (Object)
+   stack: {} (Object)
+at (anonymous) (0:17):
+ - scope (global):
+   -- skipped
+Debugger.resume called
+exports.main returned!
+Finished!
diff --git a/src/v8/test/inspector/debugger/wasm-stepping.js b/src/v8/test/inspector/debugger/wasm-stepping.js
new file mode 100644
index 0000000..d3a2c64
--- /dev/null
+++ b/src/v8/test/inspector/debugger/wasm-stepping.js
@@ -0,0 +1,203 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests stepping through wasm scripts');
+
+utils.load('test/mjsunit/wasm/wasm-constants.js');
+utils.load('test/mjsunit/wasm/wasm-module-builder.js');
+
+var builder = new WasmModuleBuilder();
+
+var func_a_idx =
+    builder.addFunction('wasm_A', kSig_v_v).addBody([kExprNop, kExprNop]).index;
+
+// wasm_B calls wasm_A <param0> times.
+builder.addFunction('wasm_B', kSig_v_i)
+    .addBody([
+      // clang-format off
+      kExprLoop, kWasmStmt,               // while
+        kExprGetLocal, 0,                 // -
+        kExprIf, kWasmStmt,               // if <param0> != 0
+          kExprGetLocal, 0,               // -
+          kExprI32Const, 1,               // -
+          kExprI32Sub,                    // -
+          kExprSetLocal, 0,               // decrease <param0>
+          kExprCallFunction, func_a_idx,  // -
+          kExprBr, 1,                     // continue
+          kExprEnd,                       // -
+        kExprEnd,                         // break
+      // clang-format on
+    ])
+    .exportAs('main');
+
+var module_bytes = builder.toArray();
+
+function instantiate(bytes) {
+  var buffer = new ArrayBuffer(bytes.length);
+  var view = new Uint8Array(buffer);
+  for (var i = 0; i < bytes.length; ++i) {
+    view[i] = bytes[i] | 0;
+  }
+
+  var module = new WebAssembly.Module(buffer);
+  // Set global variable.
+  instance = new WebAssembly.Instance(module);
+}
+
+var evalWithUrl = (code, url) => Protocol.Runtime.evaluate(
+    {'expression': code + '\n//# sourceURL=v8://test/' + url});
+
+Protocol.Debugger.onPaused(handlePaused);
+var wasm_B_scriptId;
+var step_actions = [
+  'stepInto',  // == stepOver, to call instruction
+  'stepInto',  // into call to wasm_A
+  'stepOver',  // over first nop
+  'stepOut',   // out of wasm_A
+  'stepOut',   // out of wasm_B, stop on breakpoint again
+  'stepOver',  // to call
+  'stepOver',  // over call
+  'resume',    // to next breakpoint (third iteration)
+  'stepInto',  // to call
+  'stepInto',  // into wasm_A
+  'stepOut',   // out to wasm_B
+  // now step 9 times, until we are in wasm_A again.
+  'stepInto', 'stepInto', 'stepInto', 'stepInto', 'stepInto', 'stepInto',
+  'stepInto', 'stepInto', 'stepInto',
+  // 3 more times, back to wasm_B.
+  'stepInto', 'stepInto', 'stepInto',
+  // then just resume.
+  'resume'
+];
+for (var action of step_actions) {
+  InspectorTest.logProtocolCommandCalls('Debugger.' + action)
+}
+var sources = {};
+var urls = {};
+var afterTwoSourcesCallback;
+
+Protocol.Debugger.enable()
+    .then(() => InspectorTest.log('Installing code an global variable.'))
+    .then(
+        () => evalWithUrl('var instance;\n' + instantiate.toString(), 'setup'))
+    .then(() => InspectorTest.log('Calling instantiate function.'))
+    .then(
+        () =>
+            (evalWithUrl(
+                 'instantiate(' + JSON.stringify(module_bytes) + ')',
+                 'callInstantiate'),
+             0))
+    .then(waitForTwoWasmScripts)
+    .then(
+        () => InspectorTest.log(
+            'Setting breakpoint on line 7 (on the setlocal before the call), url ' +
+            urls[wasm_B_scriptId]))
+    .then(
+        () => Protocol.Debugger.setBreakpoint(
+            {'location': {'scriptId': wasm_B_scriptId, 'lineNumber': 7}}))
+    .then(printFailure)
+    .then(msg => InspectorTest.logMessage(msg.result.actualLocation))
+    .then(() => evalWithUrl('instance.exports.main(4)', 'runWasm'))
+    .then(() => InspectorTest.log('exports.main returned!'))
+    .then(() => InspectorTest.log('Finished!'))
+    .then(InspectorTest.completeTest);
+
+function printFailure(message) {
+  if (!message.result) {
+    InspectorTest.logMessage(message);
+  }
+  return message;
+}
+
+function waitForTwoWasmScripts() {
+  var num = 0;
+  InspectorTest.log('Waiting for two wasm scripts to be parsed.');
+  var promise = new Promise(fulfill => gotBothSources = fulfill);
+  function waitForMore() {
+    if (num == 2) return promise;
+    Protocol.Debugger.onceScriptParsed()
+        .then(handleNewScript)
+        .then(waitForMore);
+  }
+  function handleNewScript(msg) {
+    var url = msg.params.url;
+    if (!url.startsWith('wasm://')) {
+      InspectorTest.log('Ignoring script with url ' + url);
+      return;
+    }
+    num += 1;
+    var scriptId = msg.params.scriptId;
+    urls[scriptId] = url;
+    InspectorTest.log('Got wasm script: ' + url);
+    if (url.substr(-2) == '-1') wasm_B_scriptId = scriptId;
+    InspectorTest.log('Requesting source for ' + url + '...');
+    Protocol.Debugger.getScriptSource({scriptId: scriptId})
+        .then(printFailure)
+        .then(msg => sources[scriptId] = msg.result.scriptSource)
+        .then(InspectorTest.log)
+        .then(() => Object.keys(sources).length == 2 ? gotBothSources() : 0);
+  }
+  waitForMore();
+  return promise;
+}
+
+function printPauseLocation(scriptId, lineNr, columnNr) {
+  var lines = sources[scriptId].split('\n');
+  var line = '<illegal line number>';
+  if (lineNr < lines.length) {
+    line = lines[lineNr];
+    if (columnNr < line.length) {
+      line = line.substr(0, columnNr) + '>' + line.substr(columnNr);
+    }
+  }
+  InspectorTest.log(
+      'Paused at ' + urls[scriptId] + ':' + lineNr + ':' + columnNr + ': ' +
+      line);
+}
+
+async function getValueString(value) {
+  if (value.type == 'object') {
+    var msg = await Protocol.Runtime.callFunctionOn({
+      objectId: value.objectId,
+      functionDeclaration: 'function () { return JSON.stringify(this); }'
+    });
+    printFailure(msg);
+    return msg.result.result.value + ' (' + value.description + ')';
+  }
+  return value.value + ' (' + value.type + ')';
+}
+
+async function dumpProperties(message) {
+  printFailure(message);
+  for (var value of message.result.result) {
+    var value_str = await getValueString(value.value);
+    InspectorTest.log('   ' + value.name + ': ' + value_str);
+  }
+}
+
+async function dumpScopeChainsOnPause(message) {
+  for (var frame of message.params.callFrames) {
+    var functionName = frame.functionName || '(anonymous)';
+    var lineNumber = frame.location ? frame.location.lineNumber : frame.lineNumber;
+    var columnNumber = frame.location ? frame.location.columnNumber : frame.columnNumber;
+    InspectorTest.log(`at ${functionName} (${lineNumber}:${columnNumber}):`);
+    for (var scope of frame.scopeChain) {
+      InspectorTest.logObject(' - scope (' + scope.type + '):');
+      if (scope.type == 'global') {
+        InspectorTest.logObject('   -- skipped');
+      } else {
+        var properties = await Protocol.Runtime.getProperties(
+            {'objectId': scope.object.objectId});
+        await dumpProperties(properties);
+      }
+    }
+  }
+}
+
+function handlePaused(msg) {
+  var loc = msg.params.callFrames[0].location;
+  printPauseLocation(loc.scriptId, loc.lineNumber, loc.columnNumber);
+  dumpScopeChainsOnPause(msg)
+      .then(Protocol.Debugger[step_actions.shift() || 'resume']);
+}
diff --git a/src/v8/test/inspector/heap-profiler/take-heap-snapshot-on-pause-expected.txt b/src/v8/test/inspector/heap-profiler/take-heap-snapshot-on-pause-expected.txt
new file mode 100644
index 0000000..2d2e553
--- /dev/null
+++ b/src/v8/test/inspector/heap-profiler/take-heap-snapshot-on-pause-expected.txt
@@ -0,0 +1,2 @@
+Checks that takeHeapSnapshot uses empty accessing_context for access checks.
+Successfully finished
diff --git a/src/v8/test/inspector/heap-profiler/take-heap-snapshot-on-pause.js b/src/v8/test/inspector/heap-profiler/take-heap-snapshot-on-pause.js
new file mode 100644
index 0000000..4e4bc40
--- /dev/null
+++ b/src/v8/test/inspector/heap-profiler/take-heap-snapshot-on-pause.js
@@ -0,0 +1,24 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that takeHeapSnapshot uses empty accessing_context for access \
+checks.');
+
+contextGroup.addScript(`
+function testFunction() {
+  var array = [ inspector.createObjectWithStrictCheck() ];
+  debugger;
+}
+//# sourceURL=test.js`);
+
+Protocol.Debugger.onScriptParsed(message => {
+  Protocol.HeapProfiler.takeHeapSnapshot({ reportProgress: false })
+    .then(() => Protocol.Debugger.resume());
+});
+
+Protocol.Debugger.enable();
+Protocol.HeapProfiler.enable();
+Protocol.Runtime.evaluate({ expression: 'testFunction()' })
+  .then(() => InspectorTest.log('Successfully finished'))
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/inspector-test.cc b/src/v8/test/inspector/inspector-test.cc
new file mode 100644
index 0000000..dcaf582
--- /dev/null
+++ b/src/v8/test/inspector/inspector-test.cc
@@ -0,0 +1,884 @@
+// Copyright 2016 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.
+
+#if !defined(_WIN32) && !defined(_WIN64)
+#include <unistd.h>  // NOLINT
+#endif               // !defined(_WIN32) && !defined(_WIN64)
+
+#include <locale.h>
+
+#include "include/libplatform/libplatform.h"
+#include "include/v8.h"
+
+#include "src/base/platform/platform.h"
+#include "src/flags.h"
+#include "src/utils.h"
+#include "src/vector.h"
+
+#include "test/inspector/isolate-data.h"
+#include "test/inspector/task-runner.h"
+
+namespace {
+
+std::vector<TaskRunner*> task_runners;
+
+void Terminate() {
+  for (size_t i = 0; i < task_runners.size(); ++i) {
+    task_runners[i]->Terminate();
+    task_runners[i]->Join();
+  }
+  std::vector<TaskRunner*> empty;
+  task_runners.swap(empty);
+}
+
+void Exit() {
+  fflush(stdout);
+  fflush(stderr);
+  Terminate();
+}
+
+v8::internal::Vector<uint16_t> ToVector(v8::Local<v8::String> str) {
+  v8::internal::Vector<uint16_t> buffer =
+      v8::internal::Vector<uint16_t>::New(str->Length());
+  str->Write(buffer.start(), 0, str->Length());
+  return buffer;
+}
+
+v8::Local<v8::String> ToV8String(v8::Isolate* isolate, const char* str) {
+  return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kNormal)
+      .ToLocalChecked();
+}
+
+v8::Local<v8::String> ToV8String(v8::Isolate* isolate, const char* str,
+                                 int length) {
+  return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kNormal,
+                                 length)
+      .ToLocalChecked();
+}
+
+v8::Local<v8::String> ToV8String(v8::Isolate* isolate,
+                                 const v8::internal::Vector<uint16_t>& buffer) {
+  return v8::String::NewFromTwoByte(isolate, buffer.start(),
+                                    v8::NewStringType::kNormal, buffer.length())
+      .ToLocalChecked();
+}
+
+v8::internal::Vector<uint16_t> ToVector(
+    const v8_inspector::StringView& string) {
+  v8::internal::Vector<uint16_t> buffer =
+      v8::internal::Vector<uint16_t>::New(static_cast<int>(string.length()));
+  for (size_t i = 0; i < string.length(); i++) {
+    if (string.is8Bit())
+      buffer[i] = string.characters8()[i];
+    else
+      buffer[i] = string.characters16()[i];
+  }
+  return buffer;
+}
+
+class FrontendChannelImpl : public v8_inspector::V8Inspector::Channel {
+ public:
+  FrontendChannelImpl(TaskRunner* task_runner, int context_group_id,
+                      v8::Isolate* isolate, v8::Local<v8::Function> function)
+      : task_runner_(task_runner),
+        context_group_id_(context_group_id),
+        function_(isolate, function) {}
+  virtual ~FrontendChannelImpl() = default;
+
+  void set_session_id(int session_id) { session_id_ = session_id; }
+
+ private:
+  void sendResponse(
+      int callId,
+      std::unique_ptr<v8_inspector::StringBuffer> message) override {
+    task_runner_->Append(
+        new SendMessageTask(this, ToVector(message->string())));
+  }
+  void sendNotification(
+      std::unique_ptr<v8_inspector::StringBuffer> message) override {
+    task_runner_->Append(
+        new SendMessageTask(this, ToVector(message->string())));
+  }
+  void flushProtocolNotifications() override {}
+
+  class SendMessageTask : public TaskRunner::Task {
+   public:
+    SendMessageTask(FrontendChannelImpl* channel,
+                    const v8::internal::Vector<uint16_t>& message)
+        : channel_(channel), message_(message) {}
+    virtual ~SendMessageTask() {}
+    bool is_priority_task() final { return false; }
+
+   private:
+    void Run(IsolateData* data) override {
+      v8::MicrotasksScope microtasks_scope(data->isolate(),
+                                           v8::MicrotasksScope::kRunMicrotasks);
+      v8::HandleScope handle_scope(data->isolate());
+      v8::Local<v8::Context> context =
+          data->GetContext(channel_->context_group_id_);
+      v8::Context::Scope context_scope(context);
+      v8::Local<v8::Value> message = ToV8String(data->isolate(), message_);
+      v8::MaybeLocal<v8::Value> result;
+      result = channel_->function_.Get(data->isolate())
+                   ->Call(context, context->Global(), 1, &message);
+    }
+    FrontendChannelImpl* channel_;
+    v8::internal::Vector<uint16_t> message_;
+  };
+
+  TaskRunner* task_runner_;
+  int context_group_id_;
+  v8::Global<v8::Function> function_;
+  int session_id_;
+  DISALLOW_COPY_AND_ASSIGN(FrontendChannelImpl);
+};
+
+template <typename T>
+void RunSyncTask(TaskRunner* task_runner, T callback) {
+  class SyncTask : public TaskRunner::Task {
+   public:
+    SyncTask(v8::base::Semaphore* ready_semaphore, T callback)
+        : ready_semaphore_(ready_semaphore), callback_(callback) {}
+    virtual ~SyncTask() = default;
+    bool is_priority_task() final { return true; }
+
+   private:
+    void Run(IsolateData* data) override {
+      callback_(data);
+      if (ready_semaphore_) ready_semaphore_->Signal();
+    }
+
+    v8::base::Semaphore* ready_semaphore_;
+    T callback_;
+  };
+
+  v8::base::Semaphore ready_semaphore(0);
+  task_runner->Append(new SyncTask(&ready_semaphore, callback));
+  ready_semaphore.Wait();
+}
+
+class SendMessageToBackendTask : public TaskRunner::Task {
+ public:
+  SendMessageToBackendTask(int session_id,
+                           const v8::internal::Vector<uint16_t>& message)
+      : session_id_(session_id), message_(message) {}
+  bool is_priority_task() final { return true; }
+
+ private:
+  void Run(IsolateData* data) override {
+    v8_inspector::StringView message_view(message_.start(), message_.length());
+    data->SendMessage(session_id_, message_view);
+  }
+
+  int session_id_;
+  v8::internal::Vector<uint16_t> message_;
+};
+
+void RunAsyncTask(TaskRunner* task_runner, const char* task_name,
+                  TaskRunner::Task* task) {
+  class AsyncTask : public TaskRunner::Task {
+   public:
+    explicit AsyncTask(TaskRunner::Task* inner) : inner_(inner) {}
+    virtual ~AsyncTask() = default;
+    bool is_priority_task() override { return inner_->is_priority_task(); }
+    void Run(IsolateData* data) override {
+      data->AsyncTaskStarted(inner_.get());
+      inner_->Run(data);
+      data->AsyncTaskFinished(inner_.get());
+    }
+
+   private:
+    std::unique_ptr<TaskRunner::Task> inner_;
+    DISALLOW_COPY_AND_ASSIGN(AsyncTask);
+  };
+
+  task_runner->data()->AsyncTaskScheduled(
+      v8_inspector::StringView(reinterpret_cast<const uint8_t*>(task_name),
+                               strlen(task_name)),
+      task, false);
+  task_runner->Append(new AsyncTask(task));
+}
+
+class ExecuteStringTask : public TaskRunner::Task {
+ public:
+  ExecuteStringTask(int context_group_id,
+                    const v8::internal::Vector<uint16_t>& expression,
+                    v8::Local<v8::String> name,
+                    v8::Local<v8::Integer> line_offset,
+                    v8::Local<v8::Integer> column_offset,
+                    v8::Local<v8::Boolean> is_module)
+      : expression_(expression),
+        name_(ToVector(name)),
+        line_offset_(line_offset.As<v8::Int32>()->Value()),
+        column_offset_(column_offset.As<v8::Int32>()->Value()),
+        is_module_(is_module->Value()),
+        context_group_id_(context_group_id) {}
+  ExecuteStringTask(const v8::internal::Vector<const char>& expression,
+                    int context_group_id)
+      : expression_utf8_(expression), context_group_id_(context_group_id) {}
+  bool is_priority_task() override { return false; }
+  void Run(IsolateData* data) override {
+    v8::MicrotasksScope microtasks_scope(data->isolate(),
+                                         v8::MicrotasksScope::kRunMicrotasks);
+    v8::HandleScope handle_scope(data->isolate());
+    v8::Local<v8::Context> context = data->GetContext(context_group_id_);
+    v8::Context::Scope context_scope(context);
+    v8::ScriptOrigin origin(
+        ToV8String(data->isolate(), name_),
+        v8::Integer::New(data->isolate(), line_offset_),
+        v8::Integer::New(data->isolate(), column_offset_),
+        /* resource_is_shared_cross_origin */ v8::Local<v8::Boolean>(),
+        /* script_id */ v8::Local<v8::Integer>(),
+        /* source_map_url */ v8::Local<v8::Value>(),
+        /* resource_is_opaque */ v8::Local<v8::Boolean>(),
+        /* is_wasm */ v8::Local<v8::Boolean>(),
+        v8::Boolean::New(data->isolate(), is_module_));
+    v8::Local<v8::String> source;
+    if (expression_.length())
+      source = ToV8String(data->isolate(), expression_);
+    else
+      source = ToV8String(data->isolate(), expression_utf8_.start(),
+                          expression_utf8_.length());
+
+    v8::ScriptCompiler::Source scriptSource(source, origin);
+    if (!is_module_) {
+      v8::Local<v8::Script> script;
+      if (!v8::ScriptCompiler::Compile(context, &scriptSource).ToLocal(&script))
+        return;
+      v8::MaybeLocal<v8::Value> result;
+      result = script->Run(context);
+    } else {
+      data->RegisterModule(context, name_, &scriptSource);
+    }
+  }
+
+ private:
+  v8::internal::Vector<uint16_t> expression_;
+  v8::internal::Vector<const char> expression_utf8_;
+  v8::internal::Vector<uint16_t> name_;
+  int32_t line_offset_ = 0;
+  int32_t column_offset_ = 0;
+  bool is_module_ = false;
+  int context_group_id_;
+
+  DISALLOW_COPY_AND_ASSIGN(ExecuteStringTask);
+};
+
+class UtilsExtension : public IsolateData::SetupGlobalTask {
+ public:
+  ~UtilsExtension() override = default;
+  void Run(v8::Isolate* isolate,
+           v8::Local<v8::ObjectTemplate> global) override {
+    v8::Local<v8::ObjectTemplate> utils = v8::ObjectTemplate::New(isolate);
+    utils->Set(ToV8String(isolate, "print"),
+               v8::FunctionTemplate::New(isolate, &UtilsExtension::Print));
+    utils->Set(ToV8String(isolate, "quit"),
+               v8::FunctionTemplate::New(isolate, &UtilsExtension::Quit));
+    utils->Set(ToV8String(isolate, "setlocale"),
+               v8::FunctionTemplate::New(isolate, &UtilsExtension::Setlocale));
+    utils->Set(ToV8String(isolate, "read"),
+               v8::FunctionTemplate::New(isolate, &UtilsExtension::Read));
+    utils->Set(ToV8String(isolate, "load"),
+               v8::FunctionTemplate::New(isolate, &UtilsExtension::Load));
+    utils->Set(ToV8String(isolate, "compileAndRunWithOrigin"),
+               v8::FunctionTemplate::New(
+                   isolate, &UtilsExtension::CompileAndRunWithOrigin));
+    utils->Set(ToV8String(isolate, "setCurrentTimeMSForTest"),
+               v8::FunctionTemplate::New(
+                   isolate, &UtilsExtension::SetCurrentTimeMSForTest));
+    utils->Set(ToV8String(isolate, "setMemoryInfoForTest"),
+               v8::FunctionTemplate::New(
+                   isolate, &UtilsExtension::SetMemoryInfoForTest));
+    utils->Set(ToV8String(isolate, "schedulePauseOnNextStatement"),
+               v8::FunctionTemplate::New(
+                   isolate, &UtilsExtension::SchedulePauseOnNextStatement));
+    utils->Set(ToV8String(isolate, "cancelPauseOnNextStatement"),
+               v8::FunctionTemplate::New(
+                   isolate, &UtilsExtension::CancelPauseOnNextStatement));
+    utils->Set(ToV8String(isolate, "setLogConsoleApiMessageCalls"),
+               v8::FunctionTemplate::New(
+                   isolate, &UtilsExtension::SetLogConsoleApiMessageCalls));
+    utils->Set(ToV8String(isolate, "createContextGroup"),
+               v8::FunctionTemplate::New(isolate,
+                                         &UtilsExtension::CreateContextGroup));
+    utils->Set(
+        ToV8String(isolate, "connectSession"),
+        v8::FunctionTemplate::New(isolate, &UtilsExtension::ConnectSession));
+    utils->Set(
+        ToV8String(isolate, "disconnectSession"),
+        v8::FunctionTemplate::New(isolate, &UtilsExtension::DisconnectSession));
+    utils->Set(ToV8String(isolate, "sendMessageToBackend"),
+               v8::FunctionTemplate::New(
+                   isolate, &UtilsExtension::SendMessageToBackend));
+    global->Set(ToV8String(isolate, "utils"), utils);
+  }
+
+  static void set_backend_task_runner(TaskRunner* runner) {
+    backend_runner_ = runner;
+  }
+
+ private:
+  static TaskRunner* backend_runner_;
+
+  static void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    for (int i = 0; i < args.Length(); i++) {
+      v8::HandleScope handle_scope(args.GetIsolate());
+      if (i != 0) {
+        printf(" ");
+      }
+
+      // Explicitly catch potential exceptions in toString().
+      v8::TryCatch try_catch(args.GetIsolate());
+      v8::Local<v8::Value> arg = args[i];
+      v8::Local<v8::String> str_obj;
+
+      if (arg->IsSymbol()) {
+        arg = v8::Local<v8::Symbol>::Cast(arg)->Name();
+      }
+      if (!arg->ToString(args.GetIsolate()->GetCurrentContext())
+               .ToLocal(&str_obj)) {
+        try_catch.ReThrow();
+        return;
+      }
+
+      v8::String::Utf8Value str(args.GetIsolate(), str_obj);
+      int n =
+          static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout));
+      if (n != str.length()) {
+        printf("Error in fwrite\n");
+        Quit(args);
+      }
+    }
+    printf("\n");
+    fflush(stdout);
+  }
+
+  static void Quit(const v8::FunctionCallbackInfo<v8::Value>& args) { Exit(); }
+
+  static void Setlocale(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 1 || !args[0]->IsString()) {
+      fprintf(stderr, "Internal error: setlocale get one string argument.");
+      Exit();
+    }
+
+    v8::String::Utf8Value str(args.GetIsolate(), args[1]);
+    setlocale(LC_NUMERIC, *str);
+  }
+
+  static bool ReadFile(v8::Isolate* isolate, v8::Local<v8::Value> name,
+                       v8::internal::Vector<const char>* chars) {
+    v8::String::Utf8Value str(isolate, name);
+    bool exists = false;
+    std::string filename(*str, str.length());
+    *chars = v8::internal::ReadFile(filename.c_str(), &exists);
+    if (!exists) {
+      isolate->ThrowException(ToV8String(isolate, "Error reading file"));
+      return false;
+    }
+    return true;
+  }
+
+  static void Read(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 1 || !args[0]->IsString()) {
+      fprintf(stderr, "Internal error: read gets one string argument.");
+      Exit();
+    }
+    v8::internal::Vector<const char> chars;
+    v8::Isolate* isolate = args.GetIsolate();
+    if (ReadFile(isolate, args[0], &chars))
+      args.GetReturnValue().Set(ToV8String(isolate, chars.start()));
+  }
+
+  static void Load(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 1 || !args[0]->IsString()) {
+      fprintf(stderr, "Internal error: load gets one string argument.");
+      Exit();
+    }
+    v8::internal::Vector<const char> chars;
+    v8::Isolate* isolate = args.GetIsolate();
+    v8::Local<v8::Context> context = isolate->GetCurrentContext();
+    IsolateData* data = IsolateData::FromContext(context);
+    int context_group_id = data->GetContextGroupId(context);
+    if (ReadFile(isolate, args[0], &chars)) {
+      ExecuteStringTask(chars, context_group_id).Run(data);
+    }
+  }
+
+  static void CompileAndRunWithOrigin(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 6 || !args[0]->IsInt32() || !args[1]->IsString() ||
+        !args[2]->IsString() || !args[3]->IsInt32() || !args[4]->IsInt32() ||
+        !args[5]->IsBoolean()) {
+      fprintf(stderr,
+              "Internal error: compileAndRunWithOrigin(context_group_id, "
+              "source, name, line, "
+              "column, is_module).");
+      Exit();
+    }
+
+    backend_runner_->Append(new ExecuteStringTask(
+        args[0].As<v8::Int32>()->Value(), ToVector(args[1].As<v8::String>()),
+        args[2].As<v8::String>(), args[3].As<v8::Int32>(),
+        args[4].As<v8::Int32>(), args[5].As<v8::Boolean>()));
+  }
+
+  static void SetCurrentTimeMSForTest(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 1 || !args[0]->IsNumber()) {
+      fprintf(stderr, "Internal error: setCurrentTimeMSForTest(time).");
+      Exit();
+    }
+    backend_runner_->data()->SetCurrentTimeMS(
+        args[0].As<v8::Number>()->Value());
+  }
+
+  static void SetMemoryInfoForTest(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 1) {
+      fprintf(stderr, "Internal error: setMemoryInfoForTest(value).");
+      Exit();
+    }
+    backend_runner_->data()->SetMemoryInfo(args[0]);
+  }
+
+  static void SchedulePauseOnNextStatement(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 3 || !args[0]->IsInt32() || !args[1]->IsString() ||
+        !args[2]->IsString()) {
+      fprintf(stderr,
+              "Internal error: schedulePauseOnNextStatement(context_group_id, "
+              "'reason', 'details').");
+      Exit();
+    }
+    v8::internal::Vector<uint16_t> reason = ToVector(args[1].As<v8::String>());
+    v8::internal::Vector<uint16_t> details = ToVector(args[2].As<v8::String>());
+    int context_group_id = args[0].As<v8::Int32>()->Value();
+    RunSyncTask(backend_runner_, [&context_group_id, &reason,
+                                  &details](IsolateData* data) {
+      data->SchedulePauseOnNextStatement(
+          context_group_id,
+          v8_inspector::StringView(reason.start(), reason.length()),
+          v8_inspector::StringView(details.start(), details.length()));
+    });
+  }
+
+  static void CancelPauseOnNextStatement(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 1 || !args[0]->IsInt32()) {
+      fprintf(stderr,
+              "Internal error: cancelPauseOnNextStatement(context_group_id).");
+      Exit();
+    }
+    int context_group_id = args[0].As<v8::Int32>()->Value();
+    RunSyncTask(backend_runner_, [&context_group_id](IsolateData* data) {
+      data->CancelPauseOnNextStatement(context_group_id);
+    });
+  }
+
+  static void SetLogConsoleApiMessageCalls(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 1 || !args[0]->IsBoolean()) {
+      fprintf(stderr, "Internal error: setLogConsoleApiMessageCalls(bool).");
+      Exit();
+    }
+    backend_runner_->data()->SetLogConsoleApiMessageCalls(
+        args[0].As<v8::Boolean>()->Value());
+  }
+
+  static void CreateContextGroup(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 0) {
+      fprintf(stderr, "Internal error: createContextGroup().");
+      Exit();
+    }
+    int context_group_id = 0;
+    RunSyncTask(backend_runner_, [&context_group_id](IsolateData* data) {
+      context_group_id = data->CreateContextGroup();
+    });
+    args.GetReturnValue().Set(
+        v8::Int32::New(args.GetIsolate(), context_group_id));
+  }
+
+  static void ConnectSession(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 3 || !args[0]->IsInt32() || !args[1]->IsString() ||
+        !args[2]->IsFunction()) {
+      fprintf(stderr,
+              "Internal error: connectionSession(context_group_id, state, "
+              "dispatch).");
+      Exit();
+    }
+    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
+    FrontendChannelImpl* channel = new FrontendChannelImpl(
+        IsolateData::FromContext(context)->task_runner(),
+        IsolateData::FromContext(context)->GetContextGroupId(context),
+        args.GetIsolate(), args[2].As<v8::Function>());
+
+    v8::internal::Vector<uint16_t> state = ToVector(args[1].As<v8::String>());
+    int context_group_id = args[0].As<v8::Int32>()->Value();
+    int session_id = 0;
+    RunSyncTask(backend_runner_, [&context_group_id, &session_id, &channel,
+                                  &state](IsolateData* data) {
+      session_id = data->ConnectSession(
+          context_group_id,
+          v8_inspector::StringView(state.start(), state.length()), channel);
+      channel->set_session_id(session_id);
+    });
+
+    channels_[session_id].reset(channel);
+    args.GetReturnValue().Set(v8::Int32::New(args.GetIsolate(), session_id));
+  }
+
+  static void DisconnectSession(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 1 || !args[0]->IsInt32()) {
+      fprintf(stderr, "Internal error: disconnectionSession(session_id).");
+      Exit();
+    }
+    int session_id = args[0].As<v8::Int32>()->Value();
+    v8::internal::Vector<uint16_t> state;
+    RunSyncTask(backend_runner_, [&session_id, &state](IsolateData* data) {
+      state = ToVector(data->DisconnectSession(session_id)->string());
+    });
+    channels_.erase(session_id);
+    args.GetReturnValue().Set(ToV8String(args.GetIsolate(), state));
+  }
+
+  static void SendMessageToBackend(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 2 || !args[0]->IsInt32() || !args[1]->IsString()) {
+      fprintf(stderr,
+              "Internal error: sendMessageToBackend(session_id, message).");
+      Exit();
+    }
+    backend_runner_->Append(new SendMessageToBackendTask(
+        args[0].As<v8::Int32>()->Value(), ToVector(args[1].As<v8::String>())));
+  }
+
+  static std::map<int, std::unique_ptr<FrontendChannelImpl>> channels_;
+};
+
+TaskRunner* UtilsExtension::backend_runner_ = nullptr;
+std::map<int, std::unique_ptr<FrontendChannelImpl>> UtilsExtension::channels_;
+
+class SetTimeoutTask : public TaskRunner::Task {
+ public:
+  SetTimeoutTask(int context_group_id, v8::Isolate* isolate,
+                 v8::Local<v8::Function> function)
+      : function_(isolate, function), context_group_id_(context_group_id) {}
+  virtual ~SetTimeoutTask() {}
+  bool is_priority_task() final { return false; }
+
+ private:
+  void Run(IsolateData* data) override {
+    v8::MicrotasksScope microtasks_scope(data->isolate(),
+                                         v8::MicrotasksScope::kRunMicrotasks);
+    v8::HandleScope handle_scope(data->isolate());
+    v8::Local<v8::Context> context = data->GetContext(context_group_id_);
+    v8::Context::Scope context_scope(context);
+
+    v8::Local<v8::Function> function = function_.Get(data->isolate());
+    v8::MaybeLocal<v8::Value> result;
+    result = function->Call(context, context->Global(), 0, nullptr);
+  }
+
+  v8::Global<v8::Function> function_;
+  int context_group_id_;
+};
+
+class SetTimeoutExtension : public IsolateData::SetupGlobalTask {
+ public:
+  void Run(v8::Isolate* isolate,
+           v8::Local<v8::ObjectTemplate> global) override {
+    global->Set(
+        ToV8String(isolate, "setTimeout"),
+        v8::FunctionTemplate::New(isolate, &SetTimeoutExtension::SetTimeout));
+  }
+
+ private:
+  static void SetTimeout(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 2 || !args[1]->IsNumber() ||
+        (!args[0]->IsFunction() && !args[0]->IsString()) ||
+        args[1].As<v8::Number>()->Value() != 0.0) {
+      fprintf(
+          stderr,
+          "Internal error: only setTimeout(function|code, 0) is supported.");
+      Exit();
+    }
+    v8::Isolate* isolate = args.GetIsolate();
+    v8::Local<v8::Context> context = isolate->GetCurrentContext();
+    IsolateData* data = IsolateData::FromContext(context);
+    int context_group_id = data->GetContextGroupId(context);
+    if (args[0]->IsFunction()) {
+      RunAsyncTask(data->task_runner(), "setTimeout",
+                   new SetTimeoutTask(context_group_id, isolate,
+                                      v8::Local<v8::Function>::Cast(args[0])));
+    } else {
+      RunAsyncTask(
+          data->task_runner(), "setTimeout",
+          new ExecuteStringTask(
+              context_group_id, ToVector(args[0].As<v8::String>()),
+              v8::String::Empty(isolate), v8::Integer::New(isolate, 0),
+              v8::Integer::New(isolate, 0), v8::Boolean::New(isolate, false)));
+    }
+  }
+};
+
+bool StrictAccessCheck(v8::Local<v8::Context> accessing_context,
+                       v8::Local<v8::Object> accessed_object,
+                       v8::Local<v8::Value> data) {
+  CHECK(accessing_context.IsEmpty());
+  return accessing_context.IsEmpty();
+}
+
+class InspectorExtension : public IsolateData::SetupGlobalTask {
+ public:
+  ~InspectorExtension() override = default;
+  void Run(v8::Isolate* isolate,
+           v8::Local<v8::ObjectTemplate> global) override {
+    v8::Local<v8::ObjectTemplate> inspector = v8::ObjectTemplate::New(isolate);
+    inspector->Set(ToV8String(isolate, "fireContextCreated"),
+                   v8::FunctionTemplate::New(
+                       isolate, &InspectorExtension::FireContextCreated));
+    inspector->Set(ToV8String(isolate, "fireContextDestroyed"),
+                   v8::FunctionTemplate::New(
+                       isolate, &InspectorExtension::FireContextDestroyed));
+    inspector->Set(
+        ToV8String(isolate, "freeContext"),
+        v8::FunctionTemplate::New(isolate, &InspectorExtension::FreeContext));
+    inspector->Set(ToV8String(isolate, "addInspectedObject"),
+                   v8::FunctionTemplate::New(
+                       isolate, &InspectorExtension::AddInspectedObject));
+    inspector->Set(ToV8String(isolate, "setMaxAsyncTaskStacks"),
+                   v8::FunctionTemplate::New(
+                       isolate, &InspectorExtension::SetMaxAsyncTaskStacks));
+    inspector->Set(
+        ToV8String(isolate, "dumpAsyncTaskStacksStateForTest"),
+        v8::FunctionTemplate::New(
+            isolate, &InspectorExtension::DumpAsyncTaskStacksStateForTest));
+    inspector->Set(
+        ToV8String(isolate, "breakProgram"),
+        v8::FunctionTemplate::New(isolate, &InspectorExtension::BreakProgram));
+    inspector->Set(
+        ToV8String(isolate, "createObjectWithStrictCheck"),
+        v8::FunctionTemplate::New(
+            isolate, &InspectorExtension::CreateObjectWithStrictCheck));
+    inspector->Set(ToV8String(isolate, "callWithScheduledBreak"),
+                   v8::FunctionTemplate::New(
+                       isolate, &InspectorExtension::CallWithScheduledBreak));
+    inspector->Set(ToV8String(isolate, "allowAccessorFormatting"),
+                   v8::FunctionTemplate::New(
+                       isolate, &InspectorExtension::AllowAccessorFormatting));
+    inspector->Set(
+        ToV8String(isolate, "markObjectAsNotInspectable"),
+        v8::FunctionTemplate::New(
+            isolate, &InspectorExtension::MarkObjectAsNotInspectable));
+    global->Set(ToV8String(isolate, "inspector"), inspector);
+  }
+
+ private:
+  static void FireContextCreated(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
+    IsolateData* data = IsolateData::FromContext(context);
+    data->FireContextCreated(context, data->GetContextGroupId(context));
+  }
+
+  static void FireContextDestroyed(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
+    IsolateData* data = IsolateData::FromContext(context);
+    data->FireContextDestroyed(context);
+  }
+
+  static void FreeContext(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
+    IsolateData* data = IsolateData::FromContext(context);
+    data->FreeContext(context);
+  }
+
+  static void AddInspectedObject(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 2 || !args[0]->IsInt32()) {
+      fprintf(stderr,
+              "Internal error: addInspectedObject(session_id, object).");
+      Exit();
+    }
+    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
+    IsolateData* data = IsolateData::FromContext(context);
+    data->AddInspectedObject(args[0].As<v8::Int32>()->Value(), args[1]);
+  }
+
+  static void SetMaxAsyncTaskStacks(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 1 || !args[0]->IsInt32()) {
+      fprintf(stderr, "Internal error: setMaxAsyncTaskStacks(max).");
+      Exit();
+    }
+    IsolateData::FromContext(args.GetIsolate()->GetCurrentContext())
+        ->SetMaxAsyncTaskStacksForTest(args[0].As<v8::Int32>()->Value());
+  }
+
+  static void DumpAsyncTaskStacksStateForTest(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 0) {
+      fprintf(stderr, "Internal error: dumpAsyncTaskStacksStateForTest().");
+      Exit();
+    }
+    IsolateData::FromContext(args.GetIsolate()->GetCurrentContext())
+        ->DumpAsyncTaskStacksStateForTest();
+  }
+
+  static void BreakProgram(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) {
+      fprintf(stderr, "Internal error: breakProgram('reason', 'details').");
+      Exit();
+    }
+    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
+    IsolateData* data = IsolateData::FromContext(context);
+    v8::internal::Vector<uint16_t> reason = ToVector(args[0].As<v8::String>());
+    v8_inspector::StringView reason_view(reason.start(), reason.length());
+    v8::internal::Vector<uint16_t> details = ToVector(args[1].As<v8::String>());
+    v8_inspector::StringView details_view(details.start(), details.length());
+    data->BreakProgram(data->GetContextGroupId(context), reason_view,
+                       details_view);
+  }
+
+  static void CreateObjectWithStrictCheck(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 0) {
+      fprintf(stderr, "Internal error: createObjectWithStrictCheck().");
+      Exit();
+    }
+    v8::Local<v8::ObjectTemplate> templ =
+        v8::ObjectTemplate::New(args.GetIsolate());
+    templ->SetAccessCheckCallback(&StrictAccessCheck);
+    args.GetReturnValue().Set(
+        templ->NewInstance(args.GetIsolate()->GetCurrentContext())
+            .ToLocalChecked());
+  }
+
+  static void CallWithScheduledBreak(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 3 || !args[0]->IsFunction() || !args[1]->IsString() ||
+        !args[2]->IsString()) {
+      fprintf(stderr,
+              "Internal error: callWithScheduledBreak('reason', 'details').");
+      Exit();
+    }
+    v8::internal::Vector<uint16_t> reason = ToVector(args[1].As<v8::String>());
+    v8_inspector::StringView reason_view(reason.start(), reason.length());
+    v8::internal::Vector<uint16_t> details = ToVector(args[2].As<v8::String>());
+    v8_inspector::StringView details_view(details.start(), details.length());
+    v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
+    IsolateData* data = IsolateData::FromContext(context);
+    int context_group_id = data->GetContextGroupId(context);
+    data->SchedulePauseOnNextStatement(context_group_id, reason_view,
+                                       details_view);
+    v8::MaybeLocal<v8::Value> result;
+    result = args[0].As<v8::Function>()->Call(context, context->Global(), 0,
+                                              nullptr);
+    data->CancelPauseOnNextStatement(context_group_id);
+  }
+
+  static void AllowAccessorFormatting(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 1 || !args[0]->IsObject()) {
+      fprintf(stderr, "Internal error: allowAccessorFormatting('object').");
+      Exit();
+    }
+    v8::Local<v8::Object> object = args[0].As<v8::Object>();
+    v8::Isolate* isolate = args.GetIsolate();
+    v8::Local<v8::Private> shouldFormatAccessorsPrivate = v8::Private::ForApi(
+        isolate, ToV8String(isolate, "allowAccessorFormatting"));
+    object
+        ->SetPrivate(isolate->GetCurrentContext(), shouldFormatAccessorsPrivate,
+                     v8::Null(isolate))
+        .ToChecked();
+  }
+
+  static void MarkObjectAsNotInspectable(
+      const v8::FunctionCallbackInfo<v8::Value>& args) {
+    if (args.Length() != 1 || !args[0]->IsObject()) {
+      fprintf(stderr, "Internal error: markObjectAsNotInspectable(object).");
+      Exit();
+    }
+    v8::Local<v8::Object> object = args[0].As<v8::Object>();
+    v8::Isolate* isolate = args.GetIsolate();
+    v8::Local<v8::Private> notInspectablePrivate =
+        v8::Private::ForApi(isolate, ToV8String(isolate, "notInspectable"));
+    object
+        ->SetPrivate(isolate->GetCurrentContext(), notInspectablePrivate,
+                     v8::True(isolate))
+        .ToChecked();
+  }
+};
+
+}  //  namespace
+
+int main(int argc, char* argv[]) {
+  v8::V8::InitializeICUDefaultLocation(argv[0]);
+  v8::Platform* platform = v8::platform::CreateDefaultPlatform();
+  v8::V8::InitializePlatform(platform);
+  v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
+  v8::V8::InitializeExternalStartupData(argv[0]);
+  v8::V8::Initialize();
+
+  v8::base::Semaphore ready_semaphore(0);
+
+  v8::StartupData startup_data = {nullptr, 0};
+  for (int i = 1; i < argc; ++i) {
+    if (strcmp(argv[i], "--embed") == 0) {
+      argv[i++] = nullptr;
+      printf("Embedding script '%s'\n", argv[i]);
+      startup_data = v8::V8::CreateSnapshotDataBlob(argv[i]);
+      argv[i] = nullptr;
+    }
+  }
+
+  IsolateData::SetupGlobalTasks frontend_extensions;
+  frontend_extensions.emplace_back(new UtilsExtension());
+  TaskRunner frontend_runner(std::move(frontend_extensions), true,
+                             &ready_semaphore, nullptr, false);
+  ready_semaphore.Wait();
+
+  int frontend_context_group_id = 0;
+  RunSyncTask(&frontend_runner,
+              [&frontend_context_group_id](IsolateData* data) {
+                frontend_context_group_id = data->CreateContextGroup();
+              });
+
+  IsolateData::SetupGlobalTasks backend_extensions;
+  backend_extensions.emplace_back(new SetTimeoutExtension());
+  backend_extensions.emplace_back(new InspectorExtension());
+  TaskRunner backend_runner(std::move(backend_extensions), false,
+                            &ready_semaphore,
+                            startup_data.data ? &startup_data : nullptr, true);
+  ready_semaphore.Wait();
+  UtilsExtension::set_backend_task_runner(&backend_runner);
+
+  task_runners.push_back(&frontend_runner);
+  task_runners.push_back(&backend_runner);
+
+  for (int i = 1; i < argc; ++i) {
+    // Ignore unknown flags.
+    if (argv[i] == nullptr || argv[i][0] == '-') continue;
+
+    bool exists = false;
+    v8::internal::Vector<const char> chars =
+        v8::internal::ReadFile(argv[i], &exists, true);
+    if (!exists) {
+      fprintf(stderr, "Internal error: script file doesn't exists: %s\n",
+              argv[i]);
+      Exit();
+    }
+    frontend_runner.Append(
+        new ExecuteStringTask(chars, frontend_context_group_id));
+  }
+
+  frontend_runner.Join();
+  backend_runner.Join();
+
+  delete startup_data.data;
+  return 0;
+}
diff --git a/src/v8/test/inspector/inspector.gyp b/src/v8/test/inspector/inspector.gyp
new file mode 100644
index 0000000..b465f9e
--- /dev/null
+++ b/src/v8/test/inspector/inspector.gyp
@@ -0,0 +1,58 @@
+# Copyright 2016 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.
+
+{
+  'variables': {
+    'v8_code': 1,
+  },
+  'includes': ['../../gypfiles/toolchain.gypi', '../../gypfiles/features.gypi'],
+  'targets': [
+    {
+      'target_name': 'inspector-test',
+      'type': 'executable',
+      'dependencies': [
+        '../../src/v8.gyp:v8_libplatform',
+        '../../src/v8.gyp:v8_libbase',
+        '../../src/v8.gyp:v8',
+      ],
+      'include_dirs': [
+        '../..',
+      ],
+      'sources': [
+        'inspector-test.cc',
+        'isolate-data.cc',
+        'isolate-data.h',
+        'task-runner.cc',
+        'task-runner.h',
+      ],
+      'conditions': [
+        ['v8_enable_i18n_support==1', {
+          'dependencies': [
+            '<(icu_gyp_path):icui18n',
+            '<(icu_gyp_path):icuuc',
+          ],
+        }],
+      ],
+    },
+  ],
+  'conditions': [
+    ['test_isolation_mode != "noop"', {
+      'targets': [
+        {
+          'target_name': 'inspector-test_run',
+          'type': 'none',
+          'dependencies': [
+            'inspector-test',
+          ],
+          'includes': [
+            '../../gypfiles/isolate.gypi',
+          ],
+          'sources': [
+            'inspector.isolate',
+          ],
+        },
+      ],
+    }],
+  ],
+}
diff --git a/src/v8/test/inspector/inspector.isolate b/src/v8/test/inspector/inspector.isolate
new file mode 100644
index 0000000..38a96c5
--- /dev/null
+++ b/src/v8/test/inspector/inspector.isolate
@@ -0,0 +1,27 @@
+# Copyright 2016 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.
+{
+  'variables': {
+    'files': [
+      './console/',
+      './cpu-profiler/',
+      './debugger/',
+      './heap-profiler/',
+      './inspector.status',
+      './json-parse-expected.txt',
+      './json-parse.js',
+      './protocol-test.js',
+      './runtime/',
+      './sessions/',
+      './testcfg.py',
+      './type-profiler/',
+      '../../src/inspector/injected-script-source.js',
+      '<(PRODUCT_DIR)/inspector-test<(EXECUTABLE_SUFFIX)',
+    ],
+  },
+  'includes': [
+    '../../src/base.isolate',
+    '../../tools/testrunner/testrunner.isolate',
+  ],
+}
diff --git a/src/v8/test/inspector/inspector.status b/src/v8/test/inspector/inspector.status
new file mode 100644
index 0000000..0fb349e
--- /dev/null
+++ b/src/v8/test/inspector/inspector.status
@@ -0,0 +1,27 @@
+# Copyright 2016 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.
+
+[
+
+##############################################################################
+['variant != default', {
+  # Issue 6167.
+  'debugger/eval-scopes': [PASS, FAIL],
+  'debugger/scope-skip-variables-with-empty-name': [PASS, FAIL],
+  'debugger/update-call-frame-scopes': [PASS, FAIL],
+  'debugger/side-effect-free-debug-evaluate': [PASS, FAIL],
+  'debugger/evaluate-on-call-frame-in-module': [PASS, FAIL],
+  # Issue 6170. Crash.
+  'cpu-profiler/console-profile': [SKIP],
+  'cpu-profiler/console-profile-end-parameterless-crash': [SKIP],
+  # Issue 6171. Timeout.
+  'debugger/set-blackbox-patterns': [SKIP],
+}],  # variant != default
+
+##############################################################################
+['variant == wasm_traps', {
+  '*': [SKIP],
+}],  # variant == wasm_traps
+
+]
diff --git a/src/v8/test/inspector/isolate-data.cc b/src/v8/test/inspector/isolate-data.cc
new file mode 100644
index 0000000..e43dd21
--- /dev/null
+++ b/src/v8/test/inspector/isolate-data.cc
@@ -0,0 +1,398 @@
+// Copyright 2017 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.
+
+#include "test/inspector/isolate-data.h"
+
+#include "src/inspector/test-interface.h"
+#include "test/inspector/task-runner.h"
+
+namespace {
+
+const int kIsolateDataIndex = 2;
+const int kContextGroupIdIndex = 3;
+
+v8::internal::Vector<uint16_t> ToVector(v8::Local<v8::String> str) {
+  v8::internal::Vector<uint16_t> buffer =
+      v8::internal::Vector<uint16_t>::New(str->Length());
+  str->Write(buffer.start(), 0, str->Length());
+  return buffer;
+}
+
+v8::Local<v8::String> ToString(v8::Isolate* isolate,
+                               const v8_inspector::StringView& string) {
+  if (string.is8Bit())
+    return v8::String::NewFromOneByte(isolate, string.characters8(),
+                                      v8::NewStringType::kNormal,
+                                      static_cast<int>(string.length()))
+        .ToLocalChecked();
+  else
+    return v8::String::NewFromTwoByte(isolate, string.characters16(),
+                                      v8::NewStringType::kNormal,
+                                      static_cast<int>(string.length()))
+        .ToLocalChecked();
+}
+
+void Print(v8::Isolate* isolate, const v8_inspector::StringView& string) {
+  v8::Local<v8::String> v8_string = ToString(isolate, string);
+  v8::String::Utf8Value utf8_string(isolate, v8_string);
+  fwrite(*utf8_string, sizeof(**utf8_string), utf8_string.length(), stdout);
+}
+
+class Inspectable : public v8_inspector::V8InspectorSession::Inspectable {
+ public:
+  Inspectable(v8::Isolate* isolate, v8::Local<v8::Value> object)
+      : object_(isolate, object) {}
+  ~Inspectable() override {}
+  v8::Local<v8::Value> get(v8::Local<v8::Context> context) override {
+    return object_.Get(context->GetIsolate());
+  }
+
+ private:
+  v8::Global<v8::Value> object_;
+};
+
+}  //  namespace
+
+IsolateData::IsolateData(TaskRunner* task_runner,
+                         IsolateData::SetupGlobalTasks setup_global_tasks,
+                         v8::StartupData* startup_data, bool with_inspector)
+    : task_runner_(task_runner),
+      setup_global_tasks_(std::move(setup_global_tasks)) {
+  v8::Isolate::CreateParams params;
+  params.array_buffer_allocator =
+      v8::ArrayBuffer::Allocator::NewDefaultAllocator();
+  params.snapshot_blob = startup_data;
+  isolate_ = v8::Isolate::New(params);
+  isolate_->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped);
+  if (with_inspector) {
+    isolate_->AddMessageListener(&IsolateData::MessageHandler);
+    isolate_->SetPromiseRejectCallback(&IsolateData::PromiseRejectHandler);
+    inspector_ = v8_inspector::V8Inspector::create(isolate_, this);
+  }
+  v8::HandleScope handle_scope(isolate_);
+  not_inspectable_private_.Reset(
+      isolate_, v8::Private::ForApi(isolate_, v8::String::NewFromUtf8(
+                                                  isolate_, "notInspectable",
+                                                  v8::NewStringType::kNormal)
+                                                  .ToLocalChecked()));
+}
+
+IsolateData* IsolateData::FromContext(v8::Local<v8::Context> context) {
+  return static_cast<IsolateData*>(
+      context->GetAlignedPointerFromEmbedderData(kIsolateDataIndex));
+}
+
+int IsolateData::CreateContextGroup() {
+  v8::HandleScope handle_scope(isolate_);
+  v8::Local<v8::ObjectTemplate> global_template =
+      v8::ObjectTemplate::New(isolate_);
+  for (auto it = setup_global_tasks_.begin(); it != setup_global_tasks_.end();
+       ++it) {
+    (*it)->Run(isolate_, global_template);
+  }
+  v8::Local<v8::Context> context =
+      v8::Context::New(isolate_, nullptr, global_template);
+  context->SetAlignedPointerInEmbedderData(kIsolateDataIndex, this);
+  int context_group_id = ++last_context_group_id_;
+  // Should be 2-byte aligned.
+  context->SetAlignedPointerInEmbedderData(
+      kContextGroupIdIndex, reinterpret_cast<void*>(context_group_id * 2));
+  contexts_[context_group_id].Reset(isolate_, context);
+  if (inspector_) FireContextCreated(context, context_group_id);
+  return context_group_id;
+}
+
+v8::Local<v8::Context> IsolateData::GetContext(int context_group_id) {
+  return contexts_[context_group_id].Get(isolate_);
+}
+
+int IsolateData::GetContextGroupId(v8::Local<v8::Context> context) {
+  return static_cast<int>(
+      reinterpret_cast<intptr_t>(
+          context->GetAlignedPointerFromEmbedderData(kContextGroupIdIndex)) /
+      2);
+}
+
+void IsolateData::RegisterModule(v8::Local<v8::Context> context,
+                                 v8::internal::Vector<uint16_t> name,
+                                 v8::ScriptCompiler::Source* source) {
+  v8::Local<v8::Module> module;
+  if (!v8::ScriptCompiler::CompileModule(isolate(), source).ToLocal(&module))
+    return;
+  if (!module->InstantiateModule(context, &IsolateData::ModuleResolveCallback)
+           .FromMaybe(false)) {
+    return;
+  }
+  v8::Local<v8::Value> result;
+  if (!module->Evaluate(context).ToLocal(&result)) return;
+  modules_[name] = v8::Global<v8::Module>(isolate_, module);
+}
+
+// static
+v8::MaybeLocal<v8::Module> IsolateData::ModuleResolveCallback(
+    v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
+    v8::Local<v8::Module> referrer) {
+  IsolateData* data = IsolateData::FromContext(context);
+  std::string str = *v8::String::Utf8Value(data->isolate_, specifier);
+  return data->modules_[ToVector(specifier)].Get(data->isolate_);
+}
+
+int IsolateData::ConnectSession(int context_group_id,
+                                const v8_inspector::StringView& state,
+                                v8_inspector::V8Inspector::Channel* channel) {
+  int session_id = ++last_session_id_;
+  sessions_[session_id] = inspector_->connect(context_group_id, channel, state);
+  context_group_by_session_[sessions_[session_id].get()] = context_group_id;
+  return session_id;
+}
+
+std::unique_ptr<v8_inspector::StringBuffer> IsolateData::DisconnectSession(
+    int session_id) {
+  auto it = sessions_.find(session_id);
+  CHECK(it != sessions_.end());
+  context_group_by_session_.erase(it->second.get());
+  std::unique_ptr<v8_inspector::StringBuffer> result = it->second->stateJSON();
+  sessions_.erase(it);
+  return result;
+}
+
+void IsolateData::SendMessage(int session_id,
+                              const v8_inspector::StringView& message) {
+  auto it = sessions_.find(session_id);
+  if (it != sessions_.end()) it->second->dispatchProtocolMessage(message);
+}
+
+void IsolateData::BreakProgram(int context_group_id,
+                               const v8_inspector::StringView& reason,
+                               const v8_inspector::StringView& details) {
+  for (int session_id : GetSessionIds(context_group_id)) {
+    auto it = sessions_.find(session_id);
+    if (it != sessions_.end()) it->second->breakProgram(reason, details);
+  }
+}
+
+void IsolateData::SchedulePauseOnNextStatement(
+    int context_group_id, const v8_inspector::StringView& reason,
+    const v8_inspector::StringView& details) {
+  for (int session_id : GetSessionIds(context_group_id)) {
+    auto it = sessions_.find(session_id);
+    if (it != sessions_.end())
+      it->second->schedulePauseOnNextStatement(reason, details);
+  }
+}
+
+void IsolateData::CancelPauseOnNextStatement(int context_group_id) {
+  for (int session_id : GetSessionIds(context_group_id)) {
+    auto it = sessions_.find(session_id);
+    if (it != sessions_.end()) it->second->cancelPauseOnNextStatement();
+  }
+}
+
+void IsolateData::AsyncTaskScheduled(const v8_inspector::StringView& name,
+                                     void* task, bool recurring) {
+  inspector_->asyncTaskScheduled(name, task, recurring);
+}
+
+void IsolateData::AsyncTaskStarted(void* task) {
+  inspector_->asyncTaskStarted(task);
+}
+
+void IsolateData::AsyncTaskFinished(void* task) {
+  inspector_->asyncTaskFinished(task);
+}
+
+void IsolateData::AddInspectedObject(int session_id,
+                                     v8::Local<v8::Value> object) {
+  auto it = sessions_.find(session_id);
+  if (it == sessions_.end()) return;
+  std::unique_ptr<Inspectable> inspectable(new Inspectable(isolate_, object));
+  it->second->addInspectedObject(std::move(inspectable));
+}
+
+void IsolateData::SetMaxAsyncTaskStacksForTest(int limit) {
+  v8_inspector::SetMaxAsyncTaskStacksForTest(inspector_.get(), limit);
+}
+
+void IsolateData::DumpAsyncTaskStacksStateForTest() {
+  v8_inspector::DumpAsyncTaskStacksStateForTest(inspector_.get());
+}
+
+// static
+int IsolateData::HandleMessage(v8::Local<v8::Message> message,
+                               v8::Local<v8::Value> exception) {
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+  v8::Local<v8::Context> context = isolate->GetEnteredContext();
+  if (context.IsEmpty()) return 0;
+  v8_inspector::V8Inspector* inspector =
+      IsolateData::FromContext(context)->inspector_.get();
+
+  v8::Local<v8::StackTrace> stack = message->GetStackTrace();
+  int script_id =
+      static_cast<int>(message->GetScriptOrigin().ScriptID()->Value());
+  if (!stack.IsEmpty() && stack->GetFrameCount() > 0) {
+    int top_script_id = stack->GetFrame(0)->GetScriptId();
+    if (top_script_id == script_id) script_id = 0;
+  }
+  int line_number = message->GetLineNumber(context).FromMaybe(0);
+  int column_number = 0;
+  if (message->GetStartColumn(context).IsJust())
+    column_number = message->GetStartColumn(context).FromJust() + 1;
+
+  v8_inspector::StringView detailed_message;
+  v8::internal::Vector<uint16_t> message_text_string = ToVector(message->Get());
+  v8_inspector::StringView message_text(message_text_string.start(),
+                                        message_text_string.length());
+  v8::internal::Vector<uint16_t> url_string;
+  if (message->GetScriptOrigin().ResourceName()->IsString()) {
+    url_string =
+        ToVector(message->GetScriptOrigin().ResourceName().As<v8::String>());
+  }
+  v8_inspector::StringView url(url_string.start(), url_string.length());
+
+  return inspector->exceptionThrown(
+      context, message_text, exception, detailed_message, url, line_number,
+      column_number, inspector->createStackTrace(stack), script_id);
+}
+
+// static
+void IsolateData::MessageHandler(v8::Local<v8::Message> message,
+                                 v8::Local<v8::Value> exception) {
+  HandleMessage(message, exception);
+}
+
+// static
+void IsolateData::PromiseRejectHandler(v8::PromiseRejectMessage data) {
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+  v8::Local<v8::Context> context = isolate->GetEnteredContext();
+  if (context.IsEmpty()) return;
+  v8::Local<v8::Promise> promise = data.GetPromise();
+  v8::Local<v8::Private> id_private = v8::Private::ForApi(
+      isolate,
+      v8::String::NewFromUtf8(isolate, "id", v8::NewStringType::kNormal)
+          .ToLocalChecked());
+
+  if (data.GetEvent() == v8::kPromiseHandlerAddedAfterReject) {
+    v8::Local<v8::Value> id;
+    if (!promise->GetPrivate(context, id_private).ToLocal(&id)) return;
+    if (!id->IsInt32()) return;
+    v8_inspector::V8Inspector* inspector =
+        IsolateData::FromContext(context)->inspector_.get();
+    const char* reason_str = "Handler added to rejected promise";
+    inspector->exceptionRevoked(
+        context, id.As<v8::Int32>()->Value(),
+        v8_inspector::StringView(reinterpret_cast<const uint8_t*>(reason_str),
+                                 strlen(reason_str)));
+    return;
+  }
+
+  v8::Local<v8::Value> exception = data.GetValue();
+  int exception_id = HandleMessage(
+      v8::Exception::CreateMessage(isolate, exception), exception);
+  if (exception_id) {
+    promise
+        ->SetPrivate(isolate->GetCurrentContext(), id_private,
+                     v8::Int32::New(isolate, exception_id))
+        .ToChecked();
+  }
+}
+
+void IsolateData::FireContextCreated(v8::Local<v8::Context> context,
+                                     int context_group_id) {
+  v8_inspector::V8ContextInfo info(context, context_group_id,
+                                   v8_inspector::StringView());
+  info.hasMemoryOnConsole = true;
+  inspector_->contextCreated(info);
+}
+
+void IsolateData::FireContextDestroyed(v8::Local<v8::Context> context) {
+  inspector_->contextDestroyed(context);
+}
+
+void IsolateData::FreeContext(v8::Local<v8::Context> context) {
+  int context_group_id = GetContextGroupId(context);
+  auto it = contexts_.find(context_group_id);
+  if (it == contexts_.end()) return;
+  contexts_.erase(it);
+}
+
+std::vector<int> IsolateData::GetSessionIds(int context_group_id) {
+  std::vector<int> result;
+  for (auto& it : sessions_) {
+    if (context_group_by_session_[it.second.get()] == context_group_id)
+      result.push_back(it.first);
+  }
+  return result;
+}
+
+bool IsolateData::formatAccessorsAsProperties(v8::Local<v8::Value> object) {
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+  v8::Local<v8::Context> context = isolate->GetCurrentContext();
+  v8::Local<v8::Private> shouldFormatAccessorsPrivate = v8::Private::ForApi(
+      isolate, v8::String::NewFromUtf8(isolate, "allowAccessorFormatting",
+                                       v8::NewStringType::kNormal)
+                   .ToLocalChecked());
+  CHECK(object->IsObject());
+  return object.As<v8::Object>()
+      ->HasPrivate(context, shouldFormatAccessorsPrivate)
+      .FromMaybe(false);
+}
+
+bool IsolateData::isInspectableHeapObject(v8::Local<v8::Object> object) {
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+  v8::Local<v8::Context> context = isolate->GetCurrentContext();
+  v8::MicrotasksScope microtasks_scope(
+      isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);
+  return !object->HasPrivate(context, not_inspectable_private_.Get(isolate))
+              .FromMaybe(false);
+}
+
+v8::Local<v8::Context> IsolateData::ensureDefaultContextInGroup(
+    int context_group_id) {
+  return GetContext(context_group_id);
+}
+
+void IsolateData::SetCurrentTimeMS(double time) {
+  current_time_ = time;
+  current_time_set_ = true;
+}
+
+double IsolateData::currentTimeMS() {
+  if (current_time_set_) return current_time_;
+  return v8::internal::V8::GetCurrentPlatform()->CurrentClockTimeMillis();
+}
+
+void IsolateData::SetMemoryInfo(v8::Local<v8::Value> memory_info) {
+  memory_info_.Reset(isolate_, memory_info);
+}
+
+void IsolateData::SetLogConsoleApiMessageCalls(bool log) {
+  log_console_api_message_calls_ = log;
+}
+
+v8::MaybeLocal<v8::Value> IsolateData::memoryInfo(v8::Isolate* isolate,
+                                                  v8::Local<v8::Context>) {
+  if (memory_info_.IsEmpty()) return v8::MaybeLocal<v8::Value>();
+  return memory_info_.Get(isolate);
+}
+
+void IsolateData::runMessageLoopOnPause(int) {
+  task_runner_->RunMessageLoop(true);
+}
+
+void IsolateData::quitMessageLoopOnPause() { task_runner_->QuitMessageLoop(); }
+
+void IsolateData::consoleAPIMessage(int contextGroupId,
+                                    v8::Isolate::MessageErrorLevel level,
+                                    const v8_inspector::StringView& message,
+                                    const v8_inspector::StringView& url,
+                                    unsigned lineNumber, unsigned columnNumber,
+                                    v8_inspector::V8StackTrace* stack) {
+  if (!log_console_api_message_calls_) return;
+  Print(isolate_, message);
+  fprintf(stdout, " (");
+  Print(isolate_, url);
+  fprintf(stdout, ":%d:%d)", lineNumber, columnNumber);
+  Print(isolate_, stack->toString()->string());
+  fprintf(stdout, "\n");
+}
diff --git a/src/v8/test/inspector/isolate-data.h b/src/v8/test/inspector/isolate-data.h
new file mode 100644
index 0000000..b8f3b9e
--- /dev/null
+++ b/src/v8/test/inspector/isolate-data.h
@@ -0,0 +1,131 @@
+// Copyright 2017 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.
+
+#ifndef V8_TEST_INSPECTOR_PROTOCOL_ISOLATE_DATA_H_
+#define V8_TEST_INSPECTOR_PROTOCOL_ISOLATE_DATA_H_
+
+#include <map>
+
+#include "include/v8-inspector.h"
+#include "include/v8-platform.h"
+#include "include/v8.h"
+#include "src/base/macros.h"
+#include "src/base/platform/platform.h"
+#include "src/vector.h"
+
+class TaskRunner;
+
+class IsolateData : public v8_inspector::V8InspectorClient {
+ public:
+  class SetupGlobalTask {
+   public:
+    virtual ~SetupGlobalTask() = default;
+    virtual void Run(v8::Isolate* isolate,
+                     v8::Local<v8::ObjectTemplate> global) = 0;
+  };
+  using SetupGlobalTasks = std::vector<std::unique_ptr<SetupGlobalTask>>;
+
+  IsolateData(TaskRunner* task_runner, SetupGlobalTasks setup_global_tasks,
+              v8::StartupData* startup_data, bool with_inspector);
+  static IsolateData* FromContext(v8::Local<v8::Context> context);
+
+  v8::Isolate* isolate() const { return isolate_; }
+  TaskRunner* task_runner() const { return task_runner_; }
+
+  // Setting things up.
+  int CreateContextGroup();
+  v8::Local<v8::Context> GetContext(int context_group_id);
+  int GetContextGroupId(v8::Local<v8::Context> context);
+  void RegisterModule(v8::Local<v8::Context> context,
+                      v8::internal::Vector<uint16_t> name,
+                      v8::ScriptCompiler::Source* source);
+
+  // Working with V8Inspector api.
+  int ConnectSession(int context_group_id,
+                     const v8_inspector::StringView& state,
+                     v8_inspector::V8Inspector::Channel* channel);
+  std::unique_ptr<v8_inspector::StringBuffer> DisconnectSession(int session_id);
+  void SendMessage(int session_id, const v8_inspector::StringView& message);
+  void BreakProgram(int context_group_id,
+                    const v8_inspector::StringView& reason,
+                    const v8_inspector::StringView& details);
+  void SchedulePauseOnNextStatement(int context_group_id,
+                                    const v8_inspector::StringView& reason,
+                                    const v8_inspector::StringView& details);
+  void CancelPauseOnNextStatement(int context_group_id);
+  void AsyncTaskScheduled(const v8_inspector::StringView& name, void* task,
+                          bool recurring);
+  void AsyncTaskStarted(void* task);
+  void AsyncTaskFinished(void* task);
+  void AddInspectedObject(int session_id, v8::Local<v8::Value> object);
+
+  // Test utilities.
+  void SetCurrentTimeMS(double time);
+  void SetMemoryInfo(v8::Local<v8::Value> memory_info);
+  void SetLogConsoleApiMessageCalls(bool log);
+  void SetMaxAsyncTaskStacksForTest(int limit);
+  void DumpAsyncTaskStacksStateForTest();
+  void FireContextCreated(v8::Local<v8::Context> context, int context_group_id);
+  void FireContextDestroyed(v8::Local<v8::Context> context);
+  void FreeContext(v8::Local<v8::Context> context);
+
+ private:
+  struct VectorCompare {
+    bool operator()(const v8::internal::Vector<uint16_t>& lhs,
+                    const v8::internal::Vector<uint16_t>& rhs) const {
+      for (int i = 0; i < lhs.length() && i < rhs.length(); ++i) {
+        if (lhs[i] != rhs[i]) return lhs[i] < rhs[i];
+      }
+      return false;
+    }
+  };
+  static v8::MaybeLocal<v8::Module> ModuleResolveCallback(
+      v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
+      v8::Local<v8::Module> referrer);
+  static void MessageHandler(v8::Local<v8::Message> message,
+                             v8::Local<v8::Value> exception);
+  static void PromiseRejectHandler(v8::PromiseRejectMessage data);
+  static int HandleMessage(v8::Local<v8::Message> message,
+                           v8::Local<v8::Value> exception);
+  std::vector<int> GetSessionIds(int context_group_id);
+
+  // V8InspectorClient implementation.
+  bool formatAccessorsAsProperties(v8::Local<v8::Value>) override;
+  v8::Local<v8::Context> ensureDefaultContextInGroup(
+      int context_group_id) override;
+  double currentTimeMS() override;
+  v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate* isolate,
+                                       v8::Local<v8::Context>) override;
+  void runMessageLoopOnPause(int context_group_id) override;
+  void quitMessageLoopOnPause() override;
+  void consoleAPIMessage(int contextGroupId,
+                         v8::Isolate::MessageErrorLevel level,
+                         const v8_inspector::StringView& message,
+                         const v8_inspector::StringView& url,
+                         unsigned lineNumber, unsigned columnNumber,
+                         v8_inspector::V8StackTrace*) override;
+  bool isInspectableHeapObject(v8::Local<v8::Object>) override;
+
+  TaskRunner* task_runner_;
+  SetupGlobalTasks setup_global_tasks_;
+  v8::Isolate* isolate_;
+  std::unique_ptr<v8_inspector::V8Inspector> inspector_;
+  int last_context_group_id_ = 0;
+  std::map<int, v8::Global<v8::Context>> contexts_;
+  std::map<v8::internal::Vector<uint16_t>, v8::Global<v8::Module>,
+           VectorCompare>
+      modules_;
+  int last_session_id_ = 0;
+  std::map<int, std::unique_ptr<v8_inspector::V8InspectorSession>> sessions_;
+  std::map<v8_inspector::V8InspectorSession*, int> context_group_by_session_;
+  v8::Global<v8::Value> memory_info_;
+  bool current_time_set_ = false;
+  double current_time_ = 0.0;
+  bool log_console_api_message_calls_ = false;
+  v8::Global<v8::Private> not_inspectable_private_;
+
+  DISALLOW_COPY_AND_ASSIGN(IsolateData);
+};
+
+#endif  //  V8_TEST_INSPECTOR_PROTOCOL_ISOLATE_DATA_H_
diff --git a/src/v8/test/inspector/json-parse-expected.txt b/src/v8/test/inspector/json-parse-expected.txt
new file mode 100644
index 0000000..80d80ab
--- /dev/null
+++ b/src/v8/test/inspector/json-parse-expected.txt
@@ -0,0 +1,10 @@
+Tests that json parser on backend correctly works with unicode
+{
+    id : 1
+    result : {
+        result : {
+            type : string
+            value : Привет мир
+        }
+    }
+}
diff --git a/src/v8/test/inspector/json-parse.js b/src/v8/test/inspector/json-parse.js
new file mode 100644
index 0000000..92ec84b
--- /dev/null
+++ b/src/v8/test/inspector/json-parse.js
@@ -0,0 +1,16 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that json parser on backend correctly works with unicode');
+
+const id = 100500;
+var command = { "method": "Runtime.evaluate", "params": { expression: "\"!!!\"" }, "id": id };
+session.sendRawCommand(id, JSON.stringify(command).replace("!!!", "\\u041F\\u0440\\u0438\\u0432\\u0435\\u0442 \\u043C\\u0438\\u0440"), step2);
+
+function step2(msg)
+{
+  msg.id = 1;
+  InspectorTest.logObject(msg);
+  InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/protocol-test.js b/src/v8/test/inspector/protocol-test.js
new file mode 100644
index 0000000..be7314b
--- /dev/null
+++ b/src/v8/test/inspector/protocol-test.js
@@ -0,0 +1,408 @@
+// Copyright 2016 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.
+
+InspectorTest = {};
+InspectorTest._dumpInspectorProtocolMessages = false;
+InspectorTest._commandsForLogging = new Set();
+InspectorTest._sessions = new Set();
+
+InspectorTest.log = utils.print.bind(utils);
+InspectorTest.quitImmediately = utils.quit.bind(utils);
+
+InspectorTest.logProtocolCommandCalls = function(command) {
+  InspectorTest._commandsForLogging.add(command);
+}
+
+InspectorTest.completeTest = function() {
+  var promises = [];
+  for (var session of InspectorTest._sessions)
+    promises.push(session.Protocol.Debugger.disable());
+  Promise.all(promises).then(() => utils.quit());
+}
+
+InspectorTest.waitForPendingTasks = function() {
+  var promises = [];
+  for (var session of InspectorTest._sessions)
+    promises.push(session.Protocol.Runtime.evaluate({ expression: "new Promise(r => setTimeout(r, 0))//# sourceURL=wait-for-pending-tasks.js", awaitPromise: true }));
+  return Promise.all(promises);
+}
+
+InspectorTest.startDumpingProtocolMessages = function() {
+  InspectorTest._dumpInspectorProtocolMessages = true;
+}
+
+InspectorTest.logMessage = function(originalMessage) {
+  var message = JSON.parse(JSON.stringify(originalMessage));
+  if (message.id)
+    message.id = "<messageId>";
+
+  const nonStableFields = new Set(["objectId", "scriptId", "exceptionId", "timestamp",
+    "executionContextId", "callFrameId", "breakpointId", "bindRemoteObjectFunctionId", "formatterObjectId" ]);
+  var objects = [ message ];
+  while (objects.length) {
+    var object = objects.shift();
+    for (var key in object) {
+      if (nonStableFields.has(key))
+        object[key] = `<${key}>`;
+      else if (typeof object[key] === "string" && object[key].match(/\d+:\d+:\d+:debug/))
+        object[key] = object[key].replace(/\d+/, '<scriptId>');
+      else if (typeof object[key] === "object")
+        objects.push(object[key]);
+    }
+  }
+
+  InspectorTest.logObject(message);
+  return originalMessage;
+}
+
+InspectorTest.logObject = function(object, title) {
+  var lines = [];
+
+  function dumpValue(value, prefix, prefixWithName) {
+    if (typeof value === "object" && value !== null) {
+      if (value instanceof Array)
+        dumpItems(value, prefix, prefixWithName);
+      else
+        dumpProperties(value, prefix, prefixWithName);
+    } else {
+      lines.push(prefixWithName + String(value).replace(/\n/g, " "));
+    }
+  }
+
+  function dumpProperties(object, prefix, firstLinePrefix) {
+    prefix = prefix || "";
+    firstLinePrefix = firstLinePrefix || prefix;
+    lines.push(firstLinePrefix + "{");
+
+    var propertyNames = Object.keys(object);
+    propertyNames.sort();
+    for (var i = 0; i < propertyNames.length; ++i) {
+      var name = propertyNames[i];
+      if (!object.hasOwnProperty(name))
+        continue;
+      var prefixWithName = "    " + prefix + name + " : ";
+      dumpValue(object[name], "    " + prefix, prefixWithName);
+    }
+    lines.push(prefix + "}");
+  }
+
+  function dumpItems(object, prefix, firstLinePrefix) {
+    prefix = prefix || "";
+    firstLinePrefix = firstLinePrefix || prefix;
+    lines.push(firstLinePrefix + "[");
+    for (var i = 0; i < object.length; ++i)
+      dumpValue(object[i], "    " + prefix, "    " + prefix + "[" + i + "] : ");
+    lines.push(prefix + "]");
+  }
+
+  dumpValue(object, "", title || "");
+  InspectorTest.log(lines.join("\n"));
+}
+
+InspectorTest.ContextGroup = class {
+  constructor() {
+    this.id = utils.createContextGroup();
+  }
+
+  schedulePauseOnNextStatement(reason, details) {
+    utils.schedulePauseOnNextStatement(this.id, reason, details);
+  }
+
+  cancelPauseOnNextStatement() {
+    utils.cancelPauseOnNextStatement(this.id);
+  }
+
+  addScript(string, lineOffset, columnOffset, url) {
+    utils.compileAndRunWithOrigin(this.id, string, url || '', lineOffset || 0, columnOffset || 0, false);
+  }
+
+  addModule(string, url, lineOffset, columnOffset) {
+    utils.compileAndRunWithOrigin(this.id, string, url, lineOffset || 0, columnOffset || 0, true);
+  }
+
+  loadScript(fileName) {
+    this.addScript(utils.read(fileName));
+  }
+
+  connect() {
+    return new InspectorTest.Session(this);
+  }
+
+  setupInjectedScriptEnvironment(session) {
+    let scriptSource = '';
+    // First define all getters on Object.prototype.
+    let injectedScriptSource = utils.read('src/inspector/injected-script-source.js');
+    let getterRegex = /\.[a-zA-Z0-9]+/g;
+    let match;
+    let getters = new Set();
+    while (match = getterRegex.exec(injectedScriptSource)) {
+      getters.add(match[0].substr(1));
+    }
+    scriptSource += `(function installSettersAndGetters() {
+        let defineProperty = Object.defineProperty;
+        let ObjectPrototype = Object.prototype;
+        let ArrayPrototype = Array.prototype;
+        defineProperty(ArrayPrototype, 0, {
+          set() { debugger; throw 42; }, get() { debugger; throw 42; },
+          __proto__: null
+        });`,
+        scriptSource += Array.from(getters).map(getter => `
+        defineProperty(ObjectPrototype, '${getter}', {
+          set() { debugger; throw 42; }, get() { debugger; throw 42; },
+          __proto__: null
+        });
+        `).join('\n') + '})();';
+    this.addScript(scriptSource);
+
+    if (session) {
+      InspectorTest.log('WARNING: setupInjectedScriptEnvironment with debug flag for debugging only and should not be landed.');
+      InspectorTest.log('WARNING: run test with --expose-inspector-scripts flag to get more details.');
+      InspectorTest.log('WARNING: you can additionally comment rjsmin in xxd.py to get unminified injected-script-source.js.');
+      session.setupScriptMap();
+      session.Protocol.Debugger.enable();
+      session.Protocol.Debugger.onPaused(message => {
+        let callFrames = message.params.callFrames;
+        session.logSourceLocations(callFrames.map(frame => frame.location));
+      })
+    }
+  }
+};
+
+InspectorTest.Session = class {
+  constructor(contextGroup) {
+    this.contextGroup = contextGroup;
+    this._dispatchTable = new Map();
+    this._eventHandlers = new Map();
+    this._requestId = 0;
+    this.Protocol = this._setupProtocol();
+    InspectorTest._sessions.add(this);
+    this.id = utils.connectSession(contextGroup.id, '', this._dispatchMessage.bind(this));
+  }
+
+  disconnect() {
+    InspectorTest._sessions.delete(this);
+    utils.disconnectSession(this.id);
+  }
+
+  reconnect() {
+    var state = utils.disconnectSession(this.id);
+    this.id = utils.connectSession(this.contextGroup.id, state, this._dispatchMessage.bind(this));
+  }
+
+  async addInspectedObject(serializable) {
+    return this.Protocol.Runtime.evaluate({expression: `inspector.addInspectedObject(${this.id}, ${JSON.stringify(serializable)})`});
+  }
+
+  sendRawCommand(requestId, command, handler) {
+    if (InspectorTest._dumpInspectorProtocolMessages)
+      utils.print("frontend: " + command);
+    this._dispatchTable.set(requestId, handler);
+    utils.sendMessageToBackend(this.id, command);
+  }
+
+  setupScriptMap() {
+    if (this._scriptMap)
+      return;
+    this._scriptMap = new Map();
+  }
+
+  logCallFrames(callFrames) {
+    for (var frame of callFrames) {
+      var functionName = frame.functionName || '(anonymous)';
+      var url = frame.url ? frame.url : this._scriptMap.get(frame.location.scriptId).url;
+      var lineNumber = frame.location ? frame.location.lineNumber : frame.lineNumber;
+      var columnNumber = frame.location ? frame.location.columnNumber : frame.columnNumber;
+      InspectorTest.log(`${functionName} (${url}:${lineNumber}:${columnNumber})`);
+    }
+  }
+
+  logSourceLocation(location, forceSourceRequest) {
+    var scriptId = location.scriptId;
+    if (!this._scriptMap || !this._scriptMap.has(scriptId)) {
+      InspectorTest.log("setupScriptMap should be called before Protocol.Debugger.enable.");
+      InspectorTest.completeTest();
+    }
+    var script = this._scriptMap.get(scriptId);
+    if (!script.scriptSource || forceSourceRequest) {
+      return this.Protocol.Debugger.getScriptSource({ scriptId })
+          .then(message => script.scriptSource = message.result.scriptSource)
+          .then(dumpSourceWithLocation);
+    }
+    return Promise.resolve().then(dumpSourceWithLocation);
+
+    function dumpSourceWithLocation() {
+      var lines = script.scriptSource.split('\n');
+      var line = lines[location.lineNumber];
+      line = line.slice(0, location.columnNumber) + '#' + (line.slice(location.columnNumber) || '');
+      lines[location.lineNumber] = line;
+      lines = lines.filter(line => line.indexOf('//# sourceURL=') === -1);
+      InspectorTest.log(lines.slice(Math.max(location.lineNumber - 1, 0), location.lineNumber + 2).join('\n'));
+      InspectorTest.log('');
+    }
+  }
+
+  logSourceLocations(locations) {
+    if (locations.length == 0) return Promise.resolve();
+    return this.logSourceLocation(locations[0]).then(() => this.logSourceLocations(locations.splice(1)));
+  }
+
+  async logBreakLocations(inputLocations) {
+    let locations = inputLocations.slice();
+    let scriptId = locations[0].scriptId;
+    let script = this._scriptMap.get(scriptId);
+    if (!script.scriptSource) {
+      let message = await this.Protocol.Debugger.getScriptSource({scriptId});
+      script.scriptSource = message.result.scriptSource;
+    }
+    let lines = script.scriptSource.split('\n');
+    locations = locations.sort((loc1, loc2) => {
+      if (loc2.lineNumber !== loc1.lineNumber) return loc2.lineNumber - loc1.lineNumber;
+      return loc2.columnNumber - loc1.columnNumber;
+    });
+    for (let location of locations) {
+      let line = lines[location.lineNumber];
+      line = line.slice(0, location.columnNumber) + locationMark(location.type) + line.slice(location.columnNumber);
+      lines[location.lineNumber] = line;
+    }
+    lines = lines.filter(line => line.indexOf('//# sourceURL=') === -1);
+    InspectorTest.log(lines.join('\n') + '\n');
+    return inputLocations;
+
+    function locationMark(type) {
+      if (type === 'return') return '|R|';
+      if (type === 'call') return '|C|';
+      if (type === 'debuggerStatement') return '|D|';
+      return '|_|';
+    }
+  }
+
+  async logTypeProfile(typeProfile, source) {
+    let entries = typeProfile.entries;
+
+    // Sort in reverse order so we can replace entries without invalidating
+    // the other offsets.
+    entries = entries.sort((a, b) => b.offset - a.offset);
+
+    for (let entry of entries) {
+      source = source.slice(0, entry.offset) + typeAnnotation(entry.types) +
+        source.slice(entry.offset);
+    }
+    InspectorTest.log(source);
+    return typeProfile;
+
+    function typeAnnotation(types) {
+      return `/*${types.map(t => t.name).join(', ')}*/`;
+    }
+  }
+
+  logAsyncStackTrace(asyncStackTrace) {
+    while (asyncStackTrace) {
+      if (asyncStackTrace.promiseCreationFrame) {
+        var frame = asyncStackTrace.promiseCreationFrame;
+        InspectorTest.log(`-- ${asyncStackTrace.description} (${frame.url}:${frame.lineNumber}:${frame.columnNumber})--`);
+      } else {
+        InspectorTest.log(`-- ${asyncStackTrace.description} --`);
+      }
+      this.logCallFrames(asyncStackTrace.callFrames);
+      asyncStackTrace = asyncStackTrace.parent;
+    }
+  }
+
+  _sendCommandPromise(method, params) {
+    if (InspectorTest._commandsForLogging.has(method))
+      utils.print(method + ' called');
+    var requestId = ++this._requestId;
+    var messageObject = { "id": requestId, "method": method, "params": params };
+    return new Promise(fulfill => this.sendRawCommand(requestId, JSON.stringify(messageObject), fulfill));
+  }
+
+  _setupProtocol() {
+    return new Proxy({}, { get: (target, agentName, receiver) => new Proxy({}, {
+      get: (target, methodName, receiver) => {
+        const eventPattern = /^on(ce)?([A-Z][A-Za-z0-9]+)/;
+        var match = eventPattern.exec(methodName);
+        if (!match)
+          return args => this._sendCommandPromise(`${agentName}.${methodName}`, args || {});
+        var eventName = match[2];
+        eventName = eventName.charAt(0).toLowerCase() + eventName.slice(1);
+        if (match[1])
+          return () => this._waitForEventPromise(`${agentName}.${eventName}`);
+        return listener => this._eventHandlers.set(`${agentName}.${eventName}`, listener);
+      }
+    })});
+  }
+
+  _dispatchMessage(messageString) {
+    var messageObject = JSON.parse(messageString);
+    if (InspectorTest._dumpInspectorProtocolMessages)
+      utils.print("backend: " + JSON.stringify(messageObject));
+    try {
+      var messageId = messageObject["id"];
+      if (typeof messageId === "number") {
+        var handler = this._dispatchTable.get(messageId);
+        if (handler) {
+          handler(messageObject);
+          this._dispatchTable.delete(messageId);
+        }
+      } else {
+        var eventName = messageObject["method"];
+        var eventHandler = this._eventHandlers.get(eventName);
+        if (this._scriptMap && eventName === "Debugger.scriptParsed")
+          this._scriptMap.set(messageObject.params.scriptId, JSON.parse(JSON.stringify(messageObject.params)));
+        if (eventName === "Debugger.scriptParsed" && messageObject.params.url === "wait-for-pending-tasks.js")
+          return;
+        if (eventHandler)
+          eventHandler(messageObject);
+      }
+    } catch (e) {
+      InspectorTest.log("Exception when dispatching message: " + e + "\n" + e.stack + "\n message = " + JSON.stringify(messageObject, null, 2));
+      InspectorTest.completeTest();
+    }
+  };
+
+  _waitForEventPromise(eventName) {
+    return new Promise(fulfill => {
+      this._eventHandlers.set(eventName, result => {
+        delete this._eventHandlers.delete(eventName);
+        fulfill(result);
+      });
+    });
+  }
+};
+
+InspectorTest.runTestSuite = function(testSuite) {
+  function nextTest() {
+    if (!testSuite.length) {
+      InspectorTest.completeTest();
+      return;
+    }
+    var fun = testSuite.shift();
+    InspectorTest.log("\nRunning test: " + fun.name);
+    fun(nextTest);
+  }
+  nextTest();
+}
+
+InspectorTest.runAsyncTestSuite = async function(testSuite) {
+  for (var test of testSuite) {
+    InspectorTest.log("\nRunning test: " + test.name);
+    try {
+      await test();
+    } catch (e) {
+      utils.print(e.stack);
+    }
+  }
+  InspectorTest.completeTest();
+}
+
+InspectorTest.start = function(description) {
+  try {
+    InspectorTest.log(description);
+    var contextGroup = new InspectorTest.ContextGroup();
+    var session = contextGroup.connect();
+    return { session: session, contextGroup: contextGroup, Protocol: session.Protocol };
+  } catch (e) {
+    utils.print(e.stack);
+  }
+}
diff --git a/src/v8/test/inspector/runtime/await-promise-expected.txt b/src/v8/test/inspector/runtime/await-promise-expected.txt
new file mode 100644
index 0000000..3e23a71
--- /dev/null
+++ b/src/v8/test/inspector/runtime/await-promise-expected.txt
@@ -0,0 +1,181 @@
+Tests that Runtime.awaitPromise works.
+
+Running test: testResolvedPromise
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 239
+            type : number
+            value : 239
+        }
+    }
+}
+
+Running test: testRejectedPromise
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 0
+            exception : {
+                type : object
+                value : {
+                    a : 1
+                }
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 0
+            stackTrace : {
+                callFrames : [
+                ]
+                parent : {
+                    callFrames : [
+                        [0] : {
+                            columnNumber : 8
+                            functionName : 
+                            lineNumber : 0
+                            scriptId : <scriptId>
+                            url : 
+                        }
+                    ]
+                    description : Promise.reject
+                }
+            }
+            text : Uncaught (in promise)
+        }
+        result : {
+            type : object
+            value : {
+                a : 1
+            }
+        }
+    }
+}
+
+Running test: testRejectedPromiseWithStack
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 0
+            exception : {
+                description : 239
+                type : number
+                value : 239
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 0
+            stackTrace : {
+                callFrames : [
+                ]
+                parent : {
+                    callFrames : [
+                        [0] : {
+                            columnNumber : 4
+                            functionName : rejectPromise
+                            lineNumber : 17
+                            scriptId : <scriptId>
+                            url : test.js
+                        }
+                        [1] : {
+                            columnNumber : 0
+                            functionName : 
+                            lineNumber : 0
+                            scriptId : <scriptId>
+                            url : 
+                        }
+                    ]
+                    description : Promise.reject
+                }
+            }
+            text : Uncaught (in promise)
+        }
+        result : {
+            description : 239
+            type : number
+            value : 239
+        }
+    }
+}
+
+Running test: testRejectedPromiseWithError
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 0
+            exception : {
+                className : Error
+                description : Error: MyError     at rejectPromiseWithAnError (test.js:25:20)     at <anonymous>:1:1
+                objectId : <objectId>
+                subtype : error
+                type : object
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 0
+            stackTrace : {
+                callFrames : [
+                ]
+                parent : {
+                    callFrames : [
+                        [0] : {
+                            columnNumber : 4
+                            functionName : rejectPromiseWithAnError
+                            lineNumber : 24
+                            scriptId : <scriptId>
+                            url : test.js
+                        }
+                        [1] : {
+                            columnNumber : 0
+                            functionName : 
+                            lineNumber : 0
+                            scriptId : <scriptId>
+                            url : 
+                        }
+                    ]
+                    description : Promise.reject
+                }
+            }
+            text : Uncaught (in promise) Error: MyError
+        }
+        result : {
+            className : Error
+            description : Error: MyError     at rejectPromiseWithAnError (test.js:25:20)     at <anonymous>:1:1
+            objectId : <objectId>
+            subtype : error
+            type : object
+        }
+    }
+}
+
+Running test: testPendingPromise
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 239
+            type : number
+            value : 239
+        }
+    }
+}
+
+Running test: testResolvedWithoutArgsPromise
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
+
+Running test: testGarbageCollectedPromise
+{
+    error : {
+        code : -32000
+        message : Promise was collected
+    }
+    id : <messageId>
+}
diff --git a/src/v8/test/inspector/runtime/await-promise.js b/src/v8/test/inspector/runtime/await-promise.js
new file mode 100644
index 0000000..cf7d53d
--- /dev/null
+++ b/src/v8/test/inspector/runtime/await-promise.js
@@ -0,0 +1,143 @@
+// Copyright 2016 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.
+// Flags: --expose_gc
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Tests that Runtime.awaitPromise works.");
+
+contextGroup.addScript(
+`
+var resolveCallback;
+var rejectCallback;
+function createPromise()
+{
+    return new Promise((resolve, reject) => { resolveCallback = resolve; rejectCallback = reject });
+}
+
+function resolvePromise()
+{
+    resolveCallback(239);
+    resolveCallback = undefined;
+    rejectCallback = undefined;
+}
+
+function rejectPromise()
+{
+    rejectCallback(239);
+    resolveCallback = undefined;
+    rejectCallback = undefined;
+}
+
+function rejectPromiseWithAnError()
+{
+    rejectCallback(new Error('MyError'));
+    resolveCallback = undefined;
+    rejectCallback = undefined;
+}
+
+function throwError()
+{
+   throw new Error('MyError');
+}
+
+//# sourceURL=test.js`);
+
+Protocol.Debugger.enable()
+  .then(() => Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 }))
+  .then(() => testSuite());
+
+function testSuite()
+{
+  InspectorTest.runTestSuite([
+    function testResolvedPromise(next)
+    {
+      Protocol.Runtime.evaluate({ expression: "Promise.resolve(239)"})
+        .then(result => Protocol.Runtime.awaitPromise({ promiseObjectId: result.result.result.objectId, returnByValue: false, generatePreview: true }))
+        .then(result => InspectorTest.logMessage(result))
+        .then(() => next());
+    },
+
+    function testRejectedPromise(next)
+    {
+      Protocol.Runtime.evaluate({ expression: "Promise.reject({ a : 1 })"})
+        .then(result => Protocol.Runtime.awaitPromise({ promiseObjectId: result.result.result.objectId, returnByValue: true, generatePreview: false }))
+        .then(result => InspectorTest.logMessage(result))
+        .then(() => next());
+    },
+
+    function testRejectedPromiseWithStack(next)
+    {
+      Protocol.Runtime.evaluate({ expression: "createPromise()"})
+        .then(result => scheduleRejectAndAwaitPromise(result))
+        .then(result => InspectorTest.logMessage(result))
+        .then(() => next());
+
+      function scheduleRejectAndAwaitPromise(result)
+      {
+        var promise = Protocol.Runtime.awaitPromise({ promiseObjectId: result.result.result.objectId });
+        Protocol.Runtime.evaluate({ expression: "rejectPromise()" });
+        return promise;
+      }
+    },
+
+    function testRejectedPromiseWithError(next)
+    {
+      Protocol.Runtime.evaluate({ expression: "createPromise()"})
+        .then(result => scheduleRejectAndAwaitPromise(result))
+        .then(result => InspectorTest.logMessage(result))
+        .then(() => next());
+
+      function scheduleRejectAndAwaitPromise(result)
+      {
+        var promise = Protocol.Runtime.awaitPromise({ promiseObjectId: result.result.result.objectId });
+        Protocol.Runtime.evaluate({ expression: "rejectPromiseWithAnError()" });
+        return promise;
+      }
+    },
+
+    function testPendingPromise(next)
+    {
+      Protocol.Runtime.evaluate({ expression: "createPromise()"})
+        .then(result => scheduleFulfillAndAwaitPromise(result))
+        .then(result => InspectorTest.logMessage(result))
+        .then(() => next());
+
+      function scheduleFulfillAndAwaitPromise(result)
+      {
+        var promise = Protocol.Runtime.awaitPromise({ promiseObjectId: result.result.result.objectId });
+        Protocol.Runtime.evaluate({ expression: "resolvePromise()" });
+        return promise;
+      }
+    },
+
+    function testResolvedWithoutArgsPromise(next)
+    {
+      Protocol.Runtime.evaluate({ expression: "Promise.resolve()"})
+        .then(result => Protocol.Runtime.awaitPromise({ promiseObjectId: result.result.result.objectId, returnByValue: true, generatePreview: false }))
+        .then(result => InspectorTest.logMessage(result))
+        .then(() => next());
+    },
+
+    function testGarbageCollectedPromise(next)
+    {
+      Protocol.Runtime.evaluate({ expression: "new Promise(() => undefined)" })
+        .then(result => scheduleGCAndawaitPromise(result))
+        .then(result => InspectorTest.logMessage(result))
+        .then(() => next());
+
+      function scheduleGCAndawaitPromise(result)
+      {
+        var objectId = result.result.result.objectId;
+        var promise = Protocol.Runtime.awaitPromise({ promiseObjectId: objectId });
+        gcPromise(objectId);
+        return promise;
+      }
+
+      function gcPromise(objectId)
+      {
+        Protocol.Runtime.releaseObject({ objectId: objectId})
+          .then(() => Protocol.Runtime.evaluate({ expression: "gc()" }));
+      }
+    }
+  ]);
+}
diff --git a/src/v8/test/inspector/runtime/call-function-on-async-expected.txt b/src/v8/test/inspector/runtime/call-function-on-async-expected.txt
new file mode 100644
index 0000000..0cbf6f1
--- /dev/null
+++ b/src/v8/test/inspector/runtime/call-function-on-async-expected.txt
@@ -0,0 +1,195 @@
+Tests that Runtime.callFunctionOn works with awaitPromise flag.
+
+Running test: prepareTestSuite
+
+Running test: testArguments
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : string
+            value : undefined|NaN|[object Object]|[object Object]
+        }
+    }
+}
+
+Running test: testComplexArguments
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : string
+            value : bar
+        }
+    }
+}
+
+Running test: testSyntaxErrorInFunction
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 2
+            exception : {
+                className : SyntaxError
+                description : SyntaxError: Unexpected token }
+                objectId : <objectId>
+                subtype : error
+                type : object
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 1
+            scriptId : <scriptId>
+            text : Uncaught
+        }
+        result : {
+            className : SyntaxError
+            description : SyntaxError: Unexpected token }
+            objectId : <objectId>
+            subtype : error
+            type : object
+        }
+    }
+}
+
+Running test: testExceptionInFunctionExpression
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 15
+            exception : {
+                className : Error
+                description : Error     at <anonymous>:1:22     at <anonymous>:1:36
+                objectId : <objectId>
+                subtype : error
+                type : object
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 0
+            scriptId : <scriptId>
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 21
+                        functionName : 
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                    [1] : {
+                        columnNumber : 35
+                        functionName : 
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught
+        }
+        result : {
+            className : Error
+            description : Error     at <anonymous>:1:22     at <anonymous>:1:36
+            objectId : <objectId>
+            subtype : error
+            type : object
+        }
+    }
+}
+
+Running test: testFunctionReturnNotPromise
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 239
+            type : number
+            value : 239
+        }
+    }
+}
+
+Running test: testFunctionReturnResolvedPromiseReturnByValue
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : object
+            value : {
+                a : 3
+            }
+        }
+    }
+}
+
+Running test: testFunctionReturnResolvedPromiseWithPreview
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Object
+            description : Object
+            objectId : <objectId>
+            preview : {
+                description : Object
+                overflow : false
+                properties : [
+                    [0] : {
+                        name : a
+                        type : number
+                        value : 3
+                    }
+                ]
+                type : object
+            }
+            type : object
+        }
+    }
+}
+
+Running test: testFunctionReturnRejectedPromise
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 0
+            exception : {
+                type : object
+                value : {
+                    a : 3
+                }
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 0
+            text : Uncaught (in promise)
+        }
+        result : {
+            type : object
+            value : {
+                a : 3
+            }
+        }
+    }
+}
+
+Running test: testEvaluateOnExecutionContext
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 70
+            type : number
+            value : 70
+        }
+    }
+}
+
+Running test: testPassingBothObjectIdAndExecutionContextId
+{
+    error : {
+        code : -32000
+        message : ObjectId must not be specified together with executionContextId
+    }
+    id : <messageId>
+}
diff --git a/src/v8/test/inspector/runtime/call-function-on-async.js b/src/v8/test/inspector/runtime/call-function-on-async.js
new file mode 100644
index 0000000..277a01c
--- /dev/null
+++ b/src/v8/test/inspector/runtime/call-function-on-async.js
@@ -0,0 +1,150 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that Runtime.callFunctionOn works with awaitPromise flag.');
+let callFunctionOn = Protocol.Runtime.callFunctionOn.bind(Protocol.Runtime);
+
+let remoteObject1;
+let remoteObject2;
+let executionContextId;
+
+Protocol.Runtime.enable();
+Protocol.Runtime.onExecutionContextCreated(messageObject => {
+  executionContextId = messageObject.params.context.id;
+  InspectorTest.runAsyncTestSuite(testSuite);
+});
+
+let testSuite = [
+  async function prepareTestSuite() {
+    let result = await Protocol.Runtime.evaluate({ expression: '({a : 1})' });
+    remoteObject1 = result.result.result;
+    result = await Protocol.Runtime.evaluate({ expression: '({a : 2})' });
+    remoteObject2 = result.result.result;
+
+    await Protocol.Runtime.evaluate({ expression: 'globalObjectProperty = 42;' });
+  },
+
+  async function testArguments() {
+    InspectorTest.logMessage(await callFunctionOn({
+      objectId: remoteObject1.objectId,
+      functionDeclaration: 'function(arg1, arg2, arg3, arg4) { return \'\' + arg1 + \'|\' + arg2 + \'|\' + arg3 + \'|\' + arg4; }',
+      arguments: prepareArguments([undefined, NaN, remoteObject2, remoteObject1]),
+      returnByValue: true,
+      generatePreview: false,
+      awaitPromise: false
+    }));
+  },
+
+  async function testComplexArguments() {
+    InspectorTest.logMessage(await callFunctionOn({
+      objectId: remoteObject1.objectId,
+      functionDeclaration: 'function(arg) { return arg.foo; }',
+      arguments: prepareArguments([{foo: 'bar'}]),
+      returnByValue: true,
+      generatePreview: false,
+      awaitPromise: false
+    }));
+  },
+
+  async function testSyntaxErrorInFunction() {
+    InspectorTest.logMessage(await callFunctionOn({
+      objectId: remoteObject1.objectId,
+      functionDeclaration: '\n  }',
+      arguments: prepareArguments([]),
+      returnByValue: false,
+      generatePreview: false,
+      awaitPromise: true
+    }));
+  },
+
+  async function testExceptionInFunctionExpression() {
+    InspectorTest.logMessage(await callFunctionOn({
+      objectId: remoteObject1.objectId,
+      functionDeclaration: '(function() { throw new Error() })()',
+      arguments: prepareArguments([]),
+      returnByValue: false,
+      generatePreview: false,
+      awaitPromise: true
+    }));
+  },
+
+  async function testFunctionReturnNotPromise() {
+   InspectorTest.logMessage(await callFunctionOn({
+      objectId: remoteObject1.objectId,
+      functionDeclaration: '(function() { return 239; })',
+      arguments: prepareArguments([]),
+      returnByValue: true,
+      generatePreview: false,
+      awaitPromise: true
+    }));
+  },
+
+  async function testFunctionReturnResolvedPromiseReturnByValue() {
+    InspectorTest.logMessage(await callFunctionOn({
+      objectId: remoteObject1.objectId,
+      functionDeclaration: '(function(arg) { return Promise.resolve({a : this.a + arg.a}); })',
+      arguments: prepareArguments([ remoteObject2 ]),
+      returnByValue: true,
+      generatePreview: false,
+      awaitPromise: true
+    }));
+  },
+
+  async function testFunctionReturnResolvedPromiseWithPreview() {
+    InspectorTest.logMessage(await callFunctionOn({
+      objectId: remoteObject1.objectId,
+      functionDeclaration: '(function(arg) { return Promise.resolve({a : this.a + arg.a}); })',
+      arguments: prepareArguments([ remoteObject2 ]),
+      returnByValue: false,
+      generatePreview: true,
+      awaitPromise: true
+    }));
+  },
+
+  async function testFunctionReturnRejectedPromise() {
+    InspectorTest.logMessage(await callFunctionOn({
+      objectId: remoteObject1.objectId,
+      functionDeclaration: '(function(arg) { return Promise.reject({a : this.a + arg.a}); })',
+      arguments: prepareArguments([ remoteObject2 ]),
+      returnByValue: true,
+      generatePreview: false,
+      awaitPromise: true
+    }));
+  },
+
+  async function testEvaluateOnExecutionContext() {
+    InspectorTest.logMessage(await callFunctionOn({
+      executionContextId,
+      functionDeclaration: '(function(arg) { return this.globalObjectProperty + arg; })',
+      arguments: prepareArguments([ 28 ]),
+      returnByValue: true,
+      generatePreview: false,
+      awaitPromise: false
+    }));
+  },
+
+  async function testPassingBothObjectIdAndExecutionContextId() {
+    InspectorTest.logMessage(await callFunctionOn({
+      executionContextId,
+      objectId: remoteObject1.objectId,
+      functionDeclaration: '(function() { return 42; })',
+      arguments: prepareArguments([]),
+      returnByValue: true,
+      generatePreview: false,
+      awaitPromise: false
+    }));
+  },
+];
+
+function prepareArguments(args) {
+  return args.map(arg => {
+    if (Object.is(arg, -0))
+      return {unserializableValue: '-0'};
+    if (Object.is(arg, NaN) || Object.is(arg, Infinity) || Object.is(arg, -Infinity))
+      return {unserializableValue: arg + ''};
+    if (arg && arg.objectId)
+      return {objectId: arg.objectId};
+    return {value: arg};
+  });
+}
diff --git a/src/v8/test/inspector/runtime/clear-of-command-line-api-expected.txt b/src/v8/test/inspector/runtime/clear-of-command-line-api-expected.txt
new file mode 100644
index 0000000..f63b918
--- /dev/null
+++ b/src/v8/test/inspector/runtime/clear-of-command-line-api-expected.txt
@@ -0,0 +1,177 @@
+Tests that CommandLineAPI is presented only while evaluation.
+
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 15
+            type : number
+            value : 15
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 0
+            type : number
+            value : 0
+        }
+    }
+}
+setPropertyForMethod()
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 14
+            type : number
+            value : 14
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 0
+            type : number
+            value : 0
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+defineValuePropertyForMethod()
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 14
+            type : number
+            value : 14
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 0
+            type : number
+            value : 0
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+definePropertiesForMethod()
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 14
+            type : number
+            value : 14
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 0
+            type : number
+            value : 0
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+defineAccessorPropertyForMethod()
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 14
+            type : number
+            value : 14
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 0
+            type : number
+            value : 0
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+redefineGetOwnPropertyDescriptors()
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 14
+            type : number
+            value : 14
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 0
+            type : number
+            value : 0
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
diff --git a/src/v8/test/inspector/runtime/clear-of-command-line-api.js b/src/v8/test/inspector/runtime/clear-of-command-line-api.js
new file mode 100644
index 0000000..d67a1c5
--- /dev/null
+++ b/src/v8/test/inspector/runtime/clear-of-command-line-api.js
@@ -0,0 +1,117 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Tests that CommandLineAPI is presented only while evaluation.");
+
+contextGroup.addScript(
+`
+var methods = ["dir","dirxml","profile","profileEnd","clear","table","keys","values","debug","undebug","monitor","unmonitor","inspect","copy"];
+var window = this;
+function presentedAPIMethods()
+{
+    var methodCount = 0;
+    for (var method of methods) {
+        try {
+            if (eval("window." + method + "&&" + method + ".toString ? " + method + ".toString().indexOf(\\"[Command Line API]\\") !== -1 : false"))
+                ++methodCount;
+        } catch (e) {
+        }
+    }
+    methodCount += eval("\\"$_\\" in window ? $_ === 239 : false") ? 1 : 0;
+    return methodCount;
+}
+
+function setPropertyForMethod()
+{
+    window.dir = 42;
+}
+
+function defineValuePropertyForMethod()
+{
+    Object.defineProperty(window, "dir", { value: 42 });
+}
+
+function defineAccessorPropertyForMethod()
+{
+    Object.defineProperty(window, "dir", { set: function() {}, get: function(){ return 42 } });
+}
+
+function definePropertiesForMethod()
+{
+    Object.defineProperties(window, { "dir": { set: function() {}, get: function(){ return 42 } }});
+}
+
+var builtinGetOwnPropertyDescriptorOnObject;
+var builtinGetOwnPropertyDescriptorOnObjectPrototype;
+var builtinGetOwnPropertyDescriptorOnWindow;
+
+function redefineGetOwnPropertyDescriptors()
+{
+    builtinGetOwnPropertyDescriptorOnObject = Object.getOwnPropertyDescriptor;
+    Object.getOwnPropertyDescriptor = function() {}
+    builtinGetOwnPropertyDescriptorOnObjectPrototype = Object.prototype.getOwnPropertyDescriptor;
+    Object.prototype.getOwnPropertyDescriptor = function() {}
+    builtinGetOwnPropertyDescriptorOnWindow = window.getOwnPropertyDescriptor;
+    window.getOwnPropertyDescriptor = function() {}
+}
+
+function restoreGetOwnPropertyDescriptors()
+{
+    Object.getOwnPropertyDescriptor = builtinGetOwnPropertyDescriptorOnObject;
+    Object.prototype.getOwnPropertyDescriptor = builtinGetOwnPropertyDescriptorOnObjectPrototype;
+    window.getOwnPropertyDescriptor = builtinGetOwnPropertyDescriptorOnWindow;
+}`);
+
+runExpressionAndDumpPresentedMethods("")
+  .then(dumpLeftMethods)
+  .then(() => runExpressionAndDumpPresentedMethods("setPropertyForMethod()"))
+  .then(dumpLeftMethods)
+  .then(dumpDir)
+  .then(() => runExpressionAndDumpPresentedMethods("defineValuePropertyForMethod()"))
+  .then(dumpLeftMethods)
+  .then(dumpDir)
+  .then(() => runExpressionAndDumpPresentedMethods("definePropertiesForMethod()"))
+  .then(dumpLeftMethods)
+  .then(dumpDir)
+  .then(() => runExpressionAndDumpPresentedMethods("defineAccessorPropertyForMethod()"))
+  .then(dumpLeftMethods)
+  .then(dumpDir)
+  .then(() => runExpressionAndDumpPresentedMethods("redefineGetOwnPropertyDescriptors()"))
+  .then(dumpLeftMethods)
+  .then(dumpDir)
+  .then(() => evaluate("restoreGetOwnPropertyDescriptors()", false))
+  .then(InspectorTest.completeTest);
+
+function evaluate(expression, includeCommandLineAPI)
+{
+  return Protocol.Runtime.evaluate({ expression: expression, objectGroup: "console", includeCommandLineAPI: includeCommandLineAPI });
+}
+
+function setLastEvaluationResultTo239()
+{
+  return evaluate("239", false);
+}
+
+function runExpressionAndDumpPresentedMethods(expression)
+{
+  InspectorTest.log(expression);
+  return setLastEvaluationResultTo239()
+    .then(() => evaluate(expression + "; var a = presentedAPIMethods(); a", true))
+    .then((result) => InspectorTest.logMessage(result));
+}
+
+function dumpLeftMethods()
+{
+  // Should always be zero.
+  return setLastEvaluationResultTo239()
+    .then(() => evaluate("presentedAPIMethods()", false))
+    .then((result) => InspectorTest.logMessage(result));
+}
+
+function dumpDir()
+{
+  // Should always be presented.
+  return evaluate("dir", false)
+    .then((result) => InspectorTest.logMessage(result));
+}
diff --git a/src/v8/test/inspector/runtime/client-console-api-message-expected.txt b/src/v8/test/inspector/runtime/client-console-api-message-expected.txt
new file mode 100644
index 0000000..699b390
--- /dev/null
+++ b/src/v8/test/inspector/runtime/client-console-api-message-expected.txt
@@ -0,0 +1,8 @@
+Checks that we passed correct arguments in V8InspectorClient::consoleAPIMessage. Note: lines and columns are 1-based.
+42 (:1:9)
+    at (anonymous function) (:1:9)
+239 (:13:15)
+    at b (:13:15)
+    at a (:15:5)
+    at consoleTrace (:17:3)
+    at (anonymous function) (:1:1)
diff --git a/src/v8/test/inspector/runtime/client-console-api-message.js b/src/v8/test/inspector/runtime/client-console-api-message.js
new file mode 100644
index 0000000..15838fa
--- /dev/null
+++ b/src/v8/test/inspector/runtime/client-console-api-message.js
@@ -0,0 +1,28 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that we passed correct arguments in ' +
+  'V8InspectorClient::consoleAPIMessage. Note: lines and columns are 1-based.');
+
+contextGroup.addScript(`
+function consoleTrace() {
+  function a() {
+    function b() {
+      console.trace(239);
+    }
+    b();
+  }
+  a();
+}
+`, 8, 26);
+
+Protocol.Runtime.enable();
+utils.setLogConsoleApiMessageCalls(true);
+(async function test() {
+  Protocol.Runtime.evaluate({expression: 'console.log(42)'});
+  await Protocol.Runtime.onceConsoleAPICalled()
+  Protocol.Runtime.evaluate({expression: 'consoleTrace()'});
+  await Protocol.Runtime.onceConsoleAPICalled()
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/runtime/command-line-api-expected.txt b/src/v8/test/inspector/runtime/command-line-api-expected.txt
new file mode 100644
index 0000000..f655e7b
--- /dev/null
+++ b/src/v8/test/inspector/runtime/command-line-api-expected.txt
@@ -0,0 +1,683 @@
+Checks command line API.
+
+Running test: testKeys
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function keys(object) { [Command Line API] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : object
+            value : [
+                [0] : a
+            ]
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : object
+            value : [
+                [0] : a
+            ]
+        }
+    }
+}
+
+Running test: testInspect
+[object Object]
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+        }
+        object : {
+            className : Object
+            description : Object
+            objectId : <objectId>
+            type : object
+        }
+    }
+}
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+        }
+        object : {
+            description : 239
+            type : number
+            value : 239
+        }
+    }
+}
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+        }
+        object : {
+            description : -0
+            type : number
+            unserializableValue : -0
+        }
+    }
+}
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+            copyToClipboard : true
+        }
+        object : {
+            type : string
+            value : hello
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+        }
+        object : {
+            className : Object
+            description : Object
+            objectId : <objectId>
+            type : object
+        }
+    }
+}
+
+Running test: testQueryObjects
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function queryObjects(constructor) { [Command Line API] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+            queryObjects : true
+        }
+        object : {
+            className : Promise
+            description : Promise
+            objectId : <objectId>
+            type : object
+        }
+    }
+}
+Is Promise.prototype: true
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+            queryObjects : true
+        }
+        object : {
+            className : Promise
+            description : Promise
+            objectId : <objectId>
+            type : object
+        }
+    }
+}
+Is Promise.prototype: true
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+            queryObjects : true
+        }
+        object : {
+            className : Object
+            description : Object
+            objectId : <objectId>
+            type : object
+        }
+    }
+}
+Is p: true
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+            queryObjects : true
+        }
+        object : {
+            description : 1
+            type : number
+            value : 1
+        }
+    }
+}
+
+Running test: testEvaluationResult
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : -0
+            type : number
+            unserializableValue : -0
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : object
+            value : {
+            }
+        }
+    }
+}
+
+Running test: testDebug
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function debug(function) { [Command Line API] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function undebug(function) { [Command Line API] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+foo (:0:16)
+(anonymous) (:0:0)
+[
+    [0] : <scriptId>:0:12:debug
+]
+foo (:0:16)
+(anonymous) (:0:0)
+[
+    [0] : <scriptId>:0:12:debug
+]
+
+Running test: testMonitor
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function monitor(function) { [Command Line API] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function unmonitor(function) { [Command Line API] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+function foo called
+after first call
+store functions..
+function foo called
+after first call
+
+Running test: testProfile
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function profile(title) { [Command Line API] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function profileEnd(title) { [Command Line API] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+{
+    method : Profiler.consoleProfileStarted
+    params : {
+        id : 1
+        location : {
+            columnNumber : 1
+            lineNumber : 1
+            scriptId : <scriptId>
+        }
+        title : 42
+    }
+}
+{
+    method : Profiler.consoleProfileFinished
+    params : {
+        id : 1
+        location : {
+            columnNumber : 1
+            lineNumber : 1
+            scriptId : <scriptId>
+        }
+        profile : <profile>
+        title : 42
+    }
+}
+{
+    method : Profiler.consoleProfileStarted
+    params : {
+        id : 2
+        location : {
+            columnNumber : 6
+            lineNumber : 1
+            scriptId : <scriptId>
+        }
+        title : 239
+    }
+}
+{
+    method : Profiler.consoleProfileFinished
+    params : {
+        id : 2
+        location : {
+            columnNumber : 6
+            lineNumber : 1
+            scriptId : <scriptId>
+        }
+        profile : <profile>
+        title : 239
+    }
+}
+
+Running test: testDir
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function dir(value) { [Command Line API] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                className : Object
+                description : Object
+                objectId : <objectId>
+                preview : {
+                    description : Object
+                    overflow : false
+                    properties : [
+                    ]
+                    type : object
+                }
+                type : object
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : dir
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 42
+                type : number
+                value : 42
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : dir
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                className : Object
+                description : Object
+                objectId : <objectId>
+                preview : {
+                    description : Object
+                    overflow : false
+                    properties : [
+                    ]
+                    type : object
+                }
+                type : object
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 5
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : dir
+    }
+}
+
+Running test: testDirXML
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function dirxml(value) { [Command Line API] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                className : Object
+                description : Object
+                objectId : <objectId>
+                preview : {
+                    description : Object
+                    overflow : false
+                    properties : [
+                    ]
+                    type : object
+                }
+                type : object
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : dirxml
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 42
+                type : number
+                value : 42
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : dirxml
+    }
+}
+
+Running test: testTable
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function table(data, [columns]) { [Command Line API] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                className : Object
+                description : Object
+                objectId : <objectId>
+                preview : {
+                    description : Object
+                    overflow : false
+                    properties : [
+                    ]
+                    type : object
+                }
+                type : object
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : table
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 42
+                type : number
+                value : 42
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : table
+    }
+}
+
+Running test: testClear
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function clear() { [Command Line API] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.clear
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : clear
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.clear
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 5
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : clear
+    }
+}
diff --git a/src/v8/test/inspector/runtime/command-line-api.js b/src/v8/test/inspector/runtime/command-line-api.js
new file mode 100644
index 0000000..2826ac2
--- /dev/null
+++ b/src/v8/test/inspector/runtime/command-line-api.js
@@ -0,0 +1,209 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks command line API.');
+
+InspectorTest.runAsyncTestSuite([
+  async function testKeys() {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: 'keys', includeCommandLineAPI: true}));
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: 'keys({a : 1})', includeCommandLineAPI: true, returnByValue: true}));
+
+    Protocol.Runtime.evaluate({expression: 'this.keys = keys', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: 'this.keys({a : 1})', returnByValue: true}));
+  },
+
+  async function testInspect() {
+    InspectorTest.log(await Protocol.Runtime.evaluate({expression: 'inspect', includeCommandLineAPI: true}));
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.onInspectRequested(InspectorTest.logMessage);
+    await Protocol.Runtime.evaluate({expression: 'inspect({})', includeCommandLineAPI: true});
+    await Protocol.Runtime.evaluate({expression: 'inspect(239)', includeCommandLineAPI: true});
+    await Protocol.Runtime.evaluate({expression: 'inspect(-0)', includeCommandLineAPI: true});
+    await Protocol.Runtime.evaluate({expression: 'copy(\'hello\')', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$0', includeCommandLineAPI: true}));
+
+    Protocol.Runtime.evaluate({expression: 'this.inspect = inspect', includeCommandLineAPI: true});
+    await Protocol.Runtime.evaluate({expression: 'this.inspect({})'});
+
+    Protocol.Runtime.onInspectRequested(null);
+    await Protocol.Runtime.disable();
+  },
+
+  async function testQueryObjects() {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'queryObjects', includeCommandLineAPI: true}));
+    await Protocol.Runtime.enable();
+    let {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({expression: 'Promise.prototype'});
+    Protocol.Runtime.evaluate({expression: 'queryObjects(Promise)', includeCommandLineAPI: true});
+    let request = await Protocol.Runtime.onceInspectRequested();
+    InspectorTest.logMessage(request);
+    InspectorTest.logMessage('Is Promise.prototype: ' + await isEqual(objectId, request.params.object.objectId));
+
+    Protocol.Runtime.evaluate({expression: 'queryObjects(Promise.prototype)', includeCommandLineAPI: true});
+    request = await Protocol.Runtime.onceInspectRequested();
+    InspectorTest.logMessage(request);
+    InspectorTest.logMessage('Is Promise.prototype: ' + await isEqual(objectId, request.params.object.objectId));
+
+    ({result:{result:{objectId}}} = await Protocol.Runtime.evaluate({expression:'p = {a:1}'}));
+    Protocol.Runtime.evaluate({expression: 'queryObjects(p)', includeCommandLineAPI: true});
+    request = await Protocol.Runtime.onceInspectRequested();
+    InspectorTest.logMessage(request);
+    InspectorTest.logMessage('Is p: ' + await isEqual(objectId, request.params.object.objectId));
+
+    Protocol.Runtime.evaluate({expression: 'queryObjects(1)', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.onceInspectRequested());
+    await Protocol.Runtime.disable();
+  },
+
+  async function testEvaluationResult() {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
+    await Protocol.Runtime.evaluate({expression: '42', objectGroup: 'console', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
+    await Protocol.Runtime.evaluate({expression: '239', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
+    await Protocol.Runtime.evaluate({expression: '-0', objectGroup: 'console', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
+    await Protocol.Runtime.evaluate({expression: '({})', objectGroup: 'console', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true, returnByValue: true}));
+  },
+
+  async function testDebug() {
+    session.setupScriptMap();
+    await Protocol.Debugger.enable();
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'debug', includeCommandLineAPI: true}));
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'undebug', includeCommandLineAPI: true}));
+    await Protocol.Runtime.evaluate({expression: 'function foo() {}'});
+    await Protocol.Runtime.evaluate({expression: 'debug(foo)', includeCommandLineAPI: true});
+    Protocol.Runtime.evaluate({ expression: 'foo()'});
+    let message = await Protocol.Debugger.oncePaused();
+    session.logCallFrames(message.params.callFrames);
+    InspectorTest.logMessage(message.params.hitBreakpoints);
+    await Protocol.Debugger.resume();
+    await Protocol.Runtime.evaluate({expression: 'undebug(foo)', includeCommandLineAPI: true});
+    await Protocol.Runtime.evaluate({ expression: 'foo()'});
+
+    Protocol.Runtime.evaluate({
+      expression: 'this.debug = debug; this.undebug = undebug;', includeCommandLineAPI: true});
+    await Protocol.Runtime.evaluate({expression: 'this.debug(foo)'});
+    Protocol.Runtime.evaluate({ expression: 'foo()'});
+    message = await Protocol.Debugger.oncePaused();
+    session.logCallFrames(message.params.callFrames);
+    InspectorTest.logMessage(message.params.hitBreakpoints);
+    await Protocol.Debugger.resume();
+    await Protocol.Runtime.evaluate({expression: 'this.undebug(foo)'});
+    await Protocol.Runtime.evaluate({expression: 'foo()'});
+
+    await Protocol.Debugger.disable();
+  },
+
+  async function testMonitor() {
+    await Protocol.Debugger.enable();
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.onConsoleAPICalled(message => InspectorTest.log(message.params.args[0].value));
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'monitor', includeCommandLineAPI: true}));
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'unmonitor', includeCommandLineAPI: true}));
+    await Protocol.Runtime.evaluate({expression: 'function foo() {}'});
+
+    await Protocol.Runtime.evaluate({expression: 'monitor(foo)', includeCommandLineAPI: true});
+    Protocol.Runtime.evaluate({ expression: 'foo(); console.log(\'after first call\')'});
+    await Protocol.Runtime.evaluate({expression: 'unmonitor(foo)', includeCommandLineAPI: true});
+    await Protocol.Runtime.evaluate({ expression: 'foo()'});
+
+    Protocol.Runtime.evaluate({
+      expression: 'console.log(\'store functions..\'); this.monitor = monitor; this.unmonitor = unmonitor;', includeCommandLineAPI: true});
+    await Protocol.Runtime.evaluate({expression: 'this.monitor(foo)'});
+    Protocol.Runtime.evaluate({ expression: 'foo(); console.log(\'after first call\')'});
+    await Protocol.Runtime.evaluate({expression: 'this.unmonitor(foo)'});
+    await Protocol.Runtime.evaluate({ expression: 'foo()'});
+
+    Protocol.Runtime.onConsoleAPICalled(null);
+    await Protocol.Debugger.disable();
+    await Protocol.Runtime.disable();
+  },
+
+  async function testProfile() {
+    await Protocol.Profiler.enable();
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'profile', includeCommandLineAPI: true}));
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'profileEnd', includeCommandLineAPI: true}));
+
+    Protocol.Runtime.evaluate({expression: 'profile(42)', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Profiler.onceConsoleProfileStarted());
+    Protocol.Runtime.evaluate({expression: 'profileEnd(42)', includeCommandLineAPI: true});
+    let message = await Protocol.Profiler.onceConsoleProfileFinished();
+    message.params.profile = '<profile>';
+    InspectorTest.logMessage(message);
+
+    Protocol.Runtime.evaluate({
+      expression: 'this.profile = profile; this.profileEnd = profileEnd;', includeCommandLineAPI: true});
+    Protocol.Runtime.evaluate({expression: 'this.profile(239)'});
+    InspectorTest.logMessage(await Protocol.Profiler.onceConsoleProfileStarted());
+    Protocol.Runtime.evaluate({expression: 'this.profileEnd(239)'});
+    message = await Protocol.Profiler.onceConsoleProfileFinished();
+    message.params.profile = '<profile>';
+    InspectorTest.logMessage(message);
+
+    await Protocol.Profiler.disable();
+  },
+
+  async function testDir() {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'dir', includeCommandLineAPI: true}));
+
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: 'dir({})', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+    Protocol.Runtime.evaluate({expression: 'dir(42)', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+
+    Protocol.Runtime.evaluate({expression: 'this.dir = dir', includeCommandLineAPI: true});
+    Protocol.Runtime.evaluate({expression: 'this.dir({})'});
+    InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+    await Protocol.Runtime.disable();
+  },
+
+  async function testDirXML() {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'dirxml', includeCommandLineAPI: true}));
+
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: 'dirxml({})', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+    Protocol.Runtime.evaluate({expression: 'dirxml(42)', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+    await Protocol.Runtime.disable();
+  },
+
+  async function testTable() {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'table', includeCommandLineAPI: true}));
+
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: 'table({})', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+    Protocol.Runtime.evaluate({expression: 'table(42)', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+    await Protocol.Runtime.disable();
+  },
+
+  async function testClear() {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'clear', includeCommandLineAPI: true}));
+
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: 'clear()', includeCommandLineAPI: true});
+    InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+
+    Protocol.Runtime.evaluate({expression: 'this.clear = clear', includeCommandLineAPI: true});
+    Protocol.Runtime.evaluate({expression: 'this.clear()'});
+    InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+    await Protocol.Runtime.disable();
+  }
+]);
+
+async function isEqual(objectId1, objectId2) {
+  return (await Protocol.Runtime.callFunctionOn({
+    objectId: objectId1,
+    functionDeclaration: 'function(arg){return this === arg;}',
+    returnByValue: true,
+    arguments: [{objectId: objectId2}]
+  })).result.result.value;
+}
diff --git a/src/v8/test/inspector/runtime/compile-script-expected.txt b/src/v8/test/inspector/runtime/compile-script-expected.txt
new file mode 100644
index 0000000..23e6a64
--- /dev/null
+++ b/src/v8/test/inspector/runtime/compile-script-expected.txt
@@ -0,0 +1,67 @@
+Tests Runtime.compileScript
+Compiling script: foo1.js
+         persist: false
+compilation result: 
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 2
+            exception : {
+                className : SyntaxError
+                description : SyntaxError: Unexpected end of input
+                objectId : <objectId>
+                subtype : error
+                type : object
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 1
+            scriptId : <scriptId>
+            text : Uncaught
+        }
+    }
+}
+-----
+Compiling script: foo2.js
+         persist: true
+Debugger.scriptParsed: foo2.js
+compilation result: 
+{
+    id : <messageId>
+    result : {
+        scriptId : <scriptId>
+    }
+}
+-----
+Compiling script: foo3.js
+         persist: false
+compilation result: 
+{
+    id : <messageId>
+    result : {
+    }
+}
+-----
+Compiling script: foo4.js
+         persist: false
+compilation result: 
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 13
+            exception : {
+                className : SyntaxError
+                description : SyntaxError: Unexpected identifier
+                objectId : <objectId>
+                subtype : error
+                type : object
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 0
+            scriptId : <scriptId>
+            text : Uncaught
+        }
+    }
+}
+-----
diff --git a/src/v8/test/inspector/runtime/compile-script.js b/src/v8/test/inspector/runtime/compile-script.js
new file mode 100644
index 0000000..6452e07
--- /dev/null
+++ b/src/v8/test/inspector/runtime/compile-script.js
@@ -0,0 +1,52 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests Runtime.compileScript');
+
+var executionContextId;
+
+Protocol.Debugger.enable().then(onDebuggerEnabled);
+
+function onDebuggerEnabled()
+{
+  Protocol.Runtime.enable();
+  Protocol.Debugger.onScriptParsed(onScriptParsed);
+  Protocol.Runtime.onExecutionContextCreated(onExecutionContextCreated);
+}
+
+function onScriptParsed(messageObject)
+{
+  if (!messageObject.params.url)
+    return;
+  InspectorTest.log("Debugger.scriptParsed: " + messageObject.params.url);
+}
+
+function onExecutionContextCreated(messageObject)
+{
+  executionContextId = messageObject.params.context.id;
+  testCompileScript("\n  (", false, "foo1.js")
+    .then(() => testCompileScript("239", true, "foo2.js"))
+    .then(() => testCompileScript("239", false, "foo3.js"))
+    .then(() => testCompileScript("testfunction f()\n{\n    return 0;\n}\n", false, "foo4.js"))
+    .then(() => InspectorTest.completeTest());
+}
+
+function testCompileScript(expression, persistScript, sourceURL)
+{
+  InspectorTest.log("Compiling script: " + sourceURL);
+  InspectorTest.log("         persist: " + persistScript);
+  return Protocol.Runtime.compileScript({
+    expression: expression,
+    sourceURL: sourceURL,
+    persistScript: persistScript,
+    executionContextId: executionContextId
+  }).then(onCompiled);
+
+  function onCompiled(messageObject)
+  {
+    InspectorTest.log("compilation result: ");
+    InspectorTest.logMessage(messageObject);
+    InspectorTest.log("-----");
+  }
+}
diff --git a/src/v8/test/inspector/runtime/console-api-repeated-in-console-expected.txt b/src/v8/test/inspector/runtime/console-api-repeated-in-console-expected.txt
new file mode 100644
index 0000000..3ec657b
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-api-repeated-in-console-expected.txt
@@ -0,0 +1,5 @@
+Check that console.log is reported through Console domain as well.
+api call: 42
+api call: abc
+console message: 42
+console message: abc
diff --git a/src/v8/test/inspector/runtime/console-api-repeated-in-console.js b/src/v8/test/inspector/runtime/console-api-repeated-in-console.js
new file mode 100644
index 0000000..aafdbde
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-api-repeated-in-console.js
@@ -0,0 +1,37 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Check that console.log is reported through Console domain as well.");
+
+var expectedMessages = 4;
+var messages = [];
+
+Protocol.Runtime.onConsoleAPICalled(consoleAPICalled);
+Protocol.Console.onMessageAdded(messageAdded);
+Protocol.Runtime.enable();
+Protocol.Console.enable();
+Protocol.Runtime.evaluate({ "expression": "console.log(42)" });
+Protocol.Runtime.evaluate({ "expression": "console.error('abc')" });
+
+function consoleAPICalled(result)
+{
+  messages.push("api call: " + result.params.args[0].value);
+  if (!(--expectedMessages))
+    done();
+}
+
+function messageAdded(result)
+{
+  messages.push("console message: " + result.params.message.text);
+  if (!(--expectedMessages))
+    done();
+}
+
+function done()
+{
+  messages.sort();
+  for (var message of messages)
+    InspectorTest.log(message);
+  InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/runtime/console-assert-expected.txt b/src/v8/test/inspector/runtime/console-assert-expected.txt
new file mode 100644
index 0000000..bf53474
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-assert-expected.txt
@@ -0,0 +1,147 @@
+Checks that console.assert works and points to correct call frame.
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.assert
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 4
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : evaluate.js
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : assert
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 1
+                type : number
+                value : 1
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 5
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : evaluate.js
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : assert
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 1
+                type : number
+                value : 1
+            }
+            [1] : {
+                description : 2
+                type : number
+                value : 2
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 6
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : evaluate.js
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : assert
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.assert
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 7
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : evaluate.js
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : assert
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Function
+            description : function assert() { [native code] }
+            objectId : <objectId>
+            type : function
+        }
+    }
+}
diff --git a/src/v8/test/inspector/runtime/console-assert.js b/src/v8/test/inspector/runtime/console-assert.js
new file mode 100644
index 0000000..355149b
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-assert.js
@@ -0,0 +1,24 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Checks that console.assert works and points to correct call frame.");
+
+contextGroup.addScript(`
+function testFunction() {
+  Function.prototype.apply = () => console.error('Should never call this');
+  console.assert(true);
+  console.assert(false);
+  console.assert(false, 1);
+  console.assert(false, 1, 2);
+  console.assert();
+  return console.assert;
+}
+//# sourceURL=test.js`);
+
+Protocol.Runtime.onConsoleAPICalled(InspectorTest.logMessage);
+Protocol.Runtime.enable();
+Protocol.Runtime.evaluate({
+  expression: "testFunction()//# sourceURL=evaluate.js" })
+  .then(InspectorTest.logMessage)
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/runtime/console-context-expected.txt b/src/v8/test/inspector/runtime/console-context-expected.txt
new file mode 100644
index 0000000..941f9c3
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-context-expected.txt
@@ -0,0 +1,83 @@
+Tests console.context
+
+Running test: testConsoleContextMethod
+console.context description:
+{
+    className : Function
+    description : function context() { [native code] }
+    objectId : <objectId>
+    type : function
+}
+console.context() methods:
+[
+    [0] : debug
+    [1] : error
+    [2] : info
+    [3] : log
+    [4] : warn
+    [5] : dir
+    [6] : dirXml
+    [7] : table
+    [8] : trace
+    [9] : group
+    [10] : groupCollapsed
+    [11] : groupEnd
+    [12] : clear
+    [13] : count
+    [14] : assert
+    [15] : markTimeline
+    [16] : profile
+    [17] : profileEnd
+    [18] : timeline
+    [19] : timelineEnd
+    [20] : time
+    [21] : timeEnd
+    [22] : timeStamp
+]
+
+Running test: testDefaultConsoleContext
+undefined
+undefined
+undefined
+
+Running test: testAnonymousConsoleContext
+anonymous#2
+anonymous#3
+anonymous#4
+
+Running test: testNamedConsoleContext
+named-context#6
+named-context#6
+named-context#6
+
+Running test: testTwoConsoleContextsWithTheSameName
+named-context#7
+named-context#8
+
+Running test: testConsoleCountInDifferentConsoleContexts
+[
+    [0] : {
+        type : string
+        value : 239: 1
+    }
+]
+[
+    [0] : {
+        type : string
+        value : 239: 1
+    }
+]
+
+Running test: testConsoleCountForNamedConsoleContext
+[
+    [0] : {
+        type : string
+        value : 239: 1
+    }
+]
+[
+    [0] : {
+        type : string
+        value : 239: 2
+    }
+]
diff --git a/src/v8/test/inspector/runtime/console-context.js b/src/v8/test/inspector/runtime/console-context.js
new file mode 100644
index 0000000..74996ae
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-context.js
@@ -0,0 +1,106 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests console.context');
+
+InspectorTest.runAsyncTestSuite([
+  async function testConsoleContextMethod() {
+    InspectorTest.log('console.context description:');
+    var {result:{result}} = await Protocol.Runtime.evaluate({
+      expression: 'console.context'});
+    InspectorTest.logMessage(result);
+
+    InspectorTest.log('console.context() methods:');
+    var {result:{result:{value}}} = await Protocol.Runtime.evaluate({
+      expression: 'Object.keys(console.context())', returnByValue: true});
+    InspectorTest.logMessage(value);
+  },
+
+  async function testDefaultConsoleContext() {
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: 'console.log(239)'});
+    var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.log(context);
+    Protocol.Runtime.evaluate({expression: 'console.info(239)'});
+    var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.log(context);
+    Protocol.Runtime.evaluate({expression: 'console.debug(239)'});
+    var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.log(context);
+    await Protocol.Runtime.evaluate({expression: 'console.clear()'});
+    await Protocol.Runtime.disable();
+  },
+
+  async function testAnonymousConsoleContext() {
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: 'console.context().log(239)'});
+    var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.log(context);
+    Protocol.Runtime.evaluate({expression: 'console.context().info(239)'});
+    var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.log(context);
+    Protocol.Runtime.evaluate({expression: 'console.context().debug(239)'});
+    var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.log(context);
+    await Protocol.Runtime.evaluate({expression: 'console.context().clear()'});
+    await Protocol.Runtime.disable();
+  },
+
+  async function testNamedConsoleContext() {
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: `
+      var context = console.context('named-context');
+      context.log(239);
+      context.info(239);
+      context.debug(239);
+    `});
+    var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.log(context);
+    var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.log(context);
+    var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.log(context);
+    await Protocol.Runtime.evaluate({expression: 'console.clear()'});
+    await Protocol.Runtime.disable();
+  },
+
+  async function testTwoConsoleContextsWithTheSameName() {
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: 'console.context(\'named-context\').log(239)'});
+    var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.log(context);
+    Protocol.Runtime.evaluate({expression: 'console.context(\'named-context\').log(239)'});
+    var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.log(context);
+    await Protocol.Runtime.evaluate({expression: 'console.clear()'});
+    await Protocol.Runtime.disable();
+  },
+
+  async function testConsoleCountInDifferentConsoleContexts() {
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: 'console.context(\'named-context\').count(239)'});
+    var {params:{args}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.logMessage(args);
+    Protocol.Runtime.evaluate({expression: 'console.context(\'named-context\').count(239)'});
+    var {params:{args}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.logMessage(args);
+    await Protocol.Runtime.evaluate({expression: 'console.clear()'});
+    await Protocol.Runtime.disable();
+  },
+
+  async function testConsoleCountForNamedConsoleContext() {
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: `
+      var context = console.context('named-context');
+      context.count(239);
+      context.count(239);
+    `});
+    var {params:{args}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.logMessage(args);
+    var {params:{args}} = await Protocol.Runtime.onceConsoleAPICalled();
+    InspectorTest.logMessage(args);
+    await Protocol.Runtime.evaluate({expression: 'console.clear()'});
+    await Protocol.Runtime.disable();
+  }
+]);
diff --git a/src/v8/test/inspector/runtime/console-deprecated-methods-expected.txt b/src/v8/test/inspector/runtime/console-deprecated-methods-expected.txt
new file mode 100644
index 0000000..4c1e265
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-deprecated-methods-expected.txt
@@ -0,0 +1,4 @@
+Tests checks that deprecation messages for console.
+'console.timeline' is deprecated. Please use 'console.time' instead.
+'console.timelineEnd' is deprecated. Please use 'console.timeEnd' instead.
+'console.markTimeline' is deprecated. Please use 'console.timeStamp' instead.
diff --git a/src/v8/test/inspector/runtime/console-deprecated-methods.js b/src/v8/test/inspector/runtime/console-deprecated-methods.js
new file mode 100644
index 0000000..e8ccd2a
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-deprecated-methods.js
@@ -0,0 +1,28 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Tests checks that deprecation messages for console.")
+
+Protocol.Runtime.onConsoleAPICalled(messageAdded);
+Protocol.Runtime.enable();
+
+var deprecatedMethods = [
+  "console.timeline(\"42\")",
+  "console.timeline(\"42\")",
+  "console.timeline(\"42\")", // three calls should produce one warning message
+  "console.timelineEnd(\"42\")",
+  "console.markTimeline(\"42\")",
+];
+Protocol.Runtime.evaluate({ expression: deprecatedMethods.join(";") });
+
+var messagesLeft = 3;
+function messageAdded(data)
+{
+  var text = data.params.args[0].value;
+  if (text.indexOf("deprecated") === -1)
+    return;
+  InspectorTest.log(text);
+  if (!--messagesLeft)
+    InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/runtime/console-line-and-column-expected.txt b/src/v8/test/inspector/runtime/console-line-and-column-expected.txt
new file mode 100644
index 0000000..4e3ce1e4
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-line-and-column-expected.txt
@@ -0,0 +1,53 @@
+Tests line and column numbers in console messages
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 239
+                type : number
+                value : 239
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 239
+                type : number
+                value : 239
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 2
+                    functionName : 
+                    lineNumber : 1
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
diff --git a/src/v8/test/inspector/runtime/console-line-and-column.js b/src/v8/test/inspector/runtime/console-line-and-column.js
new file mode 100644
index 0000000..e7011eb
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-line-and-column.js
@@ -0,0 +1,20 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests line and column numbers in console messages');
+
+Protocol.Runtime.enable();
+
+addConsoleMessagePromise("console.log(239)")
+  .then(message => InspectorTest.logMessage(message))
+  .then(() => addConsoleMessagePromise("var l = console.log;\n  l(239)"))
+  .then(message => InspectorTest.logMessage(message))
+  .then(() => InspectorTest.completeTest());
+
+function addConsoleMessagePromise(expression)
+{
+  var wait = Protocol.Runtime.onceConsoleAPICalled();
+  Protocol.Runtime.evaluate({ expression: expression });
+  return wait;
+}
diff --git a/src/v8/test/inspector/runtime/console-log-doesnt-run-microtasks-expected.txt b/src/v8/test/inspector/runtime/console-log-doesnt-run-microtasks-expected.txt
new file mode 100644
index 0000000..d1268b9
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-log-doesnt-run-microtasks-expected.txt
@@ -0,0 +1,20 @@
+Check that console.log doesn't run microtasks.
+{
+    description : 42
+    type : number
+    value : 42
+}
+{
+    description : 43
+    type : number
+    value : 43
+}
+{
+    description : 239
+    type : number
+    value : 239
+}
+{
+    type : string
+    value : finished
+}
diff --git a/src/v8/test/inspector/runtime/console-log-doesnt-run-microtasks.js b/src/v8/test/inspector/runtime/console-log-doesnt-run-microtasks.js
new file mode 100644
index 0000000..c24e928
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-log-doesnt-run-microtasks.js
@@ -0,0 +1,26 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Check that console.log doesn't run microtasks.");
+
+contextGroup.addScript(
+`
+function testFunction()
+{
+  Promise.resolve().then(function(){ console.log(239); });
+  console.log(42);
+  console.log(43);
+}`);
+
+Protocol.Runtime.enable();
+Protocol.Runtime.onConsoleAPICalled(messageAdded);
+Protocol.Runtime.evaluate({ "expression": "testFunction()" });
+Protocol.Runtime.evaluate({ "expression": "setTimeout(() => console.log(\"finished\"), 0)" });
+
+function messageAdded(result)
+{
+  InspectorTest.logObject(result.params.args[0]);
+  if (result.params.args[0].value === "finished")
+    InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/runtime/console-memory-expected.txt b/src/v8/test/inspector/runtime/console-memory-expected.txt
new file mode 100644
index 0000000..e0f6fca
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-memory-expected.txt
@@ -0,0 +1,45 @@
+Checks console.memory
+
+Running test: testWithoutMemory
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
+
+Running test: testSetterInStrictMode
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
+
+Running test: testWithMemory
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 239
+            type : number
+            value : 239
+        }
+    }
+}
+
+Running test: testSetterDoesntOverride
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
diff --git a/src/v8/test/inspector/runtime/console-memory.js b/src/v8/test/inspector/runtime/console-memory.js
new file mode 100644
index 0000000..45f86c0
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-memory.js
@@ -0,0 +1,32 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks console.memory');
+
+InspectorTest.runAsyncTestSuite([
+  async function testWithoutMemory() {
+    InspectorTest.logMessage(
+      await Protocol.Runtime.evaluate({expression: 'console.memory'}));
+  },
+
+  async function testSetterInStrictMode() {
+    // crbug.com/468611
+    InspectorTest.logMessage(
+      await Protocol.Runtime.evaluate({
+        expression: '"use strict"\nconsole.memory = {};undefined' }));
+  },
+
+  async function testWithMemory() {
+    utils.setMemoryInfoForTest(239);
+    InspectorTest.logMessage(
+      await Protocol.Runtime.evaluate({expression: 'console.memory'}));
+  },
+
+  async function testSetterDoesntOverride() {
+    utils.setMemoryInfoForTest(42);
+    await Protocol.Runtime.evaluate({expression: 'console.memory = 0'});
+    InspectorTest.logMessage(
+      await Protocol.Runtime.evaluate({expression: 'console.memory'}));
+  }
+]);
diff --git a/src/v8/test/inspector/runtime/console-messages-limits-expected.txt b/src/v8/test/inspector/runtime/console-messages-limits-expected.txt
new file mode 100644
index 0000000..3d1cd9f
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-messages-limits-expected.txt
@@ -0,0 +1,7 @@
+Checks that console message storage doesn't exceed limits
+
+Running test: testMaxConsoleMessagesCount
+Messages reported: 1000
+
+Running test: testMaxConsoleMessagesV8Size
+Messages reported: 3
diff --git a/src/v8/test/inspector/runtime/console-messages-limits.js b/src/v8/test/inspector/runtime/console-messages-limits.js
new file mode 100644
index 0000000..4a81590
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-messages-limits.js
@@ -0,0 +1,44 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that console message storage doesn\'t exceed limits');
+
+contextGroup.addScript(`
+function generateEmptyMessages(n) {
+  for (var i = 0; i < n; ++i) {
+    console.log('');
+  }
+}
+
+function generate1MbMessages(n) {
+  for (var i = 0; i < n; ++i) {
+    console.log(new Array(1024 * 1024 - 32).join('!'));
+  }
+}
+//# sourceURL=test.js`, 7, 26);
+
+var messagesReported = 0;
+Protocol.Runtime.onConsoleAPICalled(message => {
+  ++messagesReported;
+});
+
+InspectorTest.runTestSuite([
+  function testMaxConsoleMessagesCount(next) {
+    messagesReported = 0;
+    Protocol.Runtime.evaluate({ expression: 'generateEmptyMessages(1005)'})
+      .then(() => Protocol.Runtime.enable())
+      .then(() => Protocol.Runtime.disable())
+      .then(() => InspectorTest.log(`Messages reported: ${messagesReported}`))
+      .then(next);
+  },
+
+  function testMaxConsoleMessagesV8Size(next) {
+    messagesReported = 0;
+    Protocol.Runtime.evaluate({ expression: 'generate1MbMessages(11)'})
+      .then(() => Protocol.Runtime.enable())
+      .then(() => Protocol.Runtime.disable())
+      .then(() => InspectorTest.log(`Messages reported: ${messagesReported}`))
+      .then(next);
+  }
+]);
diff --git a/src/v8/test/inspector/runtime/console-methods-expected.txt b/src/v8/test/inspector/runtime/console-methods-expected.txt
new file mode 100644
index 0000000..81c3c76
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-methods-expected.txt
@@ -0,0 +1,727 @@
+Checks console methods
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : debug
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 9
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : debug
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : error
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 10
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : error
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : info
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 11
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : info
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : log
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 12
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : warn
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 13
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : warning
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : dir
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 14
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : dir
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : dirxml
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 15
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : dirxml
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                className : Array
+                description : Array(2)
+                objectId : <objectId>
+                preview : {
+                    description : Array(2)
+                    overflow : false
+                    properties : [
+                        [0] : {
+                            name : 0
+                            subtype : array
+                            type : object
+                            valuePreview : {
+                                description : Array(2)
+                                overflow : false
+                                properties : [
+                                    [0] : {
+                                        name : 0
+                                        type : number
+                                        value : 1
+                                    }
+                                    [1] : {
+                                        name : 1
+                                        type : number
+                                        value : 2
+                                    }
+                                ]
+                                subtype : array
+                                type : object
+                            }
+                        }
+                        [1] : {
+                            name : 1
+                            subtype : array
+                            type : object
+                            valuePreview : {
+                                description : Array(2)
+                                overflow : false
+                                properties : [
+                                    [0] : {
+                                        name : 0
+                                        type : number
+                                        value : 3
+                                    }
+                                    [1] : {
+                                        name : 1
+                                        type : number
+                                        value : 4
+                                    }
+                                ]
+                                subtype : array
+                                type : object
+                            }
+                        }
+                    ]
+                    subtype : array
+                    type : object
+                }
+                subtype : array
+                type : object
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 16
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : table
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                className : Array
+                description : Array(2)
+                objectId : <objectId>
+                preview : {
+                    description : Array(2)
+                    overflow : false
+                    properties : [
+                        [0] : {
+                            name : 0
+                            subtype : array
+                            type : object
+                            valuePreview : {
+                                description : Array(2)
+                                overflow : false
+                                properties : [
+                                    [0] : {
+                                        name : 1
+                                        type : number
+                                        value : 2
+                                    }
+                                ]
+                                subtype : array
+                                type : object
+                            }
+                        }
+                        [1] : {
+                            name : 1
+                            subtype : array
+                            type : object
+                            valuePreview : {
+                                description : Array(2)
+                                overflow : false
+                                properties : [
+                                    [0] : {
+                                        name : 1
+                                        type : number
+                                        value : 4
+                                    }
+                                ]
+                                subtype : array
+                                type : object
+                            }
+                        }
+                    ]
+                    subtype : array
+                    type : object
+                }
+                subtype : array
+                type : object
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 17
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : table
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : trace
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 18
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : trace
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.trace
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 19
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : trace
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.group
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 20
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : startGroup
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.groupEnd
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 21
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : endGroup
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.groupCollapsed
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 22
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : startGroupCollapsed
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : clear
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 23
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : clear
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : console.clear
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 24
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : clear
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : count: 1
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 10
+                    functionName : testFunction
+                    lineNumber : 25
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : count
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : 1
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 12
+                    functionName : foo
+                    lineNumber : 27
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 2
+                    functionName : testFunction
+                    lineNumber : 29
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [2] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : count
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : 2
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 12
+                    functionName : foo
+                    lineNumber : 27
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [1] : {
+                    columnNumber : 2
+                    functionName : testFunction
+                    lineNumber : 30
+                    scriptId : <scriptId>
+                    url : test.js
+                }
+                [2] : {
+                    columnNumber : 0
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : count
+    }
+}
diff --git a/src/v8/test/inspector/runtime/console-methods.js b/src/v8/test/inspector/runtime/console-methods.js
new file mode 100644
index 0000000..c9e0e1d
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-methods.js
@@ -0,0 +1,38 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks console methods');
+
+contextGroup.setupInjectedScriptEnvironment();
+contextGroup.addScript(`
+function testFunction() {
+  console.debug('debug');
+  console.error('error');
+  console.info('info');
+  console.log('log');
+  console.warn('warn');
+  console.dir('dir');
+  console.dirxml('dirxml');
+  console.table([[1,2],[3,4]]);
+  console.table([[1,2],[3,4]], [1,2]);
+  console.trace('trace');
+  console.trace();
+  console.group();
+  console.groupEnd();
+  console.groupCollapsed();
+  console.clear('clear');
+  console.clear();
+  console.count('count');
+  function foo() {
+    console.count();
+  }
+  foo();
+  foo();
+}
+//# sourceURL=test.js`, 7, 26);
+
+Protocol.Runtime.onConsoleAPICalled(InspectorTest.logMessage);
+Protocol.Runtime.enable();
+Protocol.Runtime.evaluate({ expression: 'testFunction()' })
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/runtime/console-spec-expected.txt b/src/v8/test/inspector/runtime/console-spec-expected.txt
new file mode 100644
index 0000000..48cbc70
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-spec-expected.txt
@@ -0,0 +1,30 @@
+Tests console object and it's prototype
+
+Running test: consoleExistsOnGlobal
+true
+
+Running test: consoleHasRightPropertyDescriptor
+{
+    configurable : true
+    enumerable : false
+    value : <value>
+    writable : true
+}
+
+Running test: ConsoleNotExistsOnGlobal
+false
+
+Running test: prototypeChainMustBeCorrect
+true
+
+Running test: consoleToString
+[object Object]
+
+Running test: consoleMethodPropertyDescriptor
+{
+    configurable : true
+    enumerable : true
+    value : {
+    }
+    writable : true
+}
diff --git a/src/v8/test/inspector/runtime/console-spec.js b/src/v8/test/inspector/runtime/console-spec.js
new file mode 100644
index 0000000..f37898f
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-spec.js
@@ -0,0 +1,60 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests console object and it\'s prototype');
+
+contextGroup.addScript(`
+var self = this;
+function checkPrototype() {
+  const prototype1 = Object.getPrototypeOf(console);
+  const prototype2 = Object.getPrototypeOf(prototype1);
+  if (Object.getOwnPropertyNames(prototype1).length !== 0)
+    return "false: The [[Prototype]] must have no properties";
+  if (prototype2 !== Object.prototype)
+    return "false: The [[Prototype]]'s [[Prototype]] must be %ObjectPrototype%";
+  return "true";
+}
+`);
+
+InspectorTest.runAsyncTestSuite([
+  async function consoleExistsOnGlobal() {
+    let message = await Protocol.Runtime.evaluate({
+      expression: 'self.hasOwnProperty(\'console\')', returnByValue: true});
+    InspectorTest.log(message.result.result.value);
+  },
+
+  async function consoleHasRightPropertyDescriptor() {
+    let message = await Protocol.Runtime.evaluate({
+      expression: 'Object.getOwnPropertyDescriptor(self, \'console\')',
+      returnByValue: true});
+    let result = message.result.result.value;
+    result.value = '<value>';
+    InspectorTest.logObject(result);
+  },
+
+  async function ConsoleNotExistsOnGlobal() {
+    let message = await Protocol.Runtime.evaluate({
+      expression: '\'Console\' in self', returnByValue: true})
+    InspectorTest.log(message.result.result.value);
+  },
+
+  async function prototypeChainMustBeCorrect() {
+    let message = await Protocol.Runtime.evaluate({
+      expression: "checkPrototype()", returnByValue: true });
+    InspectorTest.log(message.result.result.value);
+  },
+
+  async function consoleToString() {
+    let message = await Protocol.Runtime.evaluate({
+      expression: 'console.toString()', returnByValue: true})
+    InspectorTest.log(message.result.result.value);
+  },
+
+  async function consoleMethodPropertyDescriptor() {
+    let message = await Protocol.Runtime.evaluate({
+      expression: 'Object.getOwnPropertyDescriptor(console, \'log\')',
+      returnByValue: true});
+    InspectorTest.logObject(message.result.result.value);
+  }
+]);
diff --git a/src/v8/test/inspector/runtime/console-time-end-format-expected.txt b/src/v8/test/inspector/runtime/console-time-end-format-expected.txt
new file mode 100644
index 0000000..92fa158
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-time-end-format-expected.txt
@@ -0,0 +1,29 @@
+Checks format of console.timeEnd output
+
+Running test: zero
+js: 0ms
+timeEnd: 0ms
+
+Running test: verySmall
+js: 1e-15ms
+timeEnd: 1e-15ms
+
+Running test: small
+js: 0.001ms
+timeEnd: 0.001ms
+
+Running test: regular
+js: 1.2345ms
+timeEnd: 1.2345ms
+
+Running test: big
+js: 10000.2345ms
+timeEnd: 10000.2345ms
+
+Running test: veryBig
+js: 1000000000000000.2ms
+timeEnd: 1000000000000000.2ms
+
+Running test: huge
+js: 1e+42ms
+timeEnd: 1e+42ms
diff --git a/src/v8/test/inspector/runtime/console-time-end-format.js b/src/v8/test/inspector/runtime/console-time-end-format.js
new file mode 100644
index 0000000..7e4ff78
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-time-end-format.js
@@ -0,0 +1,45 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks format of console.timeEnd output');
+
+Protocol.Runtime.enable();
+Protocol.Runtime.onConsoleAPICalled(message => {
+  InspectorTest.log(message.params.args[0].value);
+});
+
+InspectorTest.runTestSuite([
+  function zero(next) {
+    checkInterval(0.0).then(next);
+  },
+  function verySmall(next) {
+    checkInterval(1e-15).then(next);
+  },
+  function small(next) {
+    checkInterval(0.001).then(next);
+  },
+  function regular(next) {
+    checkInterval(1.2345).then(next);
+  },
+  function big(next) {
+    checkInterval(10000.2345).then(next);
+  },
+  function veryBig(next) {
+    checkInterval(1e+15 + 0.2345).then(next);
+  },
+  function huge(next) {
+    checkInterval(1e+42).then(next);
+  }
+]);
+
+function checkInterval(time) {
+  utils.setCurrentTimeMSForTest(0.0);
+  return Protocol.Runtime.evaluate({
+    expression: `console.log('js: ' + ${time} + 'ms')`})
+    .then(() => Protocol.Runtime.evaluate({
+      expression: 'console.time(\'timeEnd\')'}))
+    .then(() => utils.setCurrentTimeMSForTest(time))
+    .then(() => Protocol.Runtime.evaluate({
+      expression: 'console.timeEnd(\'timeEnd\')'}));
+}
diff --git a/src/v8/test/inspector/runtime/console-timestamp-expected.txt b/src/v8/test/inspector/runtime/console-timestamp-expected.txt
new file mode 100644
index 0000000..5710530
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-timestamp-expected.txt
@@ -0,0 +1,9 @@
+Tests timestamps in console
+Message has timestamp: true
+Message timestamp doesn't differ too much from current time (one minute interval): true
+Message 1 has non-decreasing timestamp: true
+Message has timestamp: true
+Message timestamp doesn't differ too much from current time (one minute interval): true
+Message 2 has non-decreasing timestamp: true
+Message has timestamp: true
+Message timestamp doesn't differ too much from current time (one minute interval): true
diff --git a/src/v8/test/inspector/runtime/console-timestamp.js b/src/v8/test/inspector/runtime/console-timestamp.js
new file mode 100644
index 0000000..46ee76f
--- /dev/null
+++ b/src/v8/test/inspector/runtime/console-timestamp.js
@@ -0,0 +1,25 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests timestamps in console');
+
+var messages = [];
+
+function messageAdded(data)
+{
+  var payload = data.params;
+  if (messages.length > 0)
+    InspectorTest.log("Message " + messages.length + " has non-decreasing timestamp: " + (payload.timestamp >= messages[messages.length - 1].timestamp));
+
+  messages.push(payload);
+  InspectorTest.log("Message has timestamp: " + !!payload.timestamp);
+
+  InspectorTest.log("Message timestamp doesn't differ too much from current time (one minute interval): " + (Math.abs(new Date().getTime() - payload.timestamp) < 60000));
+  if (messages.length === 3)
+    InspectorTest.completeTest();
+}
+
+Protocol.Runtime.onConsoleAPICalled(messageAdded);
+Protocol.Runtime.enable();
+Protocol.Runtime.evaluate({ expression: "console.log('testUnique'); for (var i = 0; i < 2; ++i) console.log('testDouble');" });
diff --git a/src/v8/test/inspector/runtime/context-destroyed-on-context-collected-expected.txt b/src/v8/test/inspector/runtime/context-destroyed-on-context-collected-expected.txt
new file mode 100644
index 0000000..9a5e170
--- /dev/null
+++ b/src/v8/test/inspector/runtime/context-destroyed-on-context-collected-expected.txt
@@ -0,0 +1,7 @@
+Tests that contextDesrtoyed nofitication is fired when context is collected.
+{
+    method : Runtime.executionContextDestroyed
+    params : {
+        executionContextId : <executionContextId>
+    }
+}
diff --git a/src/v8/test/inspector/runtime/context-destroyed-on-context-collected.js b/src/v8/test/inspector/runtime/context-destroyed-on-context-collected.js
new file mode 100644
index 0000000..9f71593
--- /dev/null
+++ b/src/v8/test/inspector/runtime/context-destroyed-on-context-collected.js
@@ -0,0 +1,14 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+  InspectorTest.start('Tests that contextDesrtoyed nofitication is fired when context is collected.');
+
+(async function test() {
+  await Protocol.Runtime.enable();
+  Protocol.Runtime.onExecutionContextDestroyed(InspectorTest.logMessage);
+  contextGroup.addScript('inspector.freeContext()');
+  await Protocol.HeapProfiler.collectGarbage();
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/runtime/create-context-expected.txt b/src/v8/test/inspector/runtime/create-context-expected.txt
new file mode 100644
index 0000000..e64f75b
--- /dev/null
+++ b/src/v8/test/inspector/runtime/create-context-expected.txt
@@ -0,0 +1,56 @@
+Checks createContext().
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 1
+            name : 
+            origin : 
+        }
+    }
+}
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 2
+            name : 
+            origin : 
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+    }
+}
+#debugger;
+
+setTimeout(x => x #* 3, 0)
+
+Reported script's execution id: 2
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 1
+            name : 
+            origin : 
+        }
+    }
+}
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 2
+            name : 
+            origin : 
+        }
+    }
+}
+#debugger;
+
+setTimeout(x => x #* 3, 0)
+
+Reported script's execution id: 2
diff --git a/src/v8/test/inspector/runtime/create-context.js b/src/v8/test/inspector/runtime/create-context.js
new file mode 100644
index 0000000..105bb59
--- /dev/null
+++ b/src/v8/test/inspector/runtime/create-context.js
@@ -0,0 +1,51 @@
+// Copyright 2017 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.
+
+InspectorTest.log('Checks createContext().');
+
+var executionContextIds = new Set();
+var contextGroup1 = new InspectorTest.ContextGroup();
+var session1 = contextGroup1.connect();
+setup(session1);
+var contextGroup2 = new InspectorTest.ContextGroup();
+var session2 = contextGroup2.connect();
+setup(session2);
+
+session1.Protocol.Runtime.enable()
+  .then(() => session2.Protocol.Runtime.enable({}))
+  .then(() => session1.Protocol.Debugger.enable())
+  .then(() => session2.Protocol.Debugger.enable({}))
+  .then(InspectorTest.logMessage)
+  .then(() => {
+    session1.Protocol.Runtime.evaluate({ expression: 'debugger;' });
+    session2.Protocol.Runtime.evaluate({expression: 'setTimeout(x => x * 2, 0)'});
+    session1.Protocol.Runtime.evaluate({ expression: 'setTimeout(x => x * 3, 0)' });
+  })
+  .then(() => InspectorTest.waitForPendingTasks())
+  .then(() => {
+    InspectorTest.log(`Reported script's execution id: ${executionContextIds.size}`);
+    executionContextIds.clear();
+  })
+  .then(() => session1.reconnect())
+  .then(() => session2.reconnect())
+  .then(() => {
+    session1.Protocol.Runtime.evaluate({ expression: 'debugger;' })
+    session2.Protocol.Runtime.evaluate({ expression: 'setTimeout(x => x * 2, 0)' });
+    session1.Protocol.Runtime.evaluate({ expression: 'setTimeout(x => x * 3, 0)' });
+  })
+  .then(() => InspectorTest.waitForPendingTasks())
+  .then(() => session2.Protocol.Debugger.disable({}))
+  .then(() => session1.Protocol.Debugger.disable({}))
+  .then(() => InspectorTest.log(`Reported script's execution id: ${executionContextIds.size}`))
+  .then(InspectorTest.completeTest);
+
+function setup(session) {
+  session.Protocol.Runtime.onExecutionContextCreated(InspectorTest.logMessage);
+  session.setupScriptMap();
+  session.Protocol.Debugger.onPaused((message) => {
+    session.logSourceLocation(message.params.callFrames[0].location);
+    session.Protocol.Debugger.stepOut();
+  });
+  session.Protocol.Debugger.onScriptParsed(message => executionContextIds.add(message.params.executionContextId));
+}
diff --git a/src/v8/test/inspector/runtime/es6-module-expected.txt b/src/v8/test/inspector/runtime/es6-module-expected.txt
new file mode 100644
index 0000000..646fd01
--- /dev/null
+++ b/src/v8/test/inspector/runtime/es6-module-expected.txt
@@ -0,0 +1,241 @@
+Checks basic ES6 modules support.
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 17
+        endLine : 5
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : 9C014F7249BAFA12B91017817AD15091D01A9155
+        isLiveEdit : false
+        isModule : true
+        length : 83
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : module1
+    }
+}
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 17
+        endLine : 5
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : 443A2FA24A6112E6B9101781E6A19B56BDC396D4
+        isLiveEdit : false
+        isModule : true
+        length : 84
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : module2
+    }
+}
+{
+    method : Debugger.scriptParsed
+    params : {
+        endColumn : 0
+        endLine : 8
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : 54D834614FBF9B389082DAE06CD3EFC499BEBF13
+        isLiveEdit : false
+        isModule : true
+        length : 191
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : module3
+    }
+}
+console.log(module1)
+foo (module1:2:10)
+(anonymous) (module3:3:12)
+
+console.log(42)
+(anonymous) (module3:3:8)
+
+console.log(module2)
+foo (module2:2:10)
+(anonymous) (module3:4:12)
+
+console.log(239)
+(anonymous) (module3:4:8)
+
+{
+    method : Debugger.paused
+    params : {
+        callFrames : [
+            [0] : {
+                callFrameId : <callFrameId>
+                functionLocation : {
+                    columnNumber : 0
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                }
+                functionName : 
+                location : {
+                    columnNumber : 0
+                    lineNumber : 7
+                    scriptId : <scriptId>
+                }
+                scopeChain : [
+                    [0] : {
+                        endLocation : {
+                            columnNumber : 0
+                            lineNumber : 8
+                            scriptId : <scriptId>
+                        }
+                        object : {
+                            className : Object
+                            description : Object
+                            objectId : <objectId>
+                            type : object
+                        }
+                        startLocation : {
+                            columnNumber : 0
+                            lineNumber : 0
+                            scriptId : <scriptId>
+                        }
+                        type : module
+                    }
+                    [1] : {
+                        object : {
+                            className : global
+                            description : global
+                            objectId : <objectId>
+                            type : object
+                        }
+                        type : global
+                    }
+                ]
+                this : {
+                    type : undefined
+                }
+                url : module3
+            }
+        ]
+        hitBreakpoints : [
+        ]
+        reason : other
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : foo1
+                value : {
+                    className : Function
+                    description : function foo() {   console.log('module1');   return 42; }
+                    objectId : <objectId>
+                    type : function
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : foo2
+                value : {
+                    className : Function
+                    description : function foo() {   console.log('module2');   return 239; }
+                    objectId : <objectId>
+                    type : function
+                }
+                writable : true
+            }
+            [2] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : a1
+                value : {
+                    description : 1
+                    type : number
+                    value : 1
+                }
+                writable : true
+            }
+            [3] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : a2
+                value : {
+                    description : 2
+                    type : number
+                    value : 2
+                }
+                writable : true
+            }
+        ]
+    }
+}
+{
+    method : Debugger.scriptFailedToParse
+    params : {
+        endColumn : 1
+        endLine : 0
+        executionContextId : <executionContextId>
+        hasSourceURL : false
+        hash : FF746120E4E4F1BA4CB5762843D429DC872EBA18
+        isModule : true
+        length : 1
+        scriptId : <scriptId>
+        sourceMapURL : 
+        startColumn : 0
+        startLine : 0
+        url : module4
+    }
+}
+{
+    method : Runtime.exceptionThrown
+    params : {
+        exceptionDetails : {
+            columnNumber : 0
+            exception : {
+                className : SyntaxError
+                description : SyntaxError: Unexpected token }
+                objectId : <objectId>
+                preview : {
+                    description : SyntaxError: Unexpected token }
+                    overflow : false
+                    properties : [
+                        [0] : {
+                            name : stack
+                            type : string
+                            value : SyntaxError: Unexpected token }
+                        }
+                        [1] : {
+                            name : message
+                            type : string
+                            value : Unexpected token }
+                        }
+                    ]
+                    subtype : error
+                    type : object
+                }
+                subtype : error
+                type : object
+            }
+            exceptionId : <exceptionId>
+            executionContextId : <executionContextId>
+            lineNumber : 0
+            scriptId : <scriptId>
+            text : Uncaught SyntaxError: Unexpected token }
+            url : module4
+        }
+        timestamp : <timestamp>
+    }
+}
diff --git a/src/v8/test/inspector/runtime/es6-module.js b/src/v8/test/inspector/runtime/es6-module.js
new file mode 100644
index 0000000..6d9e434
--- /dev/null
+++ b/src/v8/test/inspector/runtime/es6-module.js
@@ -0,0 +1,61 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks basic ES6 modules support.');
+
+var module1 = `
+export function foo() {
+  console.log('module1');
+  return 42;
+}
+export let a1 = 1`;
+
+var module2 = `
+export function foo() {
+  console.log('module2');
+  return 239;
+}
+export let a2 = 2`;
+
+var module3 = `
+import { foo as foo1 } from 'module1';
+import { foo as foo2 } from 'module2';
+console.log(foo1());
+console.log(foo2());
+import { a1 } from 'module1';
+import { a2 } from 'module2';
+debugger;
+`;
+
+var module4 = '}';
+
+session.setupScriptMap();
+// We get scriptParsed events for modules ..
+Protocol.Debugger.onScriptParsed(InspectorTest.logMessage);
+// .. scriptFailed to parse for modules with syntax error ..
+Protocol.Debugger.onScriptFailedToParse(InspectorTest.logMessage);
+// .. API messages from modules contain correct stack trace ..
+Protocol.Runtime.onConsoleAPICalled(message => {
+  InspectorTest.log(`console.log(${message.params.args[0].value})`);
+  session.logCallFrames(message.params.stackTrace.callFrames);
+  InspectorTest.log('');
+});
+// .. we could break inside module and scope contains correct list of variables ..
+Protocol.Debugger.onPaused(message => {
+  InspectorTest.logMessage(message);
+  Protocol.Runtime.getProperties({ objectId: message.params.callFrames[0].scopeChain[0].object.objectId})
+    .then(InspectorTest.logMessage)
+    .then(() => Protocol.Debugger.resume());
+});
+// .. we process uncaught errors from modules correctly.
+Protocol.Runtime.onExceptionThrown(InspectorTest.logMessage);
+
+Protocol.Runtime.enable();
+Protocol.Debugger.enable()
+  .then(() => contextGroup.addModule(module1, "module1"))
+  .then(() => contextGroup.addModule(module2, "module2"))
+  .then(() => contextGroup.addModule(module3, "module3"))
+  .then(() => contextGroup.addModule(module4, "module4"))
+  .then(() => InspectorTest.waitForPendingTasks())
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/runtime/evaluate-async-expected.txt b/src/v8/test/inspector/runtime/evaluate-async-expected.txt
new file mode 100644
index 0000000..763b429
--- /dev/null
+++ b/src/v8/test/inspector/runtime/evaluate-async-expected.txt
@@ -0,0 +1,249 @@
+Tests that Runtime.evaluate works with awaitPromise flag.
+
+Running test: testResolvedPromise
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 239
+            type : number
+            value : 239
+        }
+    }
+}
+
+Running test: testRejectedPromise
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 0
+            exception : {
+                description : 239
+                type : number
+                value : 239
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 0
+            text : Uncaught (in promise)
+        }
+        result : {
+            description : 239
+            type : number
+            value : 239
+        }
+    }
+}
+
+Running test: testRejectedPromiseWithError
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 11
+            exception : {
+                className : Error
+                description : Error: MyError     at foo (<anonymous>:13:11)     at throwError (<anonymous>:15:3)     at <anonymous>
+                objectId : <objectId>
+                subtype : error
+                type : object
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 13
+            scriptId : <scriptId>
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 10
+                        functionName : foo
+                        lineNumber : 12
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                    [1] : {
+                        columnNumber : 2
+                        functionName : throwError
+                        lineNumber : 14
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught (in promise) Error: MyError
+        }
+        result : {
+            className : Error
+            description : Error: MyError     at foo (<anonymous>:13:11)     at throwError (<anonymous>:15:3)     at <anonymous>
+            objectId : <objectId>
+            subtype : error
+            type : object
+        }
+    }
+}
+
+Running test: testRejectedPromiseWithSyntaxError
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 5
+            exception : {
+                className : SyntaxError
+                description : SyntaxError: Unexpected token }     at foo (<anonymous>:21:5)     at throwSyntaxError (<anonymous>:23:3)     at <anonymous>
+                objectId : <objectId>
+                subtype : error
+                type : object
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 21
+            scriptId : <scriptId>
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 4
+                        functionName : foo
+                        lineNumber : 20
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                    [1] : {
+                        columnNumber : 2
+                        functionName : throwSyntaxError
+                        lineNumber : 22
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught (in promise) SyntaxError: Unexpected token }
+        }
+        result : {
+            className : SyntaxError
+            description : SyntaxError: Unexpected token }     at foo (<anonymous>:21:5)     at throwSyntaxError (<anonymous>:23:3)     at <anonymous>
+            objectId : <objectId>
+            subtype : error
+            type : object
+        }
+    }
+}
+
+Running test: testPrimitiveValueInsteadOfPromise
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : boolean
+            value : true
+        }
+    }
+}
+
+Running test: testObjectInsteadOfPromise
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : object
+            value : {
+            }
+        }
+    }
+}
+
+Running test: testPendingPromise
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : object
+            value : {
+                a : 239
+            }
+        }
+    }
+}
+
+Running test: testExceptionInEvaluate
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 0
+            exception : {
+                description : 239
+                type : number
+                value : 239
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 0
+            scriptId : <scriptId>
+            text : Uncaught
+        }
+        result : {
+            description : 239
+            type : number
+            value : 239
+        }
+    }
+}
+
+Running test: testThenableJob
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+
+Running test: testLastEvaluatedResult
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+
+Running test: testRuntimeDisable
+Resolving promise..
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Object
+            description : Object
+            objectId : <objectId>
+            type : object
+        }
+    }
+}
+Promise resolved
+
+Running test: testImmediatelyResolvedAfterAfterContextDestroyed
+Destroying context..
+{
+    error : {
+        code : -32000
+        message : Execution context was destroyed.
+    }
+    id : <messageId>
+}
+Context destroyed
+Triggering weak callback..
diff --git a/src/v8/test/inspector/runtime/evaluate-async-with-wrap-error-expected.txt b/src/v8/test/inspector/runtime/evaluate-async-with-wrap-error-expected.txt
new file mode 100644
index 0000000..743acdb
--- /dev/null
+++ b/src/v8/test/inspector/runtime/evaluate-async-with-wrap-error-expected.txt
@@ -0,0 +1,8 @@
+Test that Runtime.evaluate correctly process errors during wrapping async result.
+{
+    error : {
+        code : -32000
+        message : Object couldn't be returned by value
+    }
+    id : <messageId>
+}
diff --git a/src/v8/test/inspector/runtime/evaluate-async-with-wrap-error.js b/src/v8/test/inspector/runtime/evaluate-async-with-wrap-error.js
new file mode 100644
index 0000000..43b71ad
--- /dev/null
+++ b/src/v8/test/inspector/runtime/evaluate-async-with-wrap-error.js
@@ -0,0 +1,15 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Test that " +
+    "Runtime.evaluate correctly process errors during wrapping async result.");
+
+var evaluateArguments = {
+  expression: "Promise.resolve(Symbol(123))",
+  returnByValue: true,
+  awaitPromise: true
+};
+Protocol.Runtime.evaluate(evaluateArguments)
+  .then(message => InspectorTest.logMessage(message))
+  .then(() => InspectorTest.completeTest());
diff --git a/src/v8/test/inspector/runtime/evaluate-async.js b/src/v8/test/inspector/runtime/evaluate-async.js
new file mode 100644
index 0000000..385b3f6
--- /dev/null
+++ b/src/v8/test/inspector/runtime/evaluate-async.js
@@ -0,0 +1,148 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Tests that Runtime.evaluate works with awaitPromise flag.");
+
+contextGroup.addScript(`
+function createPromiseAndScheduleResolve()
+{
+  var resolveCallback;
+  var promise = new Promise((resolve) => resolveCallback = resolve);
+  setTimeout(resolveCallback.bind(null, { a : 239 }), 0);
+  return promise;
+}
+
+function throwError()
+{
+  function foo() {
+    throw new Error('MyError');
+  }
+  foo();
+}
+
+function throwSyntaxError()
+{
+  function foo() {
+    eval('}');
+  }
+  foo();
+}
+`);
+
+InspectorTest.runAsyncTestSuite([
+  async function testResolvedPromise()
+  {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: "Promise.resolve(239)",
+      awaitPromise: true,
+      generatePreview: true
+    }));
+  },
+
+  async function testRejectedPromise()
+  {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: "Promise.reject(239)",
+      awaitPromise: true
+    }));
+  },
+
+  async function testRejectedPromiseWithError()
+  {
+    Protocol.Runtime.enable();
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: "Promise.resolve().then(throwError)",
+      awaitPromise: true
+    }));
+    await Protocol.Runtime.disable();
+  },
+
+  async function testRejectedPromiseWithSyntaxError()
+  {
+    Protocol.Runtime.enable();
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: "Promise.resolve().then(throwSyntaxError)",
+      awaitPromise: true
+    }));
+    await Protocol.Runtime.disable();
+  },
+
+  async function testPrimitiveValueInsteadOfPromise()
+  {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: "true",
+      awaitPromise: true
+    }));
+  },
+
+  async function testObjectInsteadOfPromise()
+  {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: "({})",
+      awaitPromise: true,
+      returnByValue: true
+    }));
+  },
+
+  async function testPendingPromise()
+  {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: "createPromiseAndScheduleResolve()",
+      awaitPromise: true,
+      returnByValue: true
+    }));
+  },
+
+  async function testExceptionInEvaluate()
+  {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: "throw 239",
+      awaitPromise: true
+    }));
+  },
+
+  async function testThenableJob()
+  {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: '({then: resolve => resolve(42)})',
+      awaitPromise: true}));
+  },
+
+  async function testLastEvaluatedResult()
+  {
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: 'Promise.resolve(42)',
+      awaitPromise: true,
+      objectGroup: 'console'
+    }));
+    InspectorTest.logMessage(await Protocol.Runtime.evaluate({
+      expression: '$_',
+      includeCommandLineAPI: true
+    }));
+  },
+
+  async function testRuntimeDisable()
+  {
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({
+      expression: 'new Promise(r1 => r = r1)',
+      awaitPromise: true }).then(InspectorTest.logMessage);
+    await Protocol.Runtime.disable();
+    InspectorTest.log('Resolving promise..');
+    await Protocol.Runtime.evaluate({expression: 'r({a:1})'});
+    InspectorTest.log('Promise resolved');
+  },
+
+  async function testImmediatelyResolvedAfterAfterContextDestroyed()
+  {
+    Protocol.Runtime.evaluate({
+      expression: 'new Promise(() => 42)',
+      awaitPromise: true }).then(InspectorTest.logMessage);
+    InspectorTest.log('Destroying context..');
+    await Protocol.Runtime.evaluate({expression: 'inspector.fireContextDestroyed()'});
+    InspectorTest.log('Context destroyed');
+    InspectorTest.log('Triggering weak callback..');
+    await Protocol.HeapProfiler.collectGarbage();
+  }
+]);
diff --git a/src/v8/test/inspector/runtime/evaluate-empty-stack-expected.txt b/src/v8/test/inspector/runtime/evaluate-empty-stack-expected.txt
new file mode 100644
index 0000000..90e67e8
--- /dev/null
+++ b/src/v8/test/inspector/runtime/evaluate-empty-stack-expected.txt
@@ -0,0 +1,10 @@
+Tests that Runtime.evaluate works with an empty stack
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : string
+            value : snape kills dumbledore
+        }
+    }
+}
diff --git a/src/v8/test/inspector/runtime/evaluate-empty-stack.js b/src/v8/test/inspector/runtime/evaluate-empty-stack.js
new file mode 100644
index 0000000..c09dfd1
--- /dev/null
+++ b/src/v8/test/inspector/runtime/evaluate-empty-stack.js
@@ -0,0 +1,13 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Tests that Runtime.evaluate works with an empty stack");
+
+contextGroup.addScript("var text = [48116210, 34460128, 1406661984071834]");
+
+var message = { expression: "text.map(x => x.toString(36)).join(' ')" };
+
+Protocol.Runtime.evaluate(message)
+  .then(message => InspectorTest.logMessage(message))
+  .then(() => InspectorTest.completeTest());
diff --git a/src/v8/test/inspector/runtime/evaluate-with-context-id-equal-zero-expected.txt b/src/v8/test/inspector/runtime/evaluate-with-context-id-equal-zero-expected.txt
new file mode 100644
index 0000000..5e26aa9
--- /dev/null
+++ b/src/v8/test/inspector/runtime/evaluate-with-context-id-equal-zero-expected.txt
@@ -0,0 +1,8 @@
+Tests that DevTools doesn't crash on Runtime.evaluate with contextId equals 0.
+{
+    error : {
+        code : -32000
+        message : Cannot find context with specified id
+    }
+    id : <messageId>
+}
diff --git a/src/v8/test/inspector/runtime/evaluate-with-context-id-equal-zero.js b/src/v8/test/inspector/runtime/evaluate-with-context-id-equal-zero.js
new file mode 100644
index 0000000..272c820
--- /dev/null
+++ b/src/v8/test/inspector/runtime/evaluate-with-context-id-equal-zero.js
@@ -0,0 +1,9 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Tests that DevTools doesn't crash on Runtime.evaluate with contextId equals 0.");
+
+Protocol.Runtime.evaluate({ "contextId": 0, "expression": "" })
+  .then(message => InspectorTest.logMessage(message))
+  .then(() => InspectorTest.completeTest());
diff --git a/src/v8/test/inspector/runtime/evaluate-with-generate-preview-expected.txt b/src/v8/test/inspector/runtime/evaluate-with-generate-preview-expected.txt
new file mode 100644
index 0000000..ef1cd1a
--- /dev/null
+++ b/src/v8/test/inspector/runtime/evaluate-with-generate-preview-expected.txt
@@ -0,0 +1,838 @@
+Tests that Runtime.evaluate will generate correct previews.
+
+Running test: testObjectPropertiesPreview
+{
+    description : Object
+    overflow : false
+    properties : [
+        [0] : {
+            name : p1
+            type : object
+            value : Object
+        }
+        [1] : {
+            name : p2
+            type : object
+            value : Object
+        }
+        [2] : {
+            name : p3
+            type : function
+            value : 
+        }
+        [3] : {
+            name : p4
+            type : accessor
+        }
+        [4] : {
+            name : p6
+            type : accessor
+        }
+    ]
+    type : object
+}
+
+Running test: testArrayPropertiesPreview
+{
+    description : Array(8)
+    overflow : false
+    properties : [
+        [0] : {
+            name : 2
+            type : number
+            value : 1
+        }
+        [1] : {
+            name : 3
+            subtype : array
+            type : object
+            value : Array(1)
+        }
+        [2] : {
+            name : 4
+            type : function
+            value : 
+        }
+        [3] : {
+            name : nonEntryFunction
+            type : function
+            value : 
+        }
+        [4] : {
+            name : 5
+            type : accessor
+        }
+        [5] : {
+            name : 7
+            type : accessor
+        }
+    ]
+    subtype : array
+    type : object
+}
+
+Running test: testInheritingObjectPropertiesPreview
+{
+    description : Object
+    overflow : false
+    properties : [
+        [0] : {
+            name : prototype
+            type : object
+            value : Object
+        }
+    ]
+    type : object
+}
+
+Running test: testInheritingArrayPropertiesPreview
+{
+    description : Array(0)
+    overflow : false
+    properties : [
+        [0] : {
+            name : prototype
+            subtype : array
+            type : object
+            value : Array(8)
+        }
+    ]
+    subtype : array
+    type : object
+}
+
+Running test: testShortTypedArrayPropertiesPreview
+{
+    description : Uint8Array(3)
+    overflow : false
+    properties : [
+        [0] : {
+            name : 0
+            type : number
+            value : 0
+        }
+        [1] : {
+            name : 1
+            type : number
+            value : 0
+        }
+        [2] : {
+            name : 2
+            type : number
+            value : 0
+        }
+    ]
+    subtype : typedarray
+    type : object
+}
+
+Running test: testLongTypedArrayPropertiesPreview
+{
+    description : Uint8Array(500001)
+    overflow : true
+    properties : [
+        [0] : {
+            name : 0
+            type : number
+            value : 0
+        }
+        [1] : {
+            name : 1
+            type : number
+            value : 0
+        }
+        [2] : {
+            name : 2
+            type : number
+            value : 0
+        }
+        [3] : {
+            name : 3
+            type : number
+            value : 0
+        }
+        [4] : {
+            name : 4
+            type : number
+            value : 0
+        }
+        [5] : {
+            name : 5
+            type : number
+            value : 0
+        }
+        [6] : {
+            name : 6
+            type : number
+            value : 0
+        }
+        [7] : {
+            name : 7
+            type : number
+            value : 0
+        }
+        [8] : {
+            name : 8
+            type : number
+            value : 0
+        }
+        [9] : {
+            name : 9
+            type : number
+            value : 0
+        }
+        [10] : {
+            name : 10
+            type : number
+            value : 0
+        }
+        [11] : {
+            name : 11
+            type : number
+            value : 0
+        }
+        [12] : {
+            name : 12
+            type : number
+            value : 0
+        }
+        [13] : {
+            name : 13
+            type : number
+            value : 0
+        }
+        [14] : {
+            name : 14
+            type : number
+            value : 0
+        }
+        [15] : {
+            name : 15
+            type : number
+            value : 0
+        }
+        [16] : {
+            name : 16
+            type : number
+            value : 0
+        }
+        [17] : {
+            name : 17
+            type : number
+            value : 0
+        }
+        [18] : {
+            name : 18
+            type : number
+            value : 0
+        }
+        [19] : {
+            name : 19
+            type : number
+            value : 0
+        }
+        [20] : {
+            name : 20
+            type : number
+            value : 0
+        }
+        [21] : {
+            name : 21
+            type : number
+            value : 0
+        }
+        [22] : {
+            name : 22
+            type : number
+            value : 0
+        }
+        [23] : {
+            name : 23
+            type : number
+            value : 0
+        }
+        [24] : {
+            name : 24
+            type : number
+            value : 0
+        }
+        [25] : {
+            name : 25
+            type : number
+            value : 0
+        }
+        [26] : {
+            name : 26
+            type : number
+            value : 0
+        }
+        [27] : {
+            name : 27
+            type : number
+            value : 0
+        }
+        [28] : {
+            name : 28
+            type : number
+            value : 0
+        }
+        [29] : {
+            name : 29
+            type : number
+            value : 0
+        }
+        [30] : {
+            name : 30
+            type : number
+            value : 0
+        }
+        [31] : {
+            name : 31
+            type : number
+            value : 0
+        }
+        [32] : {
+            name : 32
+            type : number
+            value : 0
+        }
+        [33] : {
+            name : 33
+            type : number
+            value : 0
+        }
+        [34] : {
+            name : 34
+            type : number
+            value : 0
+        }
+        [35] : {
+            name : 35
+            type : number
+            value : 0
+        }
+        [36] : {
+            name : 36
+            type : number
+            value : 0
+        }
+        [37] : {
+            name : 37
+            type : number
+            value : 0
+        }
+        [38] : {
+            name : 38
+            type : number
+            value : 0
+        }
+        [39] : {
+            name : 39
+            type : number
+            value : 0
+        }
+        [40] : {
+            name : 40
+            type : number
+            value : 0
+        }
+        [41] : {
+            name : 41
+            type : number
+            value : 0
+        }
+        [42] : {
+            name : 42
+            type : number
+            value : 0
+        }
+        [43] : {
+            name : 43
+            type : number
+            value : 0
+        }
+        [44] : {
+            name : 44
+            type : number
+            value : 0
+        }
+        [45] : {
+            name : 45
+            type : number
+            value : 0
+        }
+        [46] : {
+            name : 46
+            type : number
+            value : 0
+        }
+        [47] : {
+            name : 47
+            type : number
+            value : 0
+        }
+        [48] : {
+            name : 48
+            type : number
+            value : 0
+        }
+        [49] : {
+            name : 49
+            type : number
+            value : 0
+        }
+        [50] : {
+            name : 50
+            type : number
+            value : 0
+        }
+        [51] : {
+            name : 51
+            type : number
+            value : 0
+        }
+        [52] : {
+            name : 52
+            type : number
+            value : 0
+        }
+        [53] : {
+            name : 53
+            type : number
+            value : 0
+        }
+        [54] : {
+            name : 54
+            type : number
+            value : 0
+        }
+        [55] : {
+            name : 55
+            type : number
+            value : 0
+        }
+        [56] : {
+            name : 56
+            type : number
+            value : 0
+        }
+        [57] : {
+            name : 57
+            type : number
+            value : 0
+        }
+        [58] : {
+            name : 58
+            type : number
+            value : 0
+        }
+        [59] : {
+            name : 59
+            type : number
+            value : 0
+        }
+        [60] : {
+            name : 60
+            type : number
+            value : 0
+        }
+        [61] : {
+            name : 61
+            type : number
+            value : 0
+        }
+        [62] : {
+            name : 62
+            type : number
+            value : 0
+        }
+        [63] : {
+            name : 63
+            type : number
+            value : 0
+        }
+        [64] : {
+            name : 64
+            type : number
+            value : 0
+        }
+        [65] : {
+            name : 65
+            type : number
+            value : 0
+        }
+        [66] : {
+            name : 66
+            type : number
+            value : 0
+        }
+        [67] : {
+            name : 67
+            type : number
+            value : 0
+        }
+        [68] : {
+            name : 68
+            type : number
+            value : 0
+        }
+        [69] : {
+            name : 69
+            type : number
+            value : 0
+        }
+        [70] : {
+            name : 70
+            type : number
+            value : 0
+        }
+        [71] : {
+            name : 71
+            type : number
+            value : 0
+        }
+        [72] : {
+            name : 72
+            type : number
+            value : 0
+        }
+        [73] : {
+            name : 73
+            type : number
+            value : 0
+        }
+        [74] : {
+            name : 74
+            type : number
+            value : 0
+        }
+        [75] : {
+            name : 75
+            type : number
+            value : 0
+        }
+        [76] : {
+            name : 76
+            type : number
+            value : 0
+        }
+        [77] : {
+            name : 77
+            type : number
+            value : 0
+        }
+        [78] : {
+            name : 78
+            type : number
+            value : 0
+        }
+        [79] : {
+            name : 79
+            type : number
+            value : 0
+        }
+        [80] : {
+            name : 80
+            type : number
+            value : 0
+        }
+        [81] : {
+            name : 81
+            type : number
+            value : 0
+        }
+        [82] : {
+            name : 82
+            type : number
+            value : 0
+        }
+        [83] : {
+            name : 83
+            type : number
+            value : 0
+        }
+        [84] : {
+            name : 84
+            type : number
+            value : 0
+        }
+        [85] : {
+            name : 85
+            type : number
+            value : 0
+        }
+        [86] : {
+            name : 86
+            type : number
+            value : 0
+        }
+        [87] : {
+            name : 87
+            type : number
+            value : 0
+        }
+        [88] : {
+            name : 88
+            type : number
+            value : 0
+        }
+        [89] : {
+            name : 89
+            type : number
+            value : 0
+        }
+        [90] : {
+            name : 90
+            type : number
+            value : 0
+        }
+        [91] : {
+            name : 91
+            type : number
+            value : 0
+        }
+        [92] : {
+            name : 92
+            type : number
+            value : 0
+        }
+        [93] : {
+            name : 93
+            type : number
+            value : 0
+        }
+        [94] : {
+            name : 94
+            type : number
+            value : 0
+        }
+        [95] : {
+            name : 95
+            type : number
+            value : 0
+        }
+        [96] : {
+            name : 96
+            type : number
+            value : 0
+        }
+        [97] : {
+            name : 97
+            type : number
+            value : 0
+        }
+        [98] : {
+            name : 98
+            type : number
+            value : 0
+        }
+        [99] : {
+            name : 99
+            type : number
+            value : 0
+        }
+    ]
+    subtype : typedarray
+    type : object
+}
+
+Running test: testSetPropertiesPreview
+{
+    description : Set(3)
+    entries : [
+        [0] : {
+            value : {
+                description : 1
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+        [1] : {
+            value : {
+                description : 2
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+        [2] : {
+            value : {
+                description : 3
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+    ]
+    overflow : false
+    properties : [
+    ]
+    subtype : set
+    type : object
+}
+
+Running test: testBigSetPropertiesPreview
+{
+    description : Set(10)
+    entries : [
+        [0] : {
+            value : {
+                description : 0
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+        [1] : {
+            value : {
+                description : 1
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+        [2] : {
+            value : {
+                description : 2
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+        [3] : {
+            value : {
+                description : 3
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+        [4] : {
+            value : {
+                description : 4
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+    ]
+    overflow : true
+    properties : [
+    ]
+    subtype : set
+    type : object
+}
+
+Running test: testMixedSetPropertiesPreview
+{
+    description : Set(10)
+    entries : [
+        [0] : {
+            value : {
+                description : 0
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+        [1] : {
+            value : {
+                description : 1
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+        [2] : {
+            value : {
+                description : 2
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+        [3] : {
+            value : {
+                description : 3
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+        [4] : {
+            value : {
+                description : 4
+                overflow : false
+                properties : [
+                ]
+                type : number
+            }
+        }
+    ]
+    overflow : true
+    properties : [
+        [0] : {
+            name : _prop_0
+            type : number
+            value : 1
+        }
+        [1] : {
+            name : _prop_1
+            type : number
+            value : 1
+        }
+        [2] : {
+            name : _prop_2
+            type : number
+            value : 1
+        }
+        [3] : {
+            name : _prop_3
+            type : number
+            value : 1
+        }
+        [4] : {
+            name : _prop_4
+            type : number
+            value : 1
+        }
+    ]
+    subtype : set
+    type : object
+}
+
+Running test: testObjInheritsGetterProperty
+{
+    description : Object
+    overflow : false
+    properties : [
+        [0] : {
+            name : propNotNamedProto
+            type : number
+            value : NaN
+        }
+    ]
+    type : object
+}
+
+Running test: testObjWithArrayAsProto
+{
+    description : Array
+    overflow : false
+    properties : [
+    ]
+    type : object
+}
diff --git a/src/v8/test/inspector/runtime/evaluate-with-generate-preview.js b/src/v8/test/inspector/runtime/evaluate-with-generate-preview.js
new file mode 100644
index 0000000..8ea0ea4
--- /dev/null
+++ b/src/v8/test/inspector/runtime/evaluate-with-generate-preview.js
@@ -0,0 +1,147 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Tests that Runtime.evaluate will generate correct previews.");
+
+contextGroup.addScript(
+`
+var f1 = function(){};
+
+Object.prototype[0] = 'default-first';
+var obj = {p1: {a:1}, p2: {b:'foo'}, p3: f1};
+Object.defineProperties(obj, {
+  p4: {
+    get() { return 2 }
+  },
+  p5: {
+    set(x) { return x }
+  },
+  p6: {
+    get() { return 2 },
+    set(x) { return x }
+  }
+});
+
+Array.prototype[0] = 'default-first';
+var arr = [,, 1, [2], f1];
+Object.defineProperties(arr, {
+  5: {
+    get() { return 2 }
+  },
+  6: {
+    set(x) { return x }
+  },
+  7: {
+    get() { return 2 },
+    set(x) { return x }
+  }
+});
+arr.nonEntryFunction = f1;
+
+var inheritingObj = {};
+var inheritingArr = [];
+inheritingObj.prototype = obj;
+inheritingArr.prototype = arr;
+
+var shortTypedArray = new Uint8Array(3);
+var longTypedArray = new Uint8Array(500001);
+var set = new Set([1, 2, 3]);
+var bigSet = new Set();
+var mixedSet = new Set();
+for (var i = 0; i < 10; i++) {
+  bigSet.add(i);
+  mixedSet["_prop_" + i] = 1;
+  mixedSet.add(i);
+}
+
+var deterministicNativeFunction = Math.log;
+var parentObj = {};
+Object.defineProperty(parentObj, 'propNotNamedProto', {
+  get: deterministicNativeFunction,
+  set: function() {}
+});
+var objInheritsGetterProperty = {__proto__: parentObj};
+inspector.allowAccessorFormatting(objInheritsGetterProperty);
+`);
+
+contextGroup.setupInjectedScriptEnvironment();
+
+InspectorTest.runTestSuite([
+  function testObjectPropertiesPreview(next)
+  {
+    Protocol.Runtime.evaluate({ "expression": "obj", "generatePreview": true })
+        .then(result => InspectorTest.logMessage(result.result.result.preview))
+        .then(next);
+  },
+
+  function testArrayPropertiesPreview(next)
+  {
+    Protocol.Runtime.evaluate({ "expression": "arr", "generatePreview": true })
+        .then(result => InspectorTest.logMessage(result.result.result.preview))
+        .then(next);
+  },
+
+  function testInheritingObjectPropertiesPreview(next)
+  {
+    Protocol.Runtime.evaluate({ "expression": "inheritingObj", "generatePreview": true })
+        .then(result => InspectorTest.logMessage(result.result.result.preview))
+        .then(next);
+  },
+
+  function testInheritingArrayPropertiesPreview(next)
+  {
+    Protocol.Runtime.evaluate({ "expression": "inheritingArr", "generatePreview": true })
+        .then(result => InspectorTest.logMessage(result.result.result.preview))
+        .then(next);
+  },
+
+  function testShortTypedArrayPropertiesPreview(next)
+  {
+    Protocol.Runtime.evaluate({ "expression": "shortTypedArray", "generatePreview": true })
+        .then(result => InspectorTest.logMessage(result.result.result.preview))
+        .then(next);
+  },
+
+  function testLongTypedArrayPropertiesPreview(next)
+  {
+    Protocol.Runtime.evaluate({ "expression": "longTypedArray", "generatePreview": true })
+        .then(result => InspectorTest.logMessage(result.result.result.preview))
+        .then(next);
+  },
+
+  function testSetPropertiesPreview(next)
+  {
+    Protocol.Runtime.evaluate({ "expression": "set", "generatePreview": true })
+        .then(result => InspectorTest.logMessage(result.result.result.preview))
+        .then(next);
+  },
+
+  function testBigSetPropertiesPreview(next)
+  {
+    Protocol.Runtime.evaluate({ "expression": "bigSet", "generatePreview": true })
+        .then(result => InspectorTest.logMessage(result.result.result.preview))
+        .then(next);
+  },
+
+  function testMixedSetPropertiesPreview(next)
+  {
+    Protocol.Runtime.evaluate({ "expression": "mixedSet", "generatePreview": true })
+        .then(result => InspectorTest.logMessage(result.result.result.preview))
+        .then(next);
+  },
+
+  function testObjInheritsGetterProperty(next)
+  {
+    Protocol.Runtime.evaluate({ "expression": "objInheritsGetterProperty", "generatePreview": true })
+        .then(result => InspectorTest.logMessage(result.result.result.preview))
+        .then(next);
+  },
+
+  function testObjWithArrayAsProto(next)
+  {
+    Protocol.Runtime.evaluate({ "expression": "Object.create([1,2])", "generatePreview": true })
+        .then(result => InspectorTest.logMessage(result.result.result.preview))
+        .then(next);
+  }
+]);
diff --git a/src/v8/test/inspector/runtime/exception-thrown-expected.txt b/src/v8/test/inspector/runtime/exception-thrown-expected.txt
new file mode 100644
index 0000000..fb4cf70
--- /dev/null
+++ b/src/v8/test/inspector/runtime/exception-thrown-expected.txt
@@ -0,0 +1,113 @@
+Check that exceptionThrown is supported by test runner.
+{
+    method : Runtime.exceptionThrown
+    params : {
+        exceptionDetails : {
+            columnNumber : 2
+            exception : {
+                className : Error
+                description : Error     at setTimeout (<anonymous>:2:9)
+                objectId : <objectId>
+                preview : {
+                    description : Error     at setTimeout (<anonymous>:2:9)
+                    overflow : false
+                    properties : [
+                        [0] : {
+                            name : stack
+                            type : string
+                            value : Error     at setTimeout (<anonymous>:2:9)
+                        }
+                    ]
+                    subtype : error
+                    type : object
+                }
+                subtype : error
+                type : object
+            }
+            exceptionId : <exceptionId>
+            executionContextId : <executionContextId>
+            lineNumber : 1
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 8
+                        functionName : setTimeout
+                        lineNumber : 1
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught Error
+        }
+        timestamp : <timestamp>
+    }
+}
+{
+    method : Runtime.exceptionThrown
+    params : {
+        exceptionDetails : {
+            columnNumber : 1
+            exception : {
+                className : SyntaxError
+                description : SyntaxError: Unexpected token }
+                objectId : <objectId>
+                preview : {
+                    description : SyntaxError: Unexpected token }
+                    overflow : false
+                    properties : [
+                        [0] : {
+                            name : stack
+                            type : string
+                            value : SyntaxError: Unexpected token }
+                        }
+                        [1] : {
+                            name : message
+                            type : string
+                            value : Unexpected token }
+                        }
+                    ]
+                    subtype : error
+                    type : object
+                }
+                subtype : error
+                type : object
+            }
+            exceptionId : <exceptionId>
+            executionContextId : <executionContextId>
+            lineNumber : 0
+            scriptId : <scriptId>
+            text : Uncaught SyntaxError: Unexpected token }
+        }
+        timestamp : <timestamp>
+    }
+}
+{
+    method : Runtime.exceptionThrown
+    params : {
+        exceptionDetails : {
+            columnNumber : 2
+            exception : {
+                description : 239
+                type : number
+                value : 239
+            }
+            exceptionId : <exceptionId>
+            executionContextId : <executionContextId>
+            lineNumber : 1
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 2
+                        functionName : setTimeout
+                        lineNumber : 1
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught 239
+        }
+        timestamp : <timestamp>
+    }
+}
diff --git a/src/v8/test/inspector/runtime/exception-thrown.js b/src/v8/test/inspector/runtime/exception-thrown.js
new file mode 100644
index 0000000..91f48bc
--- /dev/null
+++ b/src/v8/test/inspector/runtime/exception-thrown.js
@@ -0,0 +1,12 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Check that exceptionThrown is supported by test runner.")
+
+Protocol.Runtime.enable();
+Protocol.Runtime.onExceptionThrown(message => InspectorTest.logMessage(message));
+Protocol.Runtime.evaluate({ expression: "setTimeout(() => { \n  throw new Error() }, 0)" });
+Protocol.Runtime.evaluate({ expression: "setTimeout(\" }\", 0)" });
+Protocol.Runtime.evaluate({ expression: "setTimeout(() => { \n  throw 239; }, 0)" });
+InspectorTest.waitForPendingTasks().then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/runtime/function-scopes-expected.txt b/src/v8/test/inspector/runtime/function-scopes-expected.txt
new file mode 100644
index 0000000..0503e31
--- /dev/null
+++ b/src/v8/test/inspector/runtime/function-scopes-expected.txt
@@ -0,0 +1,53 @@
+Checks [[Scopes]] for functions
+Catch:
+{
+    configurable : true
+    enumerable : true
+    isOwn : true
+    name : a
+    value : {
+        description : 1
+        type : number
+        value : 1
+    }
+    writable : true
+}
+With block:
+{
+    configurable : true
+    enumerable : true
+    isOwn : true
+    name : b
+    value : {
+        description : 2
+        type : number
+        value : 2
+    }
+    writable : true
+}
+Closure (closure):
+{
+    configurable : true
+    enumerable : true
+    isOwn : true
+    name : c
+    value : {
+        description : 3
+        type : number
+        value : 3
+    }
+    writable : true
+}
+Global:
+{
+    configurable : false
+    enumerable : true
+    isOwn : true
+    name : e
+    value : {
+        description : 5
+        type : number
+        value : 5
+    }
+    writable : true
+}
diff --git a/src/v8/test/inspector/runtime/function-scopes.js b/src/v8/test/inspector/runtime/function-scopes.js
new file mode 100644
index 0000000..bda069b
--- /dev/null
+++ b/src/v8/test/inspector/runtime/function-scopes.js
@@ -0,0 +1,56 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks [[Scopes]] for functions');
+
+contextGroup.addScript(`
+var f;
+try {
+  throw 1;
+} catch (a) {
+  with({b:2}) {
+    function closure() {
+      var c = 3;
+      function foo() {
+        var d = 4;
+        return a + b + c + d;
+      }
+      return foo;
+    }
+    f = closure;
+  }
+}
+var e = 5;
+//# sourceURL=test.js`);
+
+(async function test() {
+  let {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({
+    expression: 'f()'
+  });
+  let {result:{internalProperties}} = await Protocol.Runtime.getProperties({
+    objectId
+  });
+  let scopes = internalProperties.find(prop => prop.name === '[[Scopes]]');
+  let {result:{result}} = await Protocol.Runtime.getProperties({
+    objectId: scopes.value.objectId
+  });
+  await Promise.all(result.map(async scope => {
+    scope.variables = (await Protocol.Runtime.getProperties({
+      objectId: scope.value.objectId
+    })).result.result;
+  }));
+  let catchScope = result.find(scope => scope.value.description === 'Catch');
+  InspectorTest.log('Catch:');
+  InspectorTest.logMessage(catchScope.variables.find(variable => variable.name === 'a'));
+  InspectorTest.log('With block:');
+  let withScope = result.find(scope => scope.value.description === 'With Block');
+  InspectorTest.logMessage(withScope.variables.find(variable => variable.name === 'b'));
+  InspectorTest.log('Closure (closure):');
+  let closureScope = result.find(scope => scope.value.description === 'Closure (closure)');
+  InspectorTest.logMessage(closureScope.variables.find(variable => variable.name === 'c'));
+  InspectorTest.log('Global:');
+  let globalScope = result.find(scope => scope.value.description === 'Global');
+  InspectorTest.logMessage(globalScope.variables.find(variable => variable.name === 'e'));
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/runtime/get-properties-expected.txt b/src/v8/test/inspector/runtime/get-properties-expected.txt
new file mode 100644
index 0000000..1f7aa50
--- /dev/null
+++ b/src/v8/test/inspector/runtime/get-properties-expected.txt
@@ -0,0 +1,52 @@
+Checks Runtime.getProperties method
+
+Running test: testObject5
+  __proto__ own object undefined
+  foo own string cat
+Internal properties
+  [[PrimitiveValue]] number 5
+
+Running test: testNotOwn
+  __defineGetter__ inherited function undefined
+  __defineSetter__ inherited function undefined
+  __lookupGetter__ inherited function undefined
+  __lookupSetter__ inherited function undefined
+  __proto__ inherited no value, getter, setter
+  a own number 2
+  b own no value, getter, setter
+  c inherited number 4
+  constructor inherited function undefined
+  d inherited no value, getter
+  hasOwnProperty inherited function undefined
+  isPrototypeOf inherited function undefined
+  propertyIsEnumerable inherited function undefined
+  toLocaleString inherited function undefined
+  toString inherited function undefined
+  valueOf inherited function undefined
+
+Running test: testAccessorsOnly
+  b own no value, getter, setter
+  d own no value, setter
+
+Running test: testArray
+  0 own string red
+  1 own string green
+  2 own string blue
+  __proto__ own object undefined
+  length own number 3
+
+Running test: testBound
+  __proto__ own function undefined
+  length own number 0
+  name own string bound Number
+Internal properties
+  [[BoundArgs]] object undefined
+  [[BoundThis]] object undefined
+  [[TargetFunction]] function undefined
+
+Running test: testObjectThrowsLength
+  __proto__ own object undefined
+  length own no value, getter
+
+Running test: testTypedArrayWithoutLength
+  __proto__ own object undefined
diff --git a/src/v8/test/inspector/runtime/get-properties-on-proxy-expected.txt b/src/v8/test/inspector/runtime/get-properties-on-proxy-expected.txt
new file mode 100644
index 0000000..3395956
--- /dev/null
+++ b/src/v8/test/inspector/runtime/get-properties-on-proxy-expected.txt
@@ -0,0 +1,11 @@
+Check that while Runtime.getProperties call on proxy object no user defined trap will be executed.
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 0
+            type : number
+            value : 0
+        }
+    }
+}
diff --git a/src/v8/test/inspector/runtime/get-properties-on-proxy.js b/src/v8/test/inspector/runtime/get-properties-on-proxy.js
new file mode 100644
index 0000000..b2981df
--- /dev/null
+++ b/src/v8/test/inspector/runtime/get-properties-on-proxy.js
@@ -0,0 +1,101 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Check that while Runtime.getProperties call on proxy object no user defined trap will be executed.");
+
+contextGroup.addScript(`
+var self = this;
+function testFunction()
+{
+    self.counter = 0;
+    var handler = {
+        get: function(target, name){
+            self.counter++;
+            return Reflect.get.apply(this, arguments);
+        },
+        set: function(target, name){
+            self.counter++;
+            return Reflect.set.apply(this, arguments);
+        },
+        getPrototypeOf: function(target) {
+            self.counter++;
+            return Reflect.getPrototypeOf.apply(this, arguments);
+        },
+        setPrototypeOf: function(target) {
+            self.counter++;
+            return Reflect.setPrototypeOf.apply(this, arguments);
+        },
+        isExtensible: function(target) {
+            self.counter++;
+            return Reflect.isExtensible.apply(this, arguments);
+        },
+        isExtensible: function(target) {
+            self.counter++;
+            return Reflect.isExtensible.apply(this, arguments);
+        },
+        isExtensible: function(target) {
+            self.counter++;
+            return Reflect.isExtensible.apply(this, arguments);
+        },
+        preventExtensions: function() {
+            self.counter++;
+            return Reflect.preventExtensions.apply(this, arguments);
+        },
+        getOwnPropertyDescriptor: function() {
+            self.counter++;
+            return Reflect.getOwnPropertyDescriptor.apply(this, arguments);
+        },
+        defineProperty: function() {
+            self.counter++;
+            return Reflect.defineProperty.apply(this, arguments);
+        },
+        has: function() {
+            self.counter++;
+            return Reflect.has.apply(this, arguments);
+        },
+        get: function() {
+            self.counter++;
+            return Reflect.get.apply(this, arguments);
+        },
+        set: function() {
+            self.counter++;
+            return Reflect.set.apply(this, arguments);
+        },
+        deleteProperty: function() {
+            self.counter++;
+            return Reflect.deleteProperty.apply(this, arguments);
+        },
+        ownKeys: function() {
+            self.counter++;
+            return Reflect.ownKeys.apply(this, arguments);
+        },
+        apply: function() {
+            self.counter++;
+            return Reflect.apply.apply(this, arguments);
+        },
+        construct: function() {
+            self.counter++;
+            return Reflect.construct.apply(this, arguments);
+        }
+    };
+    return new Proxy({ a : 1}, handler);
+}`);
+
+Protocol.Runtime.evaluate({ expression: "testFunction()"}).then(requestProperties);
+
+function requestProperties(result)
+{
+  Protocol.Runtime.getProperties({ objectId: result.result.objectId, generatePreview: true }).then(checkCounter);
+}
+
+function checkCounter(result)
+{
+  Protocol.Runtime.evaluate({ expression: "self.counter" }).then(dumpCounter);
+}
+
+function dumpCounter(result)
+{
+  InspectorTest.logMessage(result);
+  InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/runtime/get-properties-preview-expected.txt b/src/v8/test/inspector/runtime/get-properties-preview-expected.txt
new file mode 100644
index 0000000..a3f4eb4
--- /dev/null
+++ b/src/v8/test/inspector/runtime/get-properties-preview-expected.txt
@@ -0,0 +1,32 @@
+Tests generated previews in Runtime.getProperties
+p1 : Object
+p2 : Object
+p1 : {
+    "type": "object",
+    "description": "Object",
+    "overflow": false,
+    "properties": [
+        {
+            "name": "a",
+            "type": "number",
+            "value": "1"
+        }
+    ]
+}
+p2 : {
+    "type": "object",
+    "description": "Object",
+    "overflow": false,
+    "properties": [
+        {
+            "name": "b",
+            "type": "string",
+            "value": "foo"
+        },
+        {
+            "name": "bb",
+            "type": "string",
+            "value": "bar"
+        }
+    ]
+}
diff --git a/src/v8/test/inspector/runtime/get-properties-preview.js b/src/v8/test/inspector/runtime/get-properties-preview.js
new file mode 100644
index 0000000..92c6e56
--- /dev/null
+++ b/src/v8/test/inspector/runtime/get-properties-preview.js
@@ -0,0 +1,29 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests generated previews in Runtime.getProperties');
+
+contextGroup.setupInjectedScriptEnvironment();
+
+Protocol.Runtime.evaluate({ "expression": "({p1: {a:1}, p2: {b:'foo', bb:'bar'}})" }).then(callbackEvaluate);
+
+function callbackEvaluate(result)
+{
+  Protocol.Runtime.getProperties({ "objectId": result.result.result.objectId, "ownProperties": true }).then(callbackGetProperties.bind(null, false));
+  Protocol.Runtime.getProperties({ "objectId": result.result.result.objectId, "ownProperties": true, "generatePreview": true }).then(callbackGetProperties.bind(null, true));
+}
+
+function callbackGetProperties(completeTest, result)
+{
+  for (var property of result.result.result) {
+    if (!property.value || property.name === "__proto__")
+      continue;
+    if (property.value.preview)
+      InspectorTest.log(property.name + " : " + JSON.stringify(property.value.preview, null, 4));
+    else
+      InspectorTest.log(property.name + " : " + property.value.description);
+  }
+  if (completeTest)
+    InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/runtime/get-properties.js b/src/v8/test/inspector/runtime/get-properties.js
new file mode 100644
index 0000000..56a4c4b
--- /dev/null
+++ b/src/v8/test/inspector/runtime/get-properties.js
@@ -0,0 +1,98 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks Runtime.getProperties method');
+
+InspectorTest.runAsyncTestSuite([
+  async function testObject5() {
+    let objectId = (await Protocol.Runtime.evaluate({
+      expression: '(function(){var r = Object(5); r.foo = \'cat\';return r;})()'
+    })).result.result.objectId;
+    let props = await Protocol.Runtime.getProperties({ objectId, ownProperties: true });
+    logGetPropertiesResult(props.result);
+  },
+
+  async function testNotOwn() {
+    let objectId = (await Protocol.Runtime.evaluate({
+      expression: '({ a: 2, set b(_) {}, get b() {return 5;}, __proto__: { a: 3, c: 4, get d() {return 6;} }})'
+    })).result.result.objectId;
+    let props = await Protocol.Runtime.getProperties({ objectId, ownProperties: false });
+    logGetPropertiesResult(props.result);
+  },
+
+  async function testAccessorsOnly() {
+    let objectId = (await Protocol.Runtime.evaluate({
+      expression: '({ a: 2, set b(_) {}, get b() {return 5;}, c: \'c\', set d(_){} })'
+    })).result.result.objectId;
+    let props = await Protocol.Runtime.getProperties({ objectId, ownProperties: true, accessorPropertiesOnly: true });
+    logGetPropertiesResult(props.result);
+  },
+
+  async function testArray() {
+    let objectId = (await Protocol.Runtime.evaluate({
+      expression: '[\'red\', \'green\', \'blue\']'
+    })).result.result.objectId;
+    let props = await Protocol.Runtime.getProperties({ objectId, ownProperties: true });
+    logGetPropertiesResult(props.result);
+  },
+
+  async function testBound() {
+    let objectId = (await Protocol.Runtime.evaluate({
+      expression: 'Number.bind({}, 5)'
+    })).result.result.objectId;
+    let props = await Protocol.Runtime.getProperties({ objectId, ownProperties: true });
+    logGetPropertiesResult(props.result);
+  },
+
+  async function testObjectThrowsLength() {
+    let objectId = (await Protocol.Runtime.evaluate({
+      expression: '({get length() { throw \'Length called\'; }})'
+    })).result.result.objectId;
+    let props = await Protocol.Runtime.getProperties({ objectId, ownProperties: true });
+    logGetPropertiesResult(props.result);
+  },
+
+  async function testTypedArrayWithoutLength() {
+    let objectId = (await Protocol.Runtime.evaluate({
+      expression: '({__proto__: Uint8Array.prototype})'
+    })).result.result.objectId;
+    let props = await Protocol.Runtime.getProperties({ objectId, ownProperties: true });
+    logGetPropertiesResult(props.result);
+  },
+]);
+
+function logGetPropertiesResult(protocolResult) {
+  function hasGetterSetter(property, fieldName) {
+    var v = property[fieldName];
+    if (!v) return false;
+    return v.type !== "undefined"
+  }
+
+  var propertyArray = protocolResult.result;
+  propertyArray.sort(NamedThingComparator);
+  for (var i = 0; i < propertyArray.length; i++) {
+    var p = propertyArray[i];
+    var v = p.value;
+    var own = p.isOwn ? "own" : "inherited";
+    if (v)
+      InspectorTest.log("  " + p.name + " " + own + " " + v.type + " " + v.value);
+    else
+      InspectorTest.log("  " + p.name + " " + own + " no value" +
+        (hasGetterSetter(p, "get") ? ", getter" : "") + (hasGetterSetter(p, "set") ? ", setter" : ""));
+  }
+  var internalPropertyArray = protocolResult.internalProperties;
+  if (internalPropertyArray) {
+    InspectorTest.log("Internal properties");
+    internalPropertyArray.sort(NamedThingComparator);
+    for (var i = 0; i < internalPropertyArray.length; i++) {
+      var p = internalPropertyArray[i];
+      var v = p.value;
+      InspectorTest.log("  " + p.name + " " + v.type + " " + v.value);
+    }
+  }
+
+  function NamedThingComparator(o1, o2) {
+    return o1.name === o2.name ? 0 : (o1.name < o2.name ? -1 : 1);
+  }
+}
diff --git a/src/v8/test/inspector/runtime/internal-properties-entries-expected.txt b/src/v8/test/inspector/runtime/internal-properties-entries-expected.txt
new file mode 100644
index 0000000..d395067
--- /dev/null
+++ b/src/v8/test/inspector/runtime/internal-properties-entries-expected.txt
@@ -0,0 +1,691 @@
+Checks internal [[Entries]] in Runtime.getProperties output
+
+Running test: maps
+expression: new Map([[1,2],[3,4]])
+[
+    [0] : {
+        key : 1
+        value : 2
+    }
+    [1] : {
+        key : 3
+        value : 4
+    }
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 0
+                value : {
+                    className : Object
+                    description : {1 => 2}
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 1
+                value : {
+                    className : Object
+                    description : {3 => 4}
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [2] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 2
+                    type : number
+                    value : 2
+                }
+                writable : true
+            }
+        ]
+    }
+}
+expression: new Map()
+[
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 0
+                    type : number
+                    value : 0
+                }
+                writable : true
+            }
+        ]
+    }
+}
+
+Running test: mapIterators
+expression: new Map([[1,2],[3,4]]).entries()
+[
+    [0] : {
+        key : 1
+        value : 2
+    }
+    [1] : {
+        key : 3
+        value : 4
+    }
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 0
+                value : {
+                    className : Object
+                    description : {1 => 2}
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 1
+                value : {
+                    className : Object
+                    description : {3 => 4}
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [2] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 2
+                    type : number
+                    value : 2
+                }
+                writable : true
+            }
+        ]
+    }
+}
+expression: it = new Map([[1,2],[3,4]]).entries(); it.next(); it
+[
+    [0] : {
+        key : 3
+        value : 4
+    }
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 0
+                value : {
+                    className : Object
+                    description : {3 => 4}
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 1
+                    type : number
+                    value : 1
+                }
+                writable : true
+            }
+        ]
+    }
+}
+expression: it = new Map([[1,2],[3,4]]).keys(); it.next(); it
+[
+    [0] : {
+        value : 3
+    }
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 0
+                value : {
+                    className : Object
+                    description : 3
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 1
+                    type : number
+                    value : 1
+                }
+                writable : true
+            }
+        ]
+    }
+}
+expression: it = new Map([[1,2],[3,4]]).values(); it.next(); it
+[
+    [0] : {
+        value : 4
+    }
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 0
+                value : {
+                    className : Object
+                    description : 4
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 1
+                    type : number
+                    value : 1
+                }
+                writable : true
+            }
+        ]
+    }
+}
+expression: it = new Map([[1,2],[3,4]]).entries(); it.next(); it.next(); it
+[
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 0
+                    type : number
+                    value : 0
+                }
+                writable : true
+            }
+        ]
+    }
+}
+
+Running test: sets
+expression: new Set([1,2])
+[
+    [0] : {
+        value : 1
+    }
+    [1] : {
+        value : 2
+    }
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 0
+                value : {
+                    className : Object
+                    description : 1
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 1
+                value : {
+                    className : Object
+                    description : 2
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [2] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 2
+                    type : number
+                    value : 2
+                }
+                writable : true
+            }
+        ]
+    }
+}
+expression: new Set()
+[
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 0
+                    type : number
+                    value : 0
+                }
+                writable : true
+            }
+        ]
+    }
+}
+
+Running test: setIterators
+expression: new Set([1,2]).values()
+[
+    [0] : {
+        value : 1
+    }
+    [1] : {
+        value : 2
+    }
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 0
+                value : {
+                    className : Object
+                    description : 1
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 1
+                value : {
+                    className : Object
+                    description : 2
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [2] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 2
+                    type : number
+                    value : 2
+                }
+                writable : true
+            }
+        ]
+    }
+}
+expression: it = new Set([1,2]).values(); it.next(); it
+[
+    [0] : {
+        value : 2
+    }
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 0
+                value : {
+                    className : Object
+                    description : 2
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 1
+                    type : number
+                    value : 1
+                }
+                writable : true
+            }
+        ]
+    }
+}
+expression: it = new Set([1,2]).keys(); it.next(); it
+[
+    [0] : {
+        value : 2
+    }
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 0
+                value : {
+                    className : Object
+                    description : 2
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 1
+                    type : number
+                    value : 1
+                }
+                writable : true
+            }
+        ]
+    }
+}
+expression: it = new Set([1,2]).entries(); it.next(); it
+[
+    [0] : {
+        value : 2
+    }
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 0
+                value : {
+                    className : Object
+                    description : 2
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 1
+                    type : number
+                    value : 1
+                }
+                writable : true
+            }
+        ]
+    }
+}
+expression: it = new Set([1,2]).values(); it.next(); it.next(); it
+[
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 0
+                    type : number
+                    value : 0
+                }
+                writable : true
+            }
+        ]
+    }
+}
+
+Running test: weakMaps
+expression: new WeakMap()
+[
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 0
+                    type : number
+                    value : 0
+                }
+                writable : true
+            }
+        ]
+    }
+}
+expression: new WeakMap([[{ a: 2 }, 42]])
+[
+    [0] : {
+        key : {
+            a : 2
+        }
+        value : 42
+    }
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 0
+                value : {
+                    className : Object
+                    description : {Object => 42}
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 1
+                    type : number
+                    value : 1
+                }
+                writable : true
+            }
+        ]
+    }
+}
+
+Running test: weakSets
+expression: new WeakSet()
+[
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 0
+                    type : number
+                    value : 0
+                }
+                writable : true
+            }
+        ]
+    }
+}
+expression: new WeakSet([{a:2}])
+[
+    [0] : {
+        value : {
+            a : 2
+        }
+    }
+]
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : 0
+                value : {
+                    className : Object
+                    description : Object
+                    objectId : <objectId>
+                    subtype : internal#entry
+                    type : object
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : false
+                enumerable : false
+                isOwn : true
+                name : length
+                value : {
+                    description : 1
+                    type : number
+                    value : 1
+                }
+                writable : true
+            }
+        ]
+    }
+}
diff --git a/src/v8/test/inspector/runtime/internal-properties-entries.js b/src/v8/test/inspector/runtime/internal-properties-entries.js
new file mode 100644
index 0000000..9555ae5
--- /dev/null
+++ b/src/v8/test/inspector/runtime/internal-properties-entries.js
@@ -0,0 +1,65 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks internal [[Entries]] in Runtime.getProperties output');
+
+Protocol.Runtime.enable();
+
+InspectorTest.runTestSuite([
+  function maps(next) {
+    checkExpression('new Map([[1,2],[3,4]])')
+      .then(() => checkExpression('new Map()'))
+      .then(next);
+  },
+
+  function mapIterators(next) {
+    checkExpression('new Map([[1,2],[3,4]]).entries()')
+      .then(() => checkExpression('it = new Map([[1,2],[3,4]]).entries(); it.next(); it'))
+      .then(() => checkExpression('it = new Map([[1,2],[3,4]]).keys(); it.next(); it'))
+      .then(() => checkExpression('it = new Map([[1,2],[3,4]]).values(); it.next(); it'))
+      .then(() => checkExpression('it = new Map([[1,2],[3,4]]).entries(); it.next(); it.next(); it'))
+      .then(next);
+  },
+
+  function sets(next) {
+    checkExpression('new Set([1,2])')
+      .then(() => checkExpression('new Set()'))
+      .then(next);
+  },
+
+  function setIterators(next) {
+    checkExpression('new Set([1,2]).values()')
+      .then(() => checkExpression('it = new Set([1,2]).values(); it.next(); it'))
+      .then(() => checkExpression('it = new Set([1,2]).keys(); it.next(); it'))
+      .then(() => checkExpression('it = new Set([1,2]).entries(); it.next(); it'))
+      .then(() => checkExpression('it = new Set([1,2]).values(); it.next(); it.next(); it'))
+      .then(next);
+  },
+
+  function weakMaps(next) {
+    checkExpression('new WeakMap()')
+      .then(() => checkExpression('new WeakMap([[{ a: 2 }, 42]])'))
+      .then(next);
+  },
+
+  function weakSets(next) {
+    checkExpression('new WeakSet()')
+      .then(() => checkExpression('new WeakSet([{a:2}])'))
+      .then(next);
+  }
+]);
+
+function checkExpression(expression)
+{
+  InspectorTest.log(`expression: ${expression}`);
+  var entriesObjectId;
+  return Protocol.Runtime.evaluate({ expression: expression })
+    .then(message => Protocol.Runtime.getProperties({ objectId: message.result.result.objectId }))
+    .then(message => message.result.internalProperties.filter(p => p.name === '[[Entries]]')[0])
+    .then(entries => entriesObjectId = entries.value.objectId)
+    .then(() => Protocol.Runtime.callFunctionOn({ objectId: entriesObjectId, functionDeclaration: 'function f() { return this; }', returnByValue: true }))
+    .then(message => InspectorTest.logMessage(message.result.result.value))
+    .then(() => Protocol.Runtime.getProperties({ objectId: entriesObjectId, ownProperties: true }))
+    .then(message => InspectorTest.logMessage(message));
+}
diff --git a/src/v8/test/inspector/runtime/internal-properties-expected.txt b/src/v8/test/inspector/runtime/internal-properties-expected.txt
new file mode 100644
index 0000000..a44c50b
--- /dev/null
+++ b/src/v8/test/inspector/runtime/internal-properties-expected.txt
@@ -0,0 +1,586 @@
+Checks internal properties in Runtime.getProperties output
+
+Running test: generatorFunction
+expression: (function* foo() { yield 1 })
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[FunctionLocation]]
+                value : {
+                    description : Object
+                    subtype : internal#location
+                    type : object
+                    value : {
+                        columnNumber : 14
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                    }
+                }
+            }
+            [1] : {
+                name : [[IsGenerator]]
+                value : {
+                    type : boolean
+                    value : true
+                }
+            }
+            [2] : {
+                name : [[Scopes]]
+                value : {
+                    className : Array
+                    description : Scopes[1]
+                    objectId : <objectId>
+                    subtype : internal#scopeList
+                    type : object
+                }
+            }
+        ]
+    }
+}
+
+Running test: regularFunction
+expression: (function foo() {})
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[FunctionLocation]]
+                value : {
+                    description : Object
+                    subtype : internal#location
+                    type : object
+                    value : {
+                        columnNumber : 13
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                    }
+                }
+            }
+            [1] : {
+                name : [[Scopes]]
+                value : {
+                    className : Array
+                    description : Scopes[1]
+                    objectId : <objectId>
+                    subtype : internal#scopeList
+                    type : object
+                }
+            }
+        ]
+    }
+}
+
+Running test: boxedObjects
+expression: new Number(239)
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[PrimitiveValue]]
+                value : {
+                    description : 239
+                    type : number
+                    value : 239
+                }
+            }
+        ]
+    }
+}
+expression: new Boolean(false)
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[PrimitiveValue]]
+                value : {
+                    type : boolean
+                    value : false
+                }
+            }
+        ]
+    }
+}
+expression: new String('abc')
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[PrimitiveValue]]
+                value : {
+                    type : string
+                    value : abc
+                }
+            }
+        ]
+    }
+}
+expression: Object(Symbol(42))
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[PrimitiveValue]]
+                value : {
+                    description : Symbol(42)
+                    objectId : <objectId>
+                    type : symbol
+                }
+            }
+        ]
+    }
+}
+
+Running test: promise
+expression: Promise.resolve(42)
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[PromiseStatus]]
+                value : {
+                    type : string
+                    value : resolved
+                }
+            }
+            [1] : {
+                name : [[PromiseValue]]
+                value : {
+                    description : 42
+                    type : number
+                    value : 42
+                }
+            }
+        ]
+    }
+}
+expression: new Promise(() => undefined)
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[PromiseStatus]]
+                value : {
+                    type : string
+                    value : pending
+                }
+            }
+            [1] : {
+                name : [[PromiseValue]]
+                value : {
+                    type : undefined
+                }
+            }
+        ]
+    }
+}
+
+Running test: generatorObject
+expression: gen1
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[GeneratorStatus]]
+                value : {
+                    type : string
+                    value : suspended
+                }
+            }
+            [1] : {
+                name : [[GeneratorFunction]]
+                value : {
+                    className : GeneratorFunction
+                    description : function* foo() {   yield 1; }
+                    objectId : <objectId>
+                    type : function
+                }
+            }
+            [2] : {
+                name : [[GeneratorReceiver]]
+                value : {
+                    className : global
+                    description : global
+                    objectId : <objectId>
+                    type : object
+                }
+            }
+            [3] : {
+                name : [[GeneratorLocation]]
+                value : {
+                    description : Object
+                    subtype : internal#location
+                    type : object
+                    value : {
+                        columnNumber : 13
+                        lineNumber : 8
+                        scriptId : <scriptId>
+                    }
+                }
+            }
+            [4] : {
+                name : [[Scopes]]
+                value : {
+                    className : Array
+                    description : Scopes[2]
+                    objectId : <objectId>
+                    subtype : internal#scopeList
+                    type : object
+                }
+            }
+        ]
+    }
+}
+expression: gen1.next();gen1
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[GeneratorStatus]]
+                value : {
+                    type : string
+                    value : suspended
+                }
+            }
+            [1] : {
+                name : [[GeneratorFunction]]
+                value : {
+                    className : GeneratorFunction
+                    description : function* foo() {   yield 1; }
+                    objectId : <objectId>
+                    type : function
+                }
+            }
+            [2] : {
+                name : [[GeneratorReceiver]]
+                value : {
+                    className : global
+                    description : global
+                    objectId : <objectId>
+                    type : object
+                }
+            }
+            [3] : {
+                name : [[GeneratorLocation]]
+                value : {
+                    description : Object
+                    subtype : internal#location
+                    type : object
+                    value : {
+                        columnNumber : 2
+                        lineNumber : 9
+                        scriptId : <scriptId>
+                    }
+                }
+            }
+            [4] : {
+                name : [[Scopes]]
+                value : {
+                    className : Array
+                    description : Scopes[2]
+                    objectId : <objectId>
+                    subtype : internal#scopeList
+                    type : object
+                }
+            }
+        ]
+    }
+}
+expression: gen1.next();gen1
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[GeneratorStatus]]
+                value : {
+                    type : string
+                    value : closed
+                }
+            }
+            [1] : {
+                name : [[GeneratorFunction]]
+                value : {
+                    className : GeneratorFunction
+                    description : function* foo() {   yield 1; }
+                    objectId : <objectId>
+                    type : function
+                }
+            }
+            [2] : {
+                name : [[GeneratorReceiver]]
+                value : {
+                    className : global
+                    description : global
+                    objectId : <objectId>
+                    type : object
+                }
+            }
+            [3] : {
+                name : [[GeneratorLocation]]
+                value : {
+                    description : Object
+                    subtype : internal#location
+                    type : object
+                    value : {
+                        columnNumber : 13
+                        lineNumber : 8
+                        scriptId : <scriptId>
+                    }
+                }
+            }
+        ]
+    }
+}
+
+Running test: generatorObjectDebuggerDisabled
+expression: gen2
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[GeneratorStatus]]
+                value : {
+                    type : string
+                    value : suspended
+                }
+            }
+            [1] : {
+                name : [[GeneratorFunction]]
+                value : {
+                    className : GeneratorFunction
+                    description : function* foo() {   yield 1; }
+                    objectId : <objectId>
+                    type : function
+                }
+            }
+            [2] : {
+                name : [[GeneratorReceiver]]
+                value : {
+                    className : global
+                    description : global
+                    objectId : <objectId>
+                    type : object
+                }
+            }
+            [3] : {
+                name : [[GeneratorLocation]]
+                value : {
+                    description : Object
+                    subtype : internal#location
+                    type : object
+                    value : {
+                        columnNumber : 13
+                        lineNumber : 8
+                        scriptId : <scriptId>
+                    }
+                }
+            }
+            [4] : {
+                name : [[Scopes]]
+                value : {
+                    className : Array
+                    description : Scopes[2]
+                    objectId : <objectId>
+                    subtype : internal#scopeList
+                    type : object
+                }
+            }
+        ]
+    }
+}
+expression: gen2.next();gen2
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[GeneratorStatus]]
+                value : {
+                    type : string
+                    value : suspended
+                }
+            }
+            [1] : {
+                name : [[GeneratorFunction]]
+                value : {
+                    className : GeneratorFunction
+                    description : function* foo() {   yield 1; }
+                    objectId : <objectId>
+                    type : function
+                }
+            }
+            [2] : {
+                name : [[GeneratorReceiver]]
+                value : {
+                    className : global
+                    description : global
+                    objectId : <objectId>
+                    type : object
+                }
+            }
+            [3] : {
+                name : [[GeneratorLocation]]
+                value : {
+                    description : Object
+                    subtype : internal#location
+                    type : object
+                    value : {
+                        columnNumber : 2
+                        lineNumber : 9
+                        scriptId : <scriptId>
+                    }
+                }
+            }
+            [4] : {
+                name : [[Scopes]]
+                value : {
+                    className : Array
+                    description : Scopes[2]
+                    objectId : <objectId>
+                    subtype : internal#scopeList
+                    type : object
+                }
+            }
+        ]
+    }
+}
+expression: gen2.next();gen2
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[GeneratorStatus]]
+                value : {
+                    type : string
+                    value : closed
+                }
+            }
+            [1] : {
+                name : [[GeneratorFunction]]
+                value : {
+                    className : GeneratorFunction
+                    description : function* foo() {   yield 1; }
+                    objectId : <objectId>
+                    type : function
+                }
+            }
+            [2] : {
+                name : [[GeneratorReceiver]]
+                value : {
+                    className : global
+                    description : global
+                    objectId : <objectId>
+                    type : object
+                }
+            }
+            [3] : {
+                name : [[GeneratorLocation]]
+                value : {
+                    description : Object
+                    subtype : internal#location
+                    type : object
+                    value : {
+                        columnNumber : 13
+                        lineNumber : 8
+                        scriptId : <scriptId>
+                    }
+                }
+            }
+        ]
+    }
+}
+
+Running test: iteratorObject
+expression: (new Map([[1,2]])).entries()
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[IteratorHasMore]]
+                value : {
+                    type : boolean
+                    value : true
+                }
+            }
+            [1] : {
+                name : [[IteratorIndex]]
+                value : {
+                    description : 0
+                    type : number
+                    value : 0
+                }
+            }
+            [2] : {
+                name : [[IteratorKind]]
+                value : {
+                    type : string
+                    value : entries
+                }
+            }
+            [3] : {
+                name : [[Entries]]
+                value : {
+                    className : Array
+                    description : Array(1)
+                    objectId : <objectId>
+                    subtype : array
+                    type : object
+                }
+            }
+        ]
+    }
+}
+expression: (new Set([[1,2]])).entries()
+{
+    id : <messageId>
+    result : {
+        internalProperties : [
+            [0] : {
+                name : [[IteratorHasMore]]
+                value : {
+                    type : boolean
+                    value : true
+                }
+            }
+            [1] : {
+                name : [[IteratorIndex]]
+                value : {
+                    description : 0
+                    type : number
+                    value : 0
+                }
+            }
+            [2] : {
+                name : [[IteratorKind]]
+                value : {
+                    type : string
+                    value : entries
+                }
+            }
+            [3] : {
+                name : [[Entries]]
+                value : {
+                    className : Array
+                    description : Array(1)
+                    objectId : <objectId>
+                    subtype : array
+                    type : object
+                }
+            }
+        ]
+    }
+}
diff --git a/src/v8/test/inspector/runtime/internal-properties.js b/src/v8/test/inspector/runtime/internal-properties.js
new file mode 100644
index 0000000..1e42f91
--- /dev/null
+++ b/src/v8/test/inspector/runtime/internal-properties.js
@@ -0,0 +1,70 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks internal properties in Runtime.getProperties output');
+
+contextGroup.addScript(`
+function* foo() {
+  yield 1;
+}
+var gen1 = foo();
+var gen2 = foo();
+//# sourceURL=test.js`, 7, 26);
+
+Protocol.Runtime.enable();
+Protocol.Debugger.enable();
+
+InspectorTest.runTestSuite([
+  function generatorFunction(next) {
+    checkExpression('(function* foo() { yield 1 })').then(next);
+  },
+
+  function regularFunction(next) {
+    checkExpression('(function foo() {})').then(next);
+  },
+
+  function boxedObjects(next) {
+    checkExpression('new Number(239)')
+      .then(() => checkExpression('new Boolean(false)'))
+      .then(() => checkExpression('new String(\'abc\')'))
+      .then(() => checkExpression('Object(Symbol(42))'))
+      .then(next);
+  },
+
+  function promise(next) {
+    checkExpression('Promise.resolve(42)')
+      .then(() => checkExpression('new Promise(() => undefined)'))
+      .then(next);
+  },
+
+  function generatorObject(next) {
+    checkExpression('gen1')
+      .then(() => checkExpression('gen1.next();gen1'))
+      .then(() => checkExpression('gen1.next();gen1'))
+      .then(next);
+  },
+
+  function generatorObjectDebuggerDisabled(next) {
+    Protocol.Debugger.disable()
+      .then(() => checkExpression('gen2'))
+      .then(() => checkExpression('gen2.next();gen2'))
+      .then(() => checkExpression('gen2.next();gen2'))
+      .then(next);
+  },
+
+  function iteratorObject(next) {
+    checkExpression('(new Map([[1,2]])).entries()')
+      .then(() => checkExpression('(new Set([[1,2]])).entries()'))
+      .then(next);
+  }
+]);
+
+function checkExpression(expression)
+{
+  InspectorTest.log(`expression: ${expression}`);
+  return Protocol.Runtime.evaluate({ expression: expression })
+    .then(message => Protocol.Runtime.getProperties({ objectId: message.result.result.objectId }))
+    .then(message => { delete message.result.result; return message; })
+    .then(InspectorTest.logMessage);
+}
diff --git a/src/v8/test/inspector/runtime/length-or-size-description-expected.txt b/src/v8/test/inspector/runtime/length-or-size-description-expected.txt
new file mode 100644
index 0000000..2736966
--- /dev/null
+++ b/src/v8/test/inspector/runtime/length-or-size-description-expected.txt
@@ -0,0 +1,33 @@
+Test that descriptions for arrays, maps, and sets include the correct length or size.
+Set(0)
+Set(2)
+Map(0)
+Map(2)
+Array(0)
+Array(2)
+Uint8Array(0)
+Uint8Array(2)
+ArrayBuffer(0)
+ArrayBuffer(2)
+SharedArrayBuffer(0)
+SharedArrayBuffer(2)
+DataView(0)
+DataView(5)
+WeakMap
+WeakSet
+Set(0)
+Set(2)
+Map(0)
+Map(2)
+Array(0)
+Array(2)
+Uint8Array(0)
+Uint8Array(2)
+ArrayBuffer(0)
+ArrayBuffer(2)
+SharedArrayBuffer(0)
+SharedArrayBuffer(2)
+DataView(0)
+DataView(5)
+WeakMap
+WeakSet
diff --git a/src/v8/test/inspector/runtime/length-or-size-description.js b/src/v8/test/inspector/runtime/length-or-size-description.js
new file mode 100644
index 0000000..8719a26
--- /dev/null
+++ b/src/v8/test/inspector/runtime/length-or-size-description.js
@@ -0,0 +1,36 @@
+// Copyright 2016 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.
+
+// Flags: --harmony-sharedarraybuffer
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Test that descriptions for arrays, maps, and sets include the correct length or size.");
+
+contextGroup.setupInjectedScriptEnvironment();
+
+Promise.all([
+  testExpression("new Set()"),
+  testExpression("new Set([1,2])"),
+  testExpression("new Map()"),
+  testExpression("new Map([[1,2],[3,4]])"),
+  testExpression("new Array()"),
+  testExpression("new Array(2)"),
+  testExpression("new Uint8Array()"),
+  testExpression("new Uint8Array(2)"),
+  testExpression("new ArrayBuffer()"),
+  testExpression("new ArrayBuffer(2)"),
+  testExpression("new SharedArrayBuffer()"),
+  testExpression("new SharedArrayBuffer(2)"),
+  testExpression("new DataView(new ArrayBuffer())"),
+  testExpression("new DataView(new ArrayBuffer(5))"),
+  // WeakMap and WeakSet should not have size in description.
+  testExpression("new WeakMap([[{}, 42]])"),
+  testExpression("new WeakSet([{}])")
+]).then(() => InspectorTest.completeTest());
+
+function testExpression(expression) {
+  return Protocol.Runtime.evaluate({ expression: expression })
+            .then(result => InspectorTest.logMessage(result.result.result.description))
+            .then(() => Protocol.Runtime.evaluate({ expression: "[" + expression + "]", generatePreview: true }))
+            .then(result => InspectorTest.logMessage(result.result.result.preview.properties[0].value))
+}
diff --git a/src/v8/test/inspector/runtime/property-on-console-proto-expected.txt b/src/v8/test/inspector/runtime/property-on-console-proto-expected.txt
new file mode 100644
index 0000000..f64914a
--- /dev/null
+++ b/src/v8/test/inspector/runtime/property-on-console-proto-expected.txt
@@ -0,0 +1,11 @@
+Tests that property defined on console.__proto__ doesn't observable on other Objects.
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 0
+            type : number
+            value : 0
+        }
+    }
+}
diff --git a/src/v8/test/inspector/runtime/property-on-console-proto.js b/src/v8/test/inspector/runtime/property-on-console-proto.js
new file mode 100644
index 0000000..c7ee6c2
--- /dev/null
+++ b/src/v8/test/inspector/runtime/property-on-console-proto.js
@@ -0,0 +1,25 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Tests that property defined on console.__proto__ doesn't observable on other Objects.");
+
+contextGroup.addScript(`
+function testFunction()
+{
+    var amountOfProperties = 0;
+    for (var p in {})
+        ++amountOfProperties;
+    console.__proto__.debug = 239;
+    for (var p in {})
+        --amountOfProperties;
+    return amountOfProperties;
+}`);
+
+Protocol.Runtime.evaluate({ "expression": "testFunction()" }).then(dumpResult);
+
+function dumpResult(result)
+{
+  InspectorTest.logMessage(result);
+  InspectorTest.completeTest();
+}
diff --git a/src/v8/test/inspector/runtime/protocol-works-with-different-locale-expected.txt b/src/v8/test/inspector/runtime/protocol-works-with-different-locale-expected.txt
new file mode 100644
index 0000000..da9eccc
--- /dev/null
+++ b/src/v8/test/inspector/runtime/protocol-works-with-different-locale-expected.txt
@@ -0,0 +1,140 @@
+Tests that protocol works with different locales
+
+Running test: consoleLogWithDefaultLocale
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 239
+                type : number
+                value : 239
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
+
+Running test: consoleTimeWithCommaAsSeparator
+set locale to fr_CA.UTF-8 (has comma as separator)
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : a: 0.001ms
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : timeEnd
+    }
+}
+
+Running test: consoleLogWithCommaAsSeparator
+set locale to fr_CA.UTF-8 (has comma as separator)
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 239
+                type : number
+                value : 239
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
+
+Running test: consoleTimeWithCommaAfterConsoleLog
+set locale to fr_CA.UTF-8 (has comma as separator)
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 239
+                type : number
+                value : 239
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : a: 0.001ms
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : timeEnd
+    }
+}
diff --git a/src/v8/test/inspector/runtime/protocol-works-with-different-locale.js b/src/v8/test/inspector/runtime/protocol-works-with-different-locale.js
new file mode 100644
index 0000000..833b927
--- /dev/null
+++ b/src/v8/test/inspector/runtime/protocol-works-with-different-locale.js
@@ -0,0 +1,42 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Tests that protocol works with different locales');
+
+Protocol.Runtime.enable();
+
+Protocol.Runtime.onConsoleAPICalled(InspectorTest.logMessage);
+
+InspectorTest.runTestSuite([
+  function consoleLogWithDefaultLocale(next) {
+    Protocol.Runtime.evaluate({ expression: "console.log(239) "}).then(next);
+  },
+
+  function consoleTimeWithCommaAsSeparator(next) {
+    InspectorTest.log("set locale to fr_CA.UTF-8 (has comma as separator)");
+    utils.setlocale("fr_CA.UTF-8");
+    utils.setCurrentTimeMSForTest(0.0);
+    Protocol.Runtime.evaluate({ expression: "console.time(\"a\");"})
+      .then(() => utils.setCurrentTimeMSForTest(0.001))
+      .then(() => Protocol.Runtime.evaluate({ expression: "console.timeEnd(\"a\");"}))
+      .then(next);
+  },
+
+  function consoleLogWithCommaAsSeparator(next) {
+    InspectorTest.log("set locale to fr_CA.UTF-8 (has comma as separator)");
+    utils.setlocale("fr_CA.UTF-8");
+    Protocol.Runtime.evaluate({ expression: "console.log(239) "}).then(next);
+  },
+
+  function consoleTimeWithCommaAfterConsoleLog(next) {
+    InspectorTest.log("set locale to fr_CA.UTF-8 (has comma as separator)");
+    utils.setlocale("fr_CA.UTF-8");
+    Protocol.Runtime.evaluate({ expression: "console.log(239) "})
+      .then(() => utils.setCurrentTimeMSForTest(0.0))
+      .then(() => Protocol.Runtime.evaluate({ expression: "console.time(\"a\");"}))
+      .then(() => utils.setCurrentTimeMSForTest(0.001))
+      .then(() => Protocol.Runtime.evaluate({ expression: "console.timeEnd(\"a\");"}))
+      .then(next);
+  }
+]);
diff --git a/src/v8/test/inspector/runtime/query-objects-expected.txt b/src/v8/test/inspector/runtime/query-objects-expected.txt
new file mode 100644
index 0000000..9f365d9
--- /dev/null
+++ b/src/v8/test/inspector/runtime/query-objects-expected.txt
@@ -0,0 +1,96 @@
+Checks Runtime.queryObjects
+
+Running test: testClass
+Declare class Foo & store its constructor.
+Create object with class Foo.
+Query objects with Foo prototype.
+Dump each object constructor name.
+[
+    [0] : Foo,object
+]
+Create object with class Foo.
+Query objects with Foo prototype.
+Dump each object constructor name.
+[
+    [0] : Foo,object
+    [1] : Foo,object
+]
+
+Running test: testDerivedNewClass
+Declare class Foo & store its constructor.
+Declare class Boo extends Foo & store its constructor.
+Query objects with Foo prototype.
+Dump each object constructor name.
+[
+    [0] : Boo,object
+]
+Query objects with Boo prototype.
+Dump each object constructor name.
+[
+]
+Create object with class Foo
+Query objects with Foo prototype.
+Dump each object constructor name.
+[
+    [0] : Boo,object
+    [1] : Foo,object
+]
+Create object with class Boo
+Query objects with Foo prototype.
+Dump each object constructor name.
+[
+    [0] : Boo,object
+    [1] : Boo,object
+    [2] : Foo,object
+]
+Query objects with Boo prototype.
+Dump each object constructor name.
+[
+    [0] : Boo,object
+]
+
+Running test: testNewFunction
+Declare Foo & store it.
+Create object using Foo.
+Query objects with Foo prototype.
+Dump each object constructor name.
+[
+    [0] : Foo,object
+]
+Create object using Foo.
+Query objects with Foo prototype.
+Dump each object constructor name.
+[
+    [0] : Foo,object
+    [1] : Foo,object
+]
+
+Running test: testNonInspectable
+Declare Foo & store it.
+Create object using Foo.
+Query objects with Foo prototype.
+Dump each object constructor name.
+[
+    [0] : Foo,object
+]
+Mark object as not inspectable.
+Query objects with Foo prototype.
+Dump each object constructor name.
+[
+]
+
+Running test: testObjectCreate
+Declare Object p & store it.
+Create object using Object.create(p).
+Query objects with p prototype.
+Dump each object constructor name.
+[
+    [0] : Object,object
+]
+Create object using Object.create(p).
+Query objects with p prototype.
+Dump each object constructor name.
+[
+    [0] : Object,object
+    [1] : Object,object
+]
diff --git a/src/v8/test/inspector/runtime/query-objects.js b/src/v8/test/inspector/runtime/query-objects.js
new file mode 100644
index 0000000..c3b1b2b
--- /dev/null
+++ b/src/v8/test/inspector/runtime/query-objects.js
@@ -0,0 +1,139 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+  InspectorTest.start('Checks Runtime.queryObjects');
+
+InspectorTest.runAsyncTestSuite([
+  async function testClass() {
+    let contextGroup = new InspectorTest.ContextGroup();
+    let session = contextGroup.connect();
+    let Protocol = session.Protocol;
+
+    InspectorTest.log('Declare class Foo & store its constructor.');
+    await Protocol.Runtime.evaluate({
+      expression: 'class Foo{constructor(){}};'
+    });
+    let {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({
+      expression: 'Foo.prototype'
+    });
+
+    for (let i = 0; i < 2; ++i) {
+      InspectorTest.log('Create object with class Foo.');
+      Protocol.Runtime.evaluate({expression: 'new Foo()'});
+      await queryObjects(session, objectId, 'Foo');
+    }
+
+    session.disconnect();
+  },
+
+  async function testDerivedNewClass() {
+    let contextGroup = new InspectorTest.ContextGroup();
+    let session = contextGroup.connect();
+    let Protocol = session.Protocol;
+
+    InspectorTest.log('Declare class Foo & store its constructor.');
+    Protocol.Runtime.evaluate({expression: 'class Foo{};'});
+    let {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({
+      expression: 'Foo.prototype'
+    });
+    let fooConstructorId = objectId;
+
+    InspectorTest.log('Declare class Boo extends Foo & store its constructor.');
+    Protocol.Runtime.evaluate({expression: 'class Boo extends Foo{};'});
+    ({result:{result:{objectId}}} = await Protocol.Runtime.evaluate({
+      expression: 'Boo.prototype'
+    }));
+    let booConstructorId = objectId;
+
+    await queryObjects(session, fooConstructorId, 'Foo');
+    await queryObjects(session, booConstructorId, 'Boo');
+
+    InspectorTest.log('Create object with class Foo');
+    Protocol.Runtime.evaluate({expression: 'new Foo()'});
+    await queryObjects(session, fooConstructorId, 'Foo');
+
+    InspectorTest.log('Create object with class Boo');
+    Protocol.Runtime.evaluate({expression: 'new Boo()'});
+    await queryObjects(session, fooConstructorId, 'Foo');
+    await queryObjects(session, booConstructorId, 'Boo');
+
+    session.disconnect();
+  },
+
+  async function testNewFunction() {
+    let contextGroup = new InspectorTest.ContextGroup();
+    let session = contextGroup.connect();
+    let Protocol = session.Protocol;
+
+    InspectorTest.log('Declare Foo & store it.');
+    Protocol.Runtime.evaluate({expression: 'function Foo(){}'});
+    let {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({
+      expression: 'Foo.prototype'
+    });
+
+    for (let i = 0; i < 2; ++i) {
+      InspectorTest.log('Create object using Foo.');
+      Protocol.Runtime.evaluate({expression: 'new Foo()'});
+      await queryObjects(session, objectId, 'Foo');
+    }
+    session.disconnect();
+  },
+
+  async function testNonInspectable() {
+    let contextGroup = new InspectorTest.ContextGroup();
+    let session = contextGroup.connect();
+    let Protocol = session.Protocol;
+
+    InspectorTest.log('Declare Foo & store it.');
+    Protocol.Runtime.evaluate({expression: 'function Foo(){}'});
+    let {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({
+      expression: 'Foo.prototype'
+    });
+
+    InspectorTest.log('Create object using Foo.');
+    Protocol.Runtime.evaluate({expression: 'a = new Foo()'});
+    await queryObjects(session, objectId, 'Foo');
+    InspectorTest.log('Mark object as not inspectable.')
+    Protocol.Runtime.evaluate({expression: 'inspector.markObjectAsNotInspectable(a)'});
+    await queryObjects(session, objectId, 'Foo');
+    session.disconnect();
+  },
+
+  async function testObjectCreate() {
+    let contextGroup = new InspectorTest.ContextGroup();
+    let session = contextGroup.connect();
+    let Protocol = session.Protocol;
+
+    InspectorTest.log('Declare Object p & store it.');
+    let {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({
+      expression: 'p = {a:1}'
+    });
+    for (let i = 0; i < 2; ++i) {
+      InspectorTest.log('Create object using Object.create(p).');
+      Protocol.Runtime.evaluate({expression: 'Object.create(p)'});
+      await queryObjects(session, objectId, 'p');
+    }
+    session.disconnect();
+  }
+]);
+
+const constructorsNameFunction = `
+function() {
+  return this.map(o => o.constructor.name + ',' + typeof o).sort();
+}`;
+
+async function queryObjects(sesion, prototypeObjectId, name) {
+  let {result:{objects}} = await sesion.Protocol.Runtime.queryObjects({
+    prototypeObjectId
+  });
+  InspectorTest.log(`Query objects with ${name} prototype.`);
+  let {result:{result:{value}}} = await sesion.Protocol.Runtime.callFunctionOn({
+    objectId: objects.objectId,
+    functionDeclaration: constructorsNameFunction,
+    returnByValue: true
+  });
+  InspectorTest.log('Dump each object constructor name.');
+  InspectorTest.logMessage(value);
+}
diff --git a/src/v8/test/inspector/runtime/regression-732717-expected.txt b/src/v8/test/inspector/runtime/regression-732717-expected.txt
new file mode 100644
index 0000000..68ddd76
--- /dev/null
+++ b/src/v8/test/inspector/runtime/regression-732717-expected.txt
@@ -0,0 +1 @@
+Regression test for crbug.com/732717
diff --git a/src/v8/test/inspector/runtime/regression-732717.js b/src/v8/test/inspector/runtime/regression-732717.js
new file mode 100644
index 0000000..f874b2f
--- /dev/null
+++ b/src/v8/test/inspector/runtime/regression-732717.js
@@ -0,0 +1,17 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} =
+    InspectorTest.start('Regression test for crbug.com/732717');
+
+Protocol.Runtime.evaluate({expression: `var v3 = {};
+var v6 = {};
+Array.prototype.__defineGetter__(0, function() {
+  this[0] = 2147483647;
+})
+Array.prototype.__defineSetter__(0, function() {
+console.context(v3);
+this[0] = v6;
+});
+v60 = Array(0x8000).join();`}).then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/runtime/regression-736302-expected.txt b/src/v8/test/inspector/runtime/regression-736302-expected.txt
new file mode 100644
index 0000000..17243f2
--- /dev/null
+++ b/src/v8/test/inspector/runtime/regression-736302-expected.txt
@@ -0,0 +1,82 @@
+crbug.com/736302
+
+Running test: testThrowException
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : 1
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 12
+                    functionName : 
+                    lineNumber : 1
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : count
+    }
+}
+
+Running test: testCustomName
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : [object MyObject]: 1
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 12
+                    functionName : 
+                    lineNumber : 1
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : count
+    }
+}
+
+Running test: testObject
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : [object Object]: 1
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 12
+                    functionName : 
+                    lineNumber : 1
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : count
+    }
+}
diff --git a/src/v8/test/inspector/runtime/regression-736302.js b/src/v8/test/inspector/runtime/regression-736302.js
new file mode 100644
index 0000000..083e34a
--- /dev/null
+++ b/src/v8/test/inspector/runtime/regression-736302.js
@@ -0,0 +1,40 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('crbug.com/736302');
+
+InspectorTest.runAsyncTestSuite([
+  async function testThrowException() {
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: `
+    console.count({
+      get [Symbol.toStringTag]() {
+        throw new Error();
+      }
+    });`});
+    InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+    await Protocol.Runtime.disable();
+  },
+
+  async function testCustomName() {
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: `
+    console.count({
+      get [Symbol.toStringTag]() {
+        return 'MyObject';
+      }
+    });`});
+    InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+    await Protocol.Runtime.disable();
+  },
+
+  async function testObject() {
+    await Protocol.Runtime.enable();
+    Protocol.Runtime.evaluate({expression: `
+    console.count({});`});
+    InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
+    await Protocol.Runtime.disable();
+  }
+
+]);
diff --git a/src/v8/test/inspector/runtime/run-script-async-expected.txt b/src/v8/test/inspector/runtime/run-script-async-expected.txt
new file mode 100644
index 0000000..29b9c52
--- /dev/null
+++ b/src/v8/test/inspector/runtime/run-script-async-expected.txt
@@ -0,0 +1,191 @@
+Tests that Runtime.compileScript and Runtime.runScript work with awaitPromise flag.
+
+Running test: testRunAndCompileWithoutAgentEnable
+{
+    error : {
+        code : -32000
+        message : Runtime agent is not enabled
+    }
+    id : <messageId>
+}
+{
+    error : {
+        code : -32000
+        message : Runtime agent is not enabled
+    }
+    id : <messageId>
+}
+
+Running test: testSyntaxErrorInScript
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 1
+            exception : {
+                className : SyntaxError
+                description : SyntaxError: Unexpected token }
+                objectId : <objectId>
+                subtype : error
+                type : object
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 1
+            scriptId : <scriptId>
+            text : Uncaught
+        }
+    }
+}
+
+Running test: testSyntaxErrorInEvalInScript
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 0
+            exception : {
+                className : SyntaxError
+                description : SyntaxError: Unexpected token }     at boo.js:2:2
+                objectId : <objectId>
+                subtype : error
+                type : object
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 0
+            scriptId : <scriptId>
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 1
+                        functionName : 
+                        lineNumber : 1
+                        scriptId : <scriptId>
+                        url : boo.js
+                    }
+                ]
+            }
+            text : Uncaught
+        }
+        result : {
+            className : SyntaxError
+            description : SyntaxError: Unexpected token }     at boo.js:2:2
+            objectId : <objectId>
+            subtype : error
+            type : object
+        }
+    }
+}
+
+Running test: testRunNotCompiledScript
+{
+    error : {
+        code : -32000
+        message : No script with given id
+    }
+    id : <messageId>
+}
+
+Running test: testRunCompiledScriptAfterAgentWasReenabled
+{
+    error : {
+        code : -32000
+        message : Runtime agent is not enabled
+    }
+    id : <messageId>
+}
+{
+    error : {
+        code : -32000
+        message : No script with given id
+    }
+    id : <messageId>
+}
+
+Running test: testRunScriptWithPreview
+{
+    id : <messageId>
+    result : {
+        result : {
+            className : Object
+            description : Object
+            objectId : <objectId>
+            preview : {
+                description : Object
+                overflow : false
+                properties : [
+                    [0] : {
+                        name : a
+                        type : number
+                        value : 1
+                    }
+                ]
+                type : object
+            }
+            type : object
+        }
+    }
+}
+
+Running test: testRunScriptReturnByValue
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : object
+            value : {
+                a : 1
+            }
+        }
+    }
+}
+
+Running test: testAwaitNotPromise
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : object
+            value : {
+                a : 1
+            }
+        }
+    }
+}
+
+Running test: testAwaitResolvedPromise
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : object
+            value : {
+                a : 1
+            }
+        }
+    }
+}
+
+Running test: testAwaitRejectedPromise
+{
+    id : <messageId>
+    result : {
+        exceptionDetails : {
+            columnNumber : 0
+            exception : {
+                type : object
+                value : {
+                    a : 1
+                }
+            }
+            exceptionId : <exceptionId>
+            lineNumber : 0
+            text : Uncaught (in promise)
+        }
+        result : {
+            type : object
+            value : {
+                a : 1
+            }
+        }
+    }
+}
diff --git a/src/v8/test/inspector/runtime/run-script-async.js b/src/v8/test/inspector/runtime/run-script-async.js
new file mode 100644
index 0000000..7448337
--- /dev/null
+++ b/src/v8/test/inspector/runtime/run-script-async.js
@@ -0,0 +1,110 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Tests that Runtime.compileScript and Runtime.runScript work with awaitPromise flag.");
+
+InspectorTest.runTestSuite([
+  function testRunAndCompileWithoutAgentEnable(next)
+  {
+    Protocol.Runtime.compileScript({ expression: "", sourceURL: "", persistScript: true })
+      .then((result) => InspectorTest.logMessage(result))
+      .then(() => Protocol.Runtime.runScript({ scriptId: "1" }))
+      .then((result) => InspectorTest.logMessage(result))
+      .then(() => next());
+  },
+
+  function testSyntaxErrorInScript(next)
+  {
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: "\n }", sourceURL: "boo.js", persistScript: true }))
+      .then((result) => InspectorTest.logMessage(result))
+      .then(() => Protocol.Runtime.disable())
+      .then(() => next());
+  },
+
+  function testSyntaxErrorInEvalInScript(next)
+  {
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: "{\n eval(\"\\\n}\")\n}", sourceURL: "boo.js", persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId }))
+      .then((result) => InspectorTest.logMessage(result))
+      .then(() => Protocol.Runtime.disable())
+      .then(() => next());
+  },
+
+  function testRunNotCompiledScript(next)
+  {
+    Protocol.Runtime.enable()
+      .then((result) => Protocol.Runtime.runScript({ scriptId: "1" }))
+      .then((result) => InspectorTest.logMessage(result))
+      .then(() => Protocol.Runtime.disable())
+      .then(() => next());
+  },
+
+  function testRunCompiledScriptAfterAgentWasReenabled(next)
+  {
+    var scriptId;
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: "{\n eval(\"\\\n}\")\n}", sourceURL: "boo.js", persistScript: true }))
+      .then((result) => scriptId = result.result.scriptId)
+      .then(() => Protocol.Runtime.disable())
+      .then((result) => Protocol.Runtime.runScript({ scriptId: scriptId }))
+      .then((result) => InspectorTest.logMessage(result))
+      .then(() => Protocol.Runtime.enable())
+      .then((result) => Protocol.Runtime.runScript({ scriptId: scriptId }))
+      .then((result) => InspectorTest.logMessage(result))
+      .then(() => Protocol.Runtime.disable())
+      .then(() => next());
+  },
+
+  function testRunScriptWithPreview(next)
+  {
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: "({a:1})", sourceURL: "boo.js", persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId, generatePreview: true }))
+      .then((result) => InspectorTest.logMessage(result))
+      .then(() => Protocol.Runtime.disable())
+      .then(() => next());
+  },
+
+  function testRunScriptReturnByValue(next)
+  {
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: "({a:1})", sourceURL: "boo.js", persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId, returnByValue: true }))
+      .then((result) => InspectorTest.logMessage(result))
+      .then(() => Protocol.Runtime.disable())
+      .then(() => next());
+  },
+
+  function testAwaitNotPromise(next)
+  {
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: "({a:1})", sourceURL: "boo.js", persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId, awaitPromise: true, returnByValue: true }))
+      .then((result) => InspectorTest.logMessage(result))
+      .then(() => Protocol.Runtime.disable())
+      .then(() => next());
+  },
+
+  function testAwaitResolvedPromise(next)
+  {
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: "Promise.resolve({a:1})", sourceURL: "boo.js", persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId, awaitPromise: true, returnByValue: true }))
+      .then((result) => InspectorTest.logMessage(result))
+      .then(() => Protocol.Runtime.disable())
+      .then(() => next());
+  },
+
+  function testAwaitRejectedPromise(next)
+  {
+    Protocol.Runtime.enable()
+      .then(() => Protocol.Runtime.compileScript({ expression: "Promise.reject({a:1})", sourceURL: "boo.js", persistScript: true }))
+      .then((result) => Protocol.Runtime.runScript({ scriptId: result.result.scriptId, awaitPromise: true, returnByValue: true }))
+      .then((result) => InspectorTest.logMessage(result))
+      .then(() => Protocol.Runtime.disable())
+      .then(() => next());
+  }
+]);
diff --git a/src/v8/test/inspector/runtime/runtime-disable-preserve-injected-script-expected.txt b/src/v8/test/inspector/runtime/runtime-disable-preserve-injected-script-expected.txt
new file mode 100644
index 0000000..f0d715c
--- /dev/null
+++ b/src/v8/test/inspector/runtime/runtime-disable-preserve-injected-script-expected.txt
@@ -0,0 +1,26 @@
+Tests that Runtime.disable doesn't invalidate injected-script.
+{
+    configurable : true
+    enumerable : true
+    isOwn : true
+    name : a
+    value : {
+        description : 1
+        type : number
+        value : 1
+    }
+    writable : true
+}
+Disabling agent..
+{
+    configurable : true
+    enumerable : true
+    isOwn : true
+    name : a
+    value : {
+        description : 1
+        type : number
+        value : 1
+    }
+    writable : true
+}
diff --git a/src/v8/test/inspector/runtime/runtime-disable-preserve-injected-script.js b/src/v8/test/inspector/runtime/runtime-disable-preserve-injected-script.js
new file mode 100644
index 0000000..0bf97f7
--- /dev/null
+++ b/src/v8/test/inspector/runtime/runtime-disable-preserve-injected-script.js
@@ -0,0 +1,25 @@
+// Copyright 2017 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.
+
+(async function test() {
+  let {session, contextGroup, Protocol} =
+      InspectorTest.start(
+          "Tests that Runtime.disable doesn't invalidate injected-script.");
+  Protocol.Runtime.enable();
+  let {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({
+    expression: "({a:1})"
+  });
+  var {result:{result}} = await Protocol.Runtime.getProperties({objectId});
+  InspectorTest.logMessage(result.find(property => property.name === 'a'));
+  InspectorTest.log('Disabling agent..');
+  await Protocol.Runtime.disable();
+  var result = await Protocol.Runtime.getProperties({objectId});
+  if (result.error) {
+    InspectorTest.logMessage(result);
+  } else {
+    var props = result.result.result;
+    InspectorTest.logMessage(props.find(property => property.name === 'a'));
+  }
+  InspectorTest.completeTest();
+})()
diff --git a/src/v8/test/inspector/runtime/runtime-evaluate-with-dirty-context-expected.txt b/src/v8/test/inspector/runtime/runtime-evaluate-with-dirty-context-expected.txt
new file mode 100644
index 0000000..65dfc1b
--- /dev/null
+++ b/src/v8/test/inspector/runtime/runtime-evaluate-with-dirty-context-expected.txt
@@ -0,0 +1,35 @@
+Checks that Runtime.evaluate works with dirty context.
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 42
+                type : number
+                value : 42
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
diff --git a/src/v8/test/inspector/runtime/runtime-evaluate-with-dirty-context.js b/src/v8/test/inspector/runtime/runtime-evaluate-with-dirty-context.js
new file mode 100644
index 0000000..5f42d49
--- /dev/null
+++ b/src/v8/test/inspector/runtime/runtime-evaluate-with-dirty-context.js
@@ -0,0 +1,11 @@
+// Copyright 2017 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that Runtime.evaluate works with dirty context.');
+contextGroup.setupInjectedScriptEnvironment();
+Protocol.Runtime.enable();
+Protocol.Runtime.onConsoleAPICalled(InspectorTest.logMessage);
+Protocol.Runtime.evaluate({expression: 'console.log(42)'})
+  .then(InspectorTest.logMessage)
+  .then(InspectorTest.completeTest);
diff --git a/src/v8/test/inspector/runtime/runtime-restore-expected.txt b/src/v8/test/inspector/runtime/runtime-restore-expected.txt
new file mode 100644
index 0000000..d95051b
--- /dev/null
+++ b/src/v8/test/inspector/runtime/runtime-restore-expected.txt
@@ -0,0 +1,115 @@
+Checks that Runtime agent correctly restore its state.
+
+Running test: testExecutionContextsNotificationsOnRestore
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 1
+            name : 
+            origin : 
+        }
+    }
+}
+will reconnect..
+{
+    method : Runtime.executionContextsCleared
+    params : {
+    }
+}
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 1
+            name : 
+            origin : 
+        }
+    }
+}
+
+Running test: testConsoleAPICalledAfterRestore
+will reconnect..
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 42
+                type : number
+                value : 42
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
+
+Running test: testSetCustomObjectFormatterEnabled
+will reconnect..
+will reconnect..
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                className : Object
+                customPreview : {
+                    bindRemoteObjectFunctionId : <bindRemoteObjectFunctionId>
+                    formatterObjectId : <formatterObjectId>
+                    hasBody : true
+                    header : ["span",{},"Header formatted ",42]
+                }
+                description : Object
+                objectId : <objectId>
+                preview : {
+                    description : Object
+                    overflow : false
+                    properties : [
+                        [0] : {
+                            name : name
+                            type : number
+                            value : 42
+                        }
+                    ]
+                    type : object
+                }
+                type : object
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
diff --git a/src/v8/test/inspector/runtime/runtime-restore.js b/src/v8/test/inspector/runtime/runtime-restore.js
new file mode 100644
index 0000000..09e4467
--- /dev/null
+++ b/src/v8/test/inspector/runtime/runtime-restore.js
@@ -0,0 +1,77 @@
+// Copyright 2017 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.v8
+
+let {session, contextGroup, Protocol} = InspectorTest.start('Checks that Runtime agent correctly restore its state.');
+
+contextGroup.addScript(`
+var formatter = {
+    header: function(x)
+    {
+        return ["span", {}, "Header formatted ", x.name];
+    },
+
+    hasBody: function(x)
+    {
+        return true;
+    },
+
+    body: function(x)
+    {
+        return ["span", {}, "Body formatted ", x.name]
+    }
+};
+
+devtoolsFormatters = [ formatter ];
+
+//# sourceURL=test.js`)
+
+InspectorTest.runTestSuite([
+  function testExecutionContextsNotificationsOnRestore(next) {
+    Protocol.Runtime.onExecutionContextsCleared(InspectorTest.logMessage);
+    Protocol.Runtime.onExecutionContextCreated(InspectorTest.logMessage);
+    Protocol.Runtime.onExecutionContextDestroyed(InspectorTest.logMessage);
+    Protocol.Runtime.enable()
+      .then(reconnect)
+      .then(Protocol.Runtime.disable)
+      .then(() => {
+        Protocol.Runtime.onExecutionContextsCleared(null);
+        Protocol.Runtime.onExecutionContextCreated(null);
+        Protocol.Runtime.onExecutionContextDestroyed(null);
+        next()
+      });
+  },
+
+  function testConsoleAPICalledAfterRestore(next) {
+    Protocol.Runtime.onConsoleAPICalled(InspectorTest.logMessage);
+    Protocol.Runtime.enable()
+      .then(reconnect)
+      .then(() => Protocol.Runtime.evaluate({ expression: 'console.log(42);' }))
+      .then(Protocol.Runtime.disable)
+      .then(() => {
+        Protocol.Runtime.onConsoleAPICalled(null);
+        next();
+      });
+  },
+
+  function testSetCustomObjectFormatterEnabled(next) {
+    Protocol.Runtime.onConsoleAPICalled(InspectorTest.logMessage);
+    Protocol.Runtime.discardConsoleEntries()
+      .then(reconnect)
+      .then(() => Protocol.Runtime.enable())
+      .then(() => Protocol.Runtime.setCustomObjectFormatterEnabled({ enabled: true }))
+      .then(reconnect)
+      .then(() => Protocol.Runtime.evaluate({ expression: 'console.log({ name: 42 })'}))
+      .then(InspectorTest.logMessage)
+      .then(Protocol.Runtime.disable)
+      .then(() => {
+        Protocol.Runtime.onConsoleAPICalled(null);
+        next();
+      });
+  },
+]);
+
+function reconnect() {
+  InspectorTest.logMessage('will reconnect..');
+  session.reconnect();
+}
diff --git a/src/v8/test/inspector/runtime/set-or-map-entries-expected.txt b/src/v8/test/inspector/runtime/set-or-map-entries-expected.txt
new file mode 100644
index 0000000..edaee51
--- /dev/null
+++ b/src/v8/test/inspector/runtime/set-or-map-entries-expected.txt
@@ -0,0 +1,9 @@
+Test that Runtime.getProperties doesn't truncate set and map entries in internalProperties.
+Entries for "createSet(10)"
+Array(10)
+Entries for "createSet(1000)"
+Array(1000)
+Entries for "createMap(10)"
+Array(10)
+Entries for "createMap(1000)"
+Array(1000)
diff --git a/src/v8/test/inspector/runtime/set-or-map-entries.js b/src/v8/test/inspector/runtime/set-or-map-entries.js
new file mode 100644
index 0000000..4206c87
--- /dev/null
+++ b/src/v8/test/inspector/runtime/set-or-map-entries.js
@@ -0,0 +1,54 @@
+// Copyright 2016 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.
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Test that Runtime.getProperties doesn't truncate set and map entries in internalProperties.")
+
+contextGroup.addScript(`
+  function createSet(size) {
+    var s = new Set();
+    var a = {};
+    a.a = a;
+    for (var i = 0; i < size; ++i) s.add({ wrapper: a});
+    return s;
+  }
+
+  function createMap(size) {
+    var m = new Map();
+    var a = {};
+    a.a = a;
+    for (var i = 0; i < size; ++i) m.set(i, { wrapper: a});
+    return m;
+  }
+`);
+
+contextGroup.setupInjectedScriptEnvironment();
+
+Protocol.Debugger.enable();
+Protocol.Runtime.enable();
+
+testExpression("createSet(10)")
+  .then(() => testExpression("createSet(1000)"))
+  .then(() => testExpression("createMap(10)"))
+  .then(() => testExpression("createMap(1000)"))
+  .then(() => InspectorTest.completeTest());
+
+function testExpression(expression)
+{
+  return Protocol.Runtime.evaluate({ "expression": expression})
+           .then(result => Protocol.Runtime.getProperties({ ownProperties: true, objectId: result.result.result.objectId }))
+           .then(message => dumpEntriesDescription(expression, message));
+}
+
+function dumpEntriesDescription(expression, message)
+{
+  InspectorTest.log(`Entries for "${expression}"`);
+  var properties = message.result.internalProperties;
+  var property;
+  if (properties)
+    property = properties.find(property => property.name === "[[Entries]]");
+  if (!property)
+    InspectorTest.log("[[Entries]] not found");
+  else
+    InspectorTest.log(property.value.description);
+}
diff --git a/src/v8/test/inspector/sessions/create-session-expected.txt b/src/v8/test/inspector/sessions/create-session-expected.txt
new file mode 100644
index 0000000..e3d921e
--- /dev/null
+++ b/src/v8/test/inspector/sessions/create-session-expected.txt
@@ -0,0 +1,132 @@
+Tests that creating multiple sessions works.
+Connecting session 1
+From session 1
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 1
+            name : 
+            origin : 
+        }
+    }
+}
+Connecting session 2
+From session 2
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 1
+            name : 
+            origin : 
+        }
+    }
+}
+Reconnecting session 2
+From session 2
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 1
+            name : 
+            origin : 
+        }
+    }
+}
+Reconnecting session 1
+From session 1
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 1
+            name : 
+            origin : 
+        }
+    }
+}
+Connecting session 3
+From session 3
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 1
+            name : 
+            origin : 
+        }
+    }
+}
+Destroying and creating context
+From session 2
+{
+    method : Runtime.executionContextDestroyed
+    params : {
+        executionContextId : <executionContextId>
+    }
+}
+id matching: true
+From session 1
+{
+    method : Runtime.executionContextDestroyed
+    params : {
+        executionContextId : <executionContextId>
+    }
+}
+id matching: true
+From session 3
+{
+    method : Runtime.executionContextDestroyed
+    params : {
+        executionContextId : <executionContextId>
+    }
+}
+id matching: true
+From session 2
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 2
+            name : 
+            origin : 
+        }
+    }
+}
+From session 1
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 2
+            name : 
+            origin : 
+        }
+    }
+}
+From session 3
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 2
+            name : 
+            origin : 
+        }
+    }
+}
+Disconnecting all sessions
+Connecting session 4
+From session 4
+{
+    method : Runtime.executionContextCreated
+    params : {
+        context : {
+            id : 2
+            name : 
+            origin : 
+        }
+    }
+}
diff --git a/src/v8/test/inspector/sessions/create-session.js b/src/v8/test/inspector/sessions/create-session.js
new file mode 100644
index 0000000..1163583
--- /dev/null
+++ b/src/v8/test/inspector/sessions/create-session.js
@@ -0,0 +1,58 @@
+// Copyright 2017 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.
+
+InspectorTest.log('Tests that creating multiple sessions works.');
+
+function connect(contextGroup, num) {
+  var session = contextGroup.connect();
+  var executionContextId;
+  session.Protocol.Runtime.onExecutionContextCreated(message => {
+    InspectorTest.log('From session ' + num);
+    InspectorTest.logMessage(message);
+    executionContextId = message.params.context.id;
+  });
+  session.Protocol.Runtime.onExecutionContextDestroyed(message => {
+    InspectorTest.log('From session ' + num);
+    InspectorTest.logMessage(message);
+    InspectorTest.log('id matching: ' + (message.params.executionContextId === executionContextId));
+  });
+  return session;
+}
+
+(async function test() {
+  var contextGroup = new InspectorTest.ContextGroup();
+  InspectorTest.log('Connecting session 1');
+  var session1 = connect(contextGroup, 1);
+  await session1.Protocol.Runtime.enable();
+
+  InspectorTest.log('Connecting session 2');
+  var session2 = connect(contextGroup, 2);
+  await session2.Protocol.Runtime.enable();
+
+  InspectorTest.log('Reconnecting session 2');
+  session2.reconnect();
+  await session2.Protocol.Runtime.enable();
+
+  InspectorTest.log('Reconnecting session 1');
+  session1.reconnect();
+  await session1.Protocol.Runtime.enable();
+
+  InspectorTest.log('Connecting session 3');
+  var session3 = connect(contextGroup, 3);
+  await session3.Protocol.Runtime.enable();
+
+  InspectorTest.log('Destroying and creating context');
+  await session2.Protocol.Runtime.evaluate({expression: 'inspector.fireContextDestroyed(); inspector.fireContextCreated(); '});
+
+  InspectorTest.log('Disconnecting all sessions');
+  session1.disconnect();
+  session2.disconnect();
+  session3.disconnect();
+
+  InspectorTest.log('Connecting session 4');
+  var session4 = connect(contextGroup, 4);
+  await session4.Protocol.Runtime.enable();
+
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/sessions/debugger-stepping-and-breakpoints-expected.txt b/src/v8/test/inspector/sessions/debugger-stepping-and-breakpoints-expected.txt
new file mode 100644
index 0000000..2b7cc16
--- /dev/null
+++ b/src/v8/test/inspector/sessions/debugger-stepping-and-breakpoints-expected.txt
@@ -0,0 +1,228 @@
+Tests how multiple sessions interact while pausing, stepping, setting breakpoints and blackboxing.
+Connecting session 1
+Pausing in 1
+Paused in 1:
+  reason: other
+  hit breakpoints: 
+  location: <anonymous>@0
+  data: null
+Connecting session 2
+Paused in 2:
+  reason: other
+  hit breakpoints: 
+  location: <anonymous>@0
+  data: null
+Resuming in 2
+Resumed in 1
+Resumed in 2
+Setting breakpoints in 1
+Setting breakpoints in 2
+Evaluating common breakpoint in 1
+Paused in 1:
+  reason: other
+  hit breakpoints: test.js:11:0
+  location: foo@11
+  data: null
+Paused in 2:
+  reason: other
+  hit breakpoints: test.js:11:0
+  location: foo@11
+  data: null
+Resuming in 1
+Resumed in 1
+Resumed in 2
+Evaluating debugger in 1
+Paused in 1:
+  reason: other
+  hit breakpoints: 
+  location: bar@25
+  data: null
+Paused in 2:
+  reason: other
+  hit breakpoints: 
+  location: bar@25
+  data: null
+Resuming in 2
+Resumed in 1
+Resumed in 2
+Evaluating exclusive breakpoint in 1
+Paused in 1:
+  reason: other
+  hit breakpoints: test.js:14:0
+  location: baz@14
+  data: null
+Paused in 2:
+  reason: other
+  hit breakpoints: 
+  location: baz@14
+  data: null
+Resuming in 1
+Resumed in 1
+Resumed in 2
+Evaluating common breakpoint in 2
+Paused in 1:
+  reason: other
+  hit breakpoints: test.js:11:0
+  location: foo@11
+  data: null
+Paused in 2:
+  reason: other
+  hit breakpoints: test.js:11:0
+  location: foo@11
+  data: null
+Resuming in 2
+Resumed in 1
+Resumed in 2
+Evaluating debugger in 2
+Paused in 1:
+  reason: other
+  hit breakpoints: 
+  location: bar@25
+  data: null
+Paused in 2:
+  reason: other
+  hit breakpoints: 
+  location: bar@25
+  data: null
+Resuming in 2
+Resumed in 1
+Resumed in 2
+Evaluating exclusive breakpoint in 2
+Paused in 1:
+  reason: other
+  hit breakpoints: test.js:14:0
+  location: baz@14
+  data: null
+Paused in 2:
+  reason: other
+  hit breakpoints: 
+  location: baz@14
+  data: null
+Resuming in 1
+Resumed in 1
+Resumed in 2
+Evaluating stepping in 1
+Paused in 1:
+  reason: other
+  hit breakpoints: 
+  location: stepping@17
+  data: null
+Paused in 2:
+  reason: other
+  hit breakpoints: 
+  location: stepping@17
+  data: null
+Stepping into in 2
+Resumed in 1
+Resumed in 2
+Paused in 1:
+  reason: other
+  hit breakpoints: 
+  location: stepping@18
+  data: null
+Paused in 2:
+  reason: other
+  hit breakpoints: 
+  location: stepping@18
+  data: null
+Stepping over in 1
+Resumed in 1
+Resumed in 2
+Paused in 1:
+  reason: other
+  hit breakpoints: 
+  location: stepping@19
+  data: null
+Paused in 2:
+  reason: other
+  hit breakpoints: 
+  location: stepping@19
+  data: null
+Stepping out in 2
+Resumed in 1
+Resumed in 2
+Paused in 1:
+  reason: other
+  hit breakpoints: 
+  location: <anonymous>@0
+  data: null
+Paused in 2:
+  reason: other
+  hit breakpoints: 
+  location: <anonymous>@0
+  data: null
+Resuming in 1
+Resumed in 1
+Resumed in 2
+Pausing in next statement
+Paused in 1:
+  reason: some-reason
+  hit breakpoints: 
+  location: <anonymous>@0
+  data: {"a":42}
+Paused in 2:
+  reason: some-reason
+  hit breakpoints: 
+  location: <anonymous>@0
+  data: {"a":42}
+Resuming in 1
+Resumed in 1
+Resumed in 2
+Pausing in next statement
+Paused in 1:
+  reason: some-reason
+  hit breakpoints: 
+  location: <anonymous>@0
+  data: {"a":42}
+Paused in 2:
+  reason: some-reason
+  hit breakpoints: 
+  location: <anonymous>@0
+  data: {"a":42}
+Resuming in 2
+Resumed in 1
+Resumed in 2
+Blackboxing bar() in 2
+Evaluating bar() in 2
+Paused in 1:
+  reason: other
+  hit breakpoints: 
+  location: bar@25
+  data: null
+Resuming in 1
+Resumed in 1
+Blackboxing bar() in 1
+Evaluating bar() in 2
+Skipping pauses in 1
+Evaluating common breakpoint in 1
+Paused in 2:
+  reason: other
+  hit breakpoints: test.js:11:0
+  location: foo@11
+  data: null
+Resuming in 2
+Resumed in 2
+Skipping pauses in 2
+Evaluating common breakpoint in 1
+Unskipping pauses in 1
+Unskipping pauses in 2
+Deactivating breakpoints in 1
+Evaluating common breakpoint in 1
+Paused in 2:
+  reason: other
+  hit breakpoints: test.js:11:0
+  location: foo@11
+  data: null
+Resuming in 2
+Resumed in 2
+Deactivating breakpoints in 2
+Evaluating common breakpoint in 1
+Activating breakpoints in 1
+Activating breakpoints in 2
+Disabling debugger agent in 1
+Evaluating breakpoint in 1 (should not be triggered)
+Paused in 2:
+  reason: other
+  hit breakpoints: 
+  location: <anonymous>@1
+  data: null
diff --git a/src/v8/test/inspector/sessions/debugger-stepping-and-breakpoints.js b/src/v8/test/inspector/sessions/debugger-stepping-and-breakpoints.js
new file mode 100644
index 0000000..b6ca626
--- /dev/null
+++ b/src/v8/test/inspector/sessions/debugger-stepping-and-breakpoints.js
@@ -0,0 +1,211 @@
+// Copyright 2017 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.
+
+InspectorTest.log('Tests how multiple sessions interact while pausing, stepping, setting breakpoints and blackboxing.');
+
+var contextGroup = new InspectorTest.ContextGroup();
+
+contextGroup.addScript(`
+function foo() {
+  return 1;
+}
+function baz() {
+  return 2;
+}
+function stepping() {
+  debugger;
+  var a = 1;
+  var b = 1;
+}
+//# sourceURL=test.js`, 9, 25);
+
+contextGroup.addScript(`
+function bar() {
+  debugger;
+}
+//# sourceURL=test2.js`, 23, 25);
+
+(async function test() {
+  InspectorTest.log('Connecting session 1');
+  var session1 = contextGroup.connect();
+  await session1.Protocol.Debugger.enable();
+  InspectorTest.log('Pausing in 1');
+  session1.Protocol.Runtime.evaluate({expression: 'debugger;'});
+  await waitForPaused(session1, 1);
+  InspectorTest.log('Connecting session 2');
+  var session2 = contextGroup.connect();
+  var enabledPromise = session2.Protocol.Debugger.enable();
+  await waitForPaused(session2, 2);
+  await enabledPromise;
+  InspectorTest.log('Resuming in 2');
+  session2.Protocol.Debugger.resume();
+  await waitForBothResumed();
+
+  InspectorTest.log('Setting breakpoints in 1');
+  await session1.Protocol.Debugger.setBreakpointByUrl({url: 'test.js', lineNumber: 11});
+  await session1.Protocol.Debugger.setBreakpointByUrl({url: 'test.js', lineNumber: 14});
+  InspectorTest.log('Setting breakpoints in 2');
+  await session2.Protocol.Debugger.setBreakpointByUrl({url: 'test.js', lineNumber: 11});
+
+  InspectorTest.log('Evaluating common breakpoint in 1');
+  session1.Protocol.Runtime.evaluate({expression: 'foo();'});
+  await waitForBothPaused();
+  InspectorTest.log('Resuming in 1');
+  session1.Protocol.Debugger.resume();
+  await waitForBothResumed();
+
+  InspectorTest.log('Evaluating debugger in 1');
+  session1.Protocol.Runtime.evaluate({expression: 'bar();'});
+  await waitForBothPaused();
+  InspectorTest.log('Resuming in 2');
+  session2.Protocol.Debugger.resume();
+  await waitForBothResumed();
+
+  InspectorTest.log('Evaluating exclusive breakpoint in 1');
+  session1.Protocol.Runtime.evaluate({expression: 'baz();'});
+  await waitForBothPaused();
+  InspectorTest.log('Resuming in 1');
+  session1.Protocol.Debugger.resume();
+  await waitForBothResumed();
+
+  InspectorTest.log('Evaluating common breakpoint in 2');
+  session2.Protocol.Runtime.evaluate({expression: 'foo();'});
+  await waitForBothPaused();
+  InspectorTest.log('Resuming in 2');
+  session2.Protocol.Debugger.resume();
+  await waitForBothResumed();
+
+  InspectorTest.log('Evaluating debugger in 2');
+  session2.Protocol.Runtime.evaluate({expression: 'bar();'});
+  await waitForBothPaused();
+  InspectorTest.log('Resuming in 2');
+  session2.Protocol.Debugger.resume();
+  await waitForBothResumed();
+
+  InspectorTest.log('Evaluating exclusive breakpoint in 2');
+  session2.Protocol.Runtime.evaluate({expression: 'baz();'});
+  await waitForBothPaused();
+  InspectorTest.log('Resuming in 1');
+  session1.Protocol.Debugger.resume();
+  await waitForBothResumed();
+
+  InspectorTest.log('Evaluating stepping in 1');
+  session1.Protocol.Runtime.evaluate({expression: 'stepping();'});
+  await waitForBothPaused();
+  InspectorTest.log('Stepping into in 2');
+  session2.Protocol.Debugger.stepInto();
+  await waitForBothResumed();
+  await waitForBothPaused();
+  InspectorTest.log('Stepping over in 1');
+  session1.Protocol.Debugger.stepOver();
+  await waitForBothResumed();
+  await waitForBothPaused();
+  InspectorTest.log('Stepping out in 2');
+  session2.Protocol.Debugger.stepOut();
+  await waitForBothResumed();
+  await waitForBothPaused();
+  InspectorTest.log('Resuming in 1');
+  session1.Protocol.Debugger.resume();
+  await waitForBothResumed();
+
+  InspectorTest.log('Pausing in next statement');
+  contextGroup.schedulePauseOnNextStatement('some-reason', JSON.stringify({a: 42}));
+  session2.Protocol.Runtime.evaluate({expression: 'var a = 1;'});
+  await waitForBothPaused();
+  InspectorTest.log('Resuming in 1');
+  session1.Protocol.Debugger.resume();
+  await waitForBothResumed();
+
+  InspectorTest.log('Pausing in next statement');
+  contextGroup.schedulePauseOnNextStatement('some-reason', JSON.stringify({a: 42}));
+  session2.Protocol.Runtime.evaluate({expression: 'var a = 1;'});
+  await waitForBothPaused();
+  InspectorTest.log('Resuming in 2');
+  session2.Protocol.Debugger.resume();
+  await waitForBothResumed();
+
+  InspectorTest.log('Blackboxing bar() in 2');
+  await session2.Protocol.Debugger.setBlackboxPatterns({patterns: ['test2.js']});
+  InspectorTest.log('Evaluating bar() in 2');
+  session2.Protocol.Runtime.evaluate({expression: 'bar();'});
+  await waitForPaused(session1, 1);
+  InspectorTest.log('Resuming in 1');
+  session1.Protocol.Debugger.resume();
+  await waitForResumed(session1, 1);
+
+  InspectorTest.log('Blackboxing bar() in 1');
+  await session1.Protocol.Debugger.setBlackboxPatterns({patterns: ['test2.js']});
+  InspectorTest.log('Evaluating bar() in 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'bar();'});
+
+  InspectorTest.log('Skipping pauses in 1');
+  await session1.Protocol.Debugger.setSkipAllPauses({skip: true});
+  InspectorTest.log('Evaluating common breakpoint in 1');
+  session1.Protocol.Runtime.evaluate({expression: 'foo();'});
+  await waitForPaused(session2, 2);
+  InspectorTest.log('Resuming in 2');
+  session2.Protocol.Debugger.resume();
+  await waitForResumed(session2, 2);
+
+  InspectorTest.log('Skipping pauses in 2');
+  await session2.Protocol.Debugger.setSkipAllPauses({skip: true});
+  InspectorTest.log('Evaluating common breakpoint in 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'foo();'});
+
+  InspectorTest.log('Unskipping pauses in 1');
+  await session1.Protocol.Debugger.setSkipAllPauses({skip: false});
+  InspectorTest.log('Unskipping pauses in 2');
+  await session2.Protocol.Debugger.setSkipAllPauses({skip: false});
+
+  InspectorTest.log('Deactivating breakpoints in 1');
+  await session1.Protocol.Debugger.setBreakpointsActive({active: false});
+  InspectorTest.log('Evaluating common breakpoint in 1');
+  session1.Protocol.Runtime.evaluate({expression: 'foo();'});
+  await waitForPaused(session2, 2);
+  InspectorTest.log('Resuming in 2');
+  session2.Protocol.Debugger.resume();
+  await waitForResumed(session2, 2);
+
+  InspectorTest.log('Deactivating breakpoints in 2');
+  await session2.Protocol.Debugger.setBreakpointsActive({active: false});
+  InspectorTest.log('Evaluating common breakpoint in 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'foo();'});
+
+  InspectorTest.log('Activating breakpoints in 1');
+  await session1.Protocol.Debugger.setBreakpointsActive({active: true});
+  InspectorTest.log('Activating breakpoints in 2');
+  await session2.Protocol.Debugger.setBreakpointsActive({active: true});
+  InspectorTest.log('Disabling debugger agent in 1');
+  await session1.Protocol.Debugger.disable();
+  InspectorTest.log('Evaluating breakpoint in 1 (should not be triggered)');
+  session2.Protocol.Runtime.evaluate({expression: 'baz();\ndebugger;'});
+  await waitForPaused(session2, 2);
+
+  InspectorTest.completeTest();
+
+  function waitForBothPaused() {
+    return Promise.all([waitForPaused(session1, 1), waitForPaused(session2, 2)]);
+  }
+
+  function waitForBothResumed() {
+    return Promise.all([waitForResumed(session1, 1), waitForResumed(session2, 2)]);
+  }
+})();
+
+function waitForPaused(session, num) {
+  return session.Protocol.Debugger.oncePaused().then(message => {
+    InspectorTest.log(`Paused in ${num}:`);
+    InspectorTest.log(`  reason: ${message.params.reason}`);
+    InspectorTest.log(`  hit breakpoints: ${(message.params.hitBreakpoints || []).join(';')}`);
+    var callFrame = message.params.callFrames[0];
+    InspectorTest.log(`  location: ${callFrame.functionName || '<anonymous>'}@${callFrame.location.lineNumber}`);
+    InspectorTest.log(`  data: ${JSON.stringify(message.params.data || null)}`);
+  });
+}
+
+function waitForResumed(session, num) {
+  return session.Protocol.Debugger.onceResumed().then(message => {
+    InspectorTest.log(`Resumed in ${num}`);
+  });
+}
diff --git a/src/v8/test/inspector/sessions/pause-on-console-assert-expected.txt b/src/v8/test/inspector/sessions/pause-on-console-assert-expected.txt
new file mode 100644
index 0000000..7b59002
--- /dev/null
+++ b/src/v8/test/inspector/sessions/pause-on-console-assert-expected.txt
@@ -0,0 +1,24 @@
+Tests that multiple sessions pause once on console.assert.
+Pausing on exceptions in 1
+Asserting in 1
+Paused in 1 with reason assert
+Paused in 2 with reason assert
+Asserting in 2
+Paused in 1 with reason assert
+Paused in 2 with reason assert
+Pausing on exceptions in both
+Asserting in 1
+Paused in 1 with reason assert
+Paused in 2 with reason assert
+Asserting in 2
+Paused in 1 with reason assert
+Paused in 2 with reason assert
+Not pausing on exceptions
+Asserting in 1
+Asserting in 2
+Pausing on exceptions in 3 (different context group)
+Asserting in 3
+Paused in 3 with reason assert
+Asserting in 1
+Paused in 1 with reason assert
+Paused in 2 with reason assert
diff --git a/src/v8/test/inspector/sessions/pause-on-console-assert.js b/src/v8/test/inspector/sessions/pause-on-console-assert.js
new file mode 100644
index 0000000..6cfdeaf
--- /dev/null
+++ b/src/v8/test/inspector/sessions/pause-on-console-assert.js
@@ -0,0 +1,54 @@
+// Copyright 2017 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.
+
+InspectorTest.log('Tests that multiple sessions pause once on console.assert.');
+
+(async function test() {
+  var contextGroup1 = new InspectorTest.ContextGroup();
+  var session1 = await connect(contextGroup1, 1);
+  var session2 = await connect(contextGroup1, 2);
+  var contextGroup2 = new InspectorTest.ContextGroup();
+  var session3 = await connect(contextGroup2, 3);
+
+  InspectorTest.log('Pausing on exceptions in 1');
+  await session1.Protocol.Debugger.setPauseOnExceptions({state: 'all'});
+  InspectorTest.log('Asserting in 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'console.assert(false)'});
+  InspectorTest.log('Asserting in 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'console.assert(false)'});
+
+  InspectorTest.log('Pausing on exceptions in both');
+  await session2.Protocol.Debugger.setPauseOnExceptions({state: 'all'});
+  InspectorTest.log('Asserting in 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'console.assert(false)'});
+  InspectorTest.log('Asserting in 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'console.assert(false)'});
+
+  InspectorTest.log('Not pausing on exceptions');
+  await session1.Protocol.Debugger.setPauseOnExceptions({state: 'none'});
+  await session2.Protocol.Debugger.setPauseOnExceptions({state: 'none'});
+  InspectorTest.log('Asserting in 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'console.assert(false)'});
+  InspectorTest.log('Asserting in 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'console.assert(false)'});
+
+  InspectorTest.log('Pausing on exceptions in 3 (different context group)');
+  await session3.Protocol.Debugger.setPauseOnExceptions({state: 'all'});
+  InspectorTest.log('Asserting in 3');
+  await session3.Protocol.Runtime.evaluate({expression: 'console.assert(false)'});
+  InspectorTest.log('Asserting in 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'console.assert(false)'});
+
+  InspectorTest.completeTest();
+})();
+
+async function connect(contextGroup, num) {
+  var session = contextGroup.connect();
+  await session.Protocol.Debugger.enable();
+  session.Protocol.Debugger.onPaused(message => {
+    InspectorTest.log(`Paused in ${num} with reason ${message.params.reason}`);
+    session.Protocol.Debugger.resume();
+  });
+  return session;
+}
diff --git a/src/v8/test/inspector/sessions/runtime-command-line-api-expected.txt b/src/v8/test/inspector/sessions/runtime-command-line-api-expected.txt
new file mode 100644
index 0000000..98583a5
--- /dev/null
+++ b/src/v8/test/inspector/sessions/runtime-command-line-api-expected.txt
@@ -0,0 +1,211 @@
+Tests that multiple sessions do not share command line api.
+Setting $0 in 1
+Evaluating $0 in 1
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+Evaluating $0 in 2
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
+Setting $0 in 2
+Evaluating $0 in 1
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+Evaluating $0 in 2
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 17
+            type : number
+            value : 17
+        }
+    }
+}
+Setting $_ in 1
+Evaluating $_ in 1
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+Evaluating $_ in 2
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : undefined
+        }
+    }
+}
+Setting $_ in 2
+Evaluating $_ in 1
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+Evaluating $_ in 2
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 17
+            type : number
+            value : 17
+        }
+    }
+}
+Inspecting in 1
+inspectRequested from 1
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+        }
+        object : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+Inspecting in 1 through variable
+inspectRequested from 1
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+        }
+        object : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+Inspecting in 2
+inspectRequested from 2
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+        }
+        object : {
+            description : 17
+            type : number
+            value : 17
+        }
+    }
+}
+Inspecting in 2 through variable
+inspectRequested from 2
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+        }
+        object : {
+            description : 17
+            type : number
+            value : 17
+        }
+    }
+}
+Inspecting in 2 through variable from 1
+inspectRequested from 1
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+        }
+        object : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+Disconnecting 1
+Evaluating $0 in 2
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 17
+            type : number
+            value : 17
+        }
+    }
+}
+Evaluating $_ in 2
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 17
+            type : number
+            value : 17
+        }
+    }
+}
+Inspecting in 2
+inspectRequested from 2
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+        }
+        object : {
+            description : 17
+            type : number
+            value : 17
+        }
+    }
+}
+Inspecting in 2 through variable from 1
+Inspecting in 2 through variable
+inspectRequested from 2
+{
+    method : Runtime.inspectRequested
+    params : {
+        hints : {
+        }
+        object : {
+            description : 17
+            type : number
+            value : 17
+        }
+    }
+}
diff --git a/src/v8/test/inspector/sessions/runtime-command-line-api.js b/src/v8/test/inspector/sessions/runtime-command-line-api.js
new file mode 100644
index 0000000..078783a
--- /dev/null
+++ b/src/v8/test/inspector/sessions/runtime-command-line-api.js
@@ -0,0 +1,76 @@
+// Copyright 2017 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.
+
+InspectorTest.log('Tests that multiple sessions do not share command line api.');
+
+(async function test() {
+  var contextGroup = new InspectorTest.ContextGroup();
+  var session1 = contextGroup.connect();
+  await session1.Protocol.Runtime.enable();
+  session1.Protocol.Runtime.onInspectRequested(message => {
+    InspectorTest.log('inspectRequested from 1');
+    InspectorTest.logMessage(message);
+  });
+  var session2 = contextGroup.connect();
+  await session2.Protocol.Runtime.enable();
+  session2.Protocol.Runtime.onInspectRequested(message => {
+    InspectorTest.log('inspectRequested from 2');
+    InspectorTest.logMessage(message);
+  });
+
+  InspectorTest.log('Setting $0 in 1');
+  await session1.addInspectedObject(42);
+  InspectorTest.log('Evaluating $0 in 1');
+  InspectorTest.logMessage(await session1.Protocol.Runtime.evaluate({expression: '$0', includeCommandLineAPI: true}));
+  InspectorTest.log('Evaluating $0 in 2');
+  InspectorTest.logMessage(await session2.Protocol.Runtime.evaluate({expression: '$0', includeCommandLineAPI: true}));
+
+  InspectorTest.log('Setting $0 in 2');
+  await session2.addInspectedObject(17);
+  InspectorTest.log('Evaluating $0 in 1');
+  InspectorTest.logMessage(await session1.Protocol.Runtime.evaluate({expression: '$0', includeCommandLineAPI: true}));
+  InspectorTest.log('Evaluating $0 in 2');
+  InspectorTest.logMessage(await session2.Protocol.Runtime.evaluate({expression: '$0', includeCommandLineAPI: true}));
+
+  InspectorTest.log('Setting $_ in 1');
+  await session1.Protocol.Runtime.evaluate({expression: '42', objectGroup: 'console', includeCommandLineAPI: true});
+  InspectorTest.log('Evaluating $_ in 1');
+  InspectorTest.logMessage(await session1.Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
+  InspectorTest.log('Evaluating $_ in 2');
+  InspectorTest.logMessage(await session2.Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
+
+  InspectorTest.log('Setting $_ in 2');
+  await session2.Protocol.Runtime.evaluate({expression: '17', objectGroup: 'console', includeCommandLineAPI: true});
+  InspectorTest.log('Evaluating $_ in 1');
+  InspectorTest.logMessage(await session1.Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
+  InspectorTest.log('Evaluating $_ in 2');
+  InspectorTest.logMessage(await session2.Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
+
+  InspectorTest.log('Inspecting in 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'var inspect1=inspect; inspect(42)', includeCommandLineAPI: true});
+  InspectorTest.log('Inspecting in 1 through variable');
+  await session1.Protocol.Runtime.evaluate({expression: 'inspect1(42)', includeCommandLineAPI: true});
+  InspectorTest.log('Inspecting in 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'var inspect2=inspect; inspect(17)', includeCommandLineAPI: true});
+  InspectorTest.log('Inspecting in 2 through variable');
+  await session2.Protocol.Runtime.evaluate({expression: 'inspect2(17)', includeCommandLineAPI: true});
+  InspectorTest.log('Inspecting in 2 through variable from 1');
+  await session2.Protocol.Runtime.evaluate({expression: 'inspect1(42)', includeCommandLineAPI: true});
+
+  InspectorTest.log('Disconnecting 1');
+  session1.disconnect();
+
+  InspectorTest.log('Evaluating $0 in 2');
+  InspectorTest.logMessage(await session2.Protocol.Runtime.evaluate({expression: '$0', includeCommandLineAPI: true}));
+  InspectorTest.log('Evaluating $_ in 2');
+  InspectorTest.logMessage(await session2.Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
+  InspectorTest.log('Inspecting in 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'inspect(17)', includeCommandLineAPI: true});
+  InspectorTest.log('Inspecting in 2 through variable from 1');
+  await session2.Protocol.Runtime.evaluate({expression: 'inspect1(42)', includeCommandLineAPI: true});
+  InspectorTest.log('Inspecting in 2 through variable');
+  await session2.Protocol.Runtime.evaluate({expression: 'inspect2(17)', includeCommandLineAPI: true});
+
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/sessions/runtime-console-api-called-expected.txt b/src/v8/test/inspector/sessions/runtime-console-api-called-expected.txt
new file mode 100644
index 0000000..0f679fa
--- /dev/null
+++ b/src/v8/test/inspector/sessions/runtime-console-api-called-expected.txt
@@ -0,0 +1,217 @@
+Tests that all sessions get console api notifications.
+Error in 2
+From session 1
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 1
+                type : number
+                value : 1
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : error
+    }
+}
+From session 2
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 1
+                type : number
+                value : 1
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : error
+    }
+}
+Logging in 1
+From session 1
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 2
+                type : number
+                value : 2
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
+From session 2
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                description : 2
+                type : number
+                value : 2
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 8
+                    functionName : 
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
+Error in setTimeout 1
+From session 1
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : a
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 25
+                    functionName : setTimeout
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : error
+    }
+}
+From session 2
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : a
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 25
+                    functionName : setTimeout
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : error
+    }
+}
+Logging in setTimeout 2
+From session 1
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : b
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 25
+                    functionName : setTimeout
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
+From session 2
+{
+    method : Runtime.consoleAPICalled
+    params : {
+        args : [
+            [0] : {
+                type : string
+                value : b
+            }
+        ]
+        executionContextId : <executionContextId>
+        stackTrace : {
+            callFrames : [
+                [0] : {
+                    columnNumber : 25
+                    functionName : setTimeout
+                    lineNumber : 0
+                    scriptId : <scriptId>
+                    url : 
+                }
+            ]
+        }
+        timestamp : <timestamp>
+        type : log
+    }
+}
diff --git a/src/v8/test/inspector/sessions/runtime-console-api-called.js b/src/v8/test/inspector/sessions/runtime-console-api-called.js
new file mode 100644
index 0000000..fc9d79b
--- /dev/null
+++ b/src/v8/test/inspector/sessions/runtime-console-api-called.js
@@ -0,0 +1,38 @@
+// Copyright 2017 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.
+
+InspectorTest.log('Tests that all sessions get console api notifications.');
+
+function connect(contextGroup, num) {
+  var session = contextGroup.connect();
+  session.Protocol.Runtime.onConsoleAPICalled(message => {
+    InspectorTest.log('From session ' + num);
+    InspectorTest.logMessage(message);
+  });
+  return session;
+}
+
+(async function test() {
+  var contextGroup = new InspectorTest.ContextGroup();
+  var session1 = connect(contextGroup, 1);
+  var session2 = connect(contextGroup, 2);
+  await session1.Protocol.Runtime.enable();
+  await session2.Protocol.Runtime.enable();
+
+  InspectorTest.log('Error in 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'console.error(1)'});
+
+  InspectorTest.log('Logging in 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'console.log(2)'});
+
+  InspectorTest.log('Error in setTimeout 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'setTimeout(() => console.error("a"), 0)'});
+  await InspectorTest.waitForPendingTasks();
+
+  InspectorTest.log('Logging in setTimeout 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'setTimeout(() => console.log("b"), 0)'});
+  await InspectorTest.waitForPendingTasks();
+
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/sessions/runtime-evaluate-exception-expected.txt b/src/v8/test/inspector/sessions/runtime-evaluate-exception-expected.txt
new file mode 100644
index 0000000..e84c770
--- /dev/null
+++ b/src/v8/test/inspector/sessions/runtime-evaluate-exception-expected.txt
@@ -0,0 +1,277 @@
+Tests that all sessions get exception notifications.
+Throwing in 2
+Throwing in 1
+Throwing in setTimeout 1
+From session 1
+{
+    method : Runtime.exceptionThrown
+    params : {
+        exceptionDetails : {
+            columnNumber : 19
+            exception : {
+                type : string
+                value : error3
+            }
+            exceptionId : <exceptionId>
+            executionContextId : <executionContextId>
+            lineNumber : 0
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 19
+                        functionName : setTimeout
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught error3
+        }
+        timestamp : <timestamp>
+    }
+}
+From session 2
+{
+    method : Runtime.exceptionThrown
+    params : {
+        exceptionDetails : {
+            columnNumber : 19
+            exception : {
+                type : string
+                value : error3
+            }
+            exceptionId : <exceptionId>
+            executionContextId : <executionContextId>
+            lineNumber : 0
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 19
+                        functionName : setTimeout
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught error3
+        }
+        timestamp : <timestamp>
+    }
+}
+Throwing in setTimeout 2
+From session 1
+{
+    method : Runtime.exceptionThrown
+    params : {
+        exceptionDetails : {
+            columnNumber : 19
+            exception : {
+                type : string
+                value : error4
+            }
+            exceptionId : <exceptionId>
+            executionContextId : <executionContextId>
+            lineNumber : 0
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 19
+                        functionName : setTimeout
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught error4
+        }
+        timestamp : <timestamp>
+    }
+}
+From session 2
+{
+    method : Runtime.exceptionThrown
+    params : {
+        exceptionDetails : {
+            columnNumber : 19
+            exception : {
+                type : string
+                value : error4
+            }
+            exceptionId : <exceptionId>
+            executionContextId : <executionContextId>
+            lineNumber : 0
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 19
+                        functionName : setTimeout
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught error4
+        }
+        timestamp : <timestamp>
+    }
+}
+Rejecting in 2
+From session 1
+{
+    method : Runtime.exceptionThrown
+    params : {
+        exceptionDetails : {
+            columnNumber : 40
+            exception : {
+                type : string
+                value : error5
+            }
+            exceptionId : <exceptionId>
+            executionContextId : <executionContextId>
+            lineNumber : 0
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 40
+                        functionName : setTimeout
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught error5
+        }
+        timestamp : <timestamp>
+    }
+}
+From session 2
+{
+    method : Runtime.exceptionThrown
+    params : {
+        exceptionDetails : {
+            columnNumber : 40
+            exception : {
+                type : string
+                value : error5
+            }
+            exceptionId : <exceptionId>
+            executionContextId : <executionContextId>
+            lineNumber : 0
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 40
+                        functionName : setTimeout
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught error5
+        }
+        timestamp : <timestamp>
+    }
+}
+Revoking in 2
+From session 1
+{
+    method : Runtime.exceptionRevoked
+    params : {
+        exceptionId : <exceptionId>
+        reason : Handler added to rejected promise
+    }
+}
+id matching: true
+From session 2
+{
+    method : Runtime.exceptionRevoked
+    params : {
+        exceptionId : <exceptionId>
+        reason : Handler added to rejected promise
+    }
+}
+id matching: true
+Rejecting in 1
+From session 1
+{
+    method : Runtime.exceptionThrown
+    params : {
+        exceptionDetails : {
+            columnNumber : 40
+            exception : {
+                type : string
+                value : error6
+            }
+            exceptionId : <exceptionId>
+            executionContextId : <executionContextId>
+            lineNumber : 0
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 40
+                        functionName : setTimeout
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught error6
+        }
+        timestamp : <timestamp>
+    }
+}
+From session 2
+{
+    method : Runtime.exceptionThrown
+    params : {
+        exceptionDetails : {
+            columnNumber : 40
+            exception : {
+                type : string
+                value : error6
+            }
+            exceptionId : <exceptionId>
+            executionContextId : <executionContextId>
+            lineNumber : 0
+            stackTrace : {
+                callFrames : [
+                    [0] : {
+                        columnNumber : 40
+                        functionName : setTimeout
+                        lineNumber : 0
+                        scriptId : <scriptId>
+                        url : 
+                    }
+                ]
+            }
+            text : Uncaught error6
+        }
+        timestamp : <timestamp>
+    }
+}
+Revoking in 1
+From session 1
+{
+    method : Runtime.exceptionRevoked
+    params : {
+        exceptionId : <exceptionId>
+        reason : Handler added to rejected promise
+    }
+}
+id matching: true
+From session 2
+{
+    method : Runtime.exceptionRevoked
+    params : {
+        exceptionId : <exceptionId>
+        reason : Handler added to rejected promise
+    }
+}
+id matching: true
diff --git a/src/v8/test/inspector/sessions/runtime-evaluate-exception.js b/src/v8/test/inspector/sessions/runtime-evaluate-exception.js
new file mode 100644
index 0000000..8f3520f
--- /dev/null
+++ b/src/v8/test/inspector/sessions/runtime-evaluate-exception.js
@@ -0,0 +1,59 @@
+// Copyright 2017 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.
+
+InspectorTest.log('Tests that all sessions get exception notifications.');
+
+function connect(contextGroup, num) {
+  var session = contextGroup.connect();
+  var exceptionId;
+  session.Protocol.Runtime.onExceptionThrown(message => {
+    InspectorTest.log('From session ' + num);
+    InspectorTest.logMessage(message);
+    exceptionId = message.params.exceptionDetails.exceptionId;
+  });
+  session.Protocol.Runtime.onExceptionRevoked(message => {
+    InspectorTest.log('From session ' + num);
+    InspectorTest.logMessage(message);
+    InspectorTest.log('id matching: ' + (message.params.exceptionId === exceptionId));
+  });
+  return session;
+}
+
+(async function test() {
+  var contextGroup = new InspectorTest.ContextGroup();
+  var session1 = connect(contextGroup, 1);
+  var session2 = connect(contextGroup, 2);
+  await session1.Protocol.Runtime.enable();
+  await session2.Protocol.Runtime.enable();
+
+  InspectorTest.log('Throwing in 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'throw "error1";'});
+
+  InspectorTest.log('Throwing in 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'throw "error2";'});
+
+  InspectorTest.log('Throwing in setTimeout 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'setTimeout(() => { throw "error3"; }, 0)'});
+  await InspectorTest.waitForPendingTasks();
+
+  InspectorTest.log('Throwing in setTimeout 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'setTimeout(() => { throw "error4"; }, 0)'});
+  await InspectorTest.waitForPendingTasks();
+
+  InspectorTest.log('Rejecting in 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'var p2; setTimeout(() => { p2 = Promise.reject("error5") }, 0)'});
+  await InspectorTest.waitForPendingTasks();
+  InspectorTest.log('Revoking in 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'setTimeout(() => { p2.catch() }, 0);'});
+  await InspectorTest.waitForPendingTasks();
+
+  InspectorTest.log('Rejecting in 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'var p1; setTimeout(() => { p1 = Promise.reject("error6")} , 0)'});
+  await InspectorTest.waitForPendingTasks();
+  InspectorTest.log('Revoking in 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'setTimeout(() => { p1.catch() }, 0);'});
+  await InspectorTest.waitForPendingTasks();
+
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/sessions/runtime-evaluate-expected.txt b/src/v8/test/inspector/sessions/runtime-evaluate-expected.txt
new file mode 100644
index 0000000..f201ff6
--- /dev/null
+++ b/src/v8/test/inspector/sessions/runtime-evaluate-expected.txt
@@ -0,0 +1,25 @@
+Tests that multiple sessions share the context.
+Assigning in 1
+Evaluating in 2
+{
+    id : <messageId>
+    result : {
+        result : {
+            description : 42
+            type : number
+            value : 42
+        }
+    }
+}
+Awaiting in 1
+Resolving in 2
+Should resolve in 1
+{
+    id : <messageId>
+    result : {
+        result : {
+            type : string
+            value : foo
+        }
+    }
+}
diff --git a/src/v8/test/inspector/sessions/runtime-evaluate.js b/src/v8/test/inspector/sessions/runtime-evaluate.js
new file mode 100644
index 0000000..72ca178
--- /dev/null
+++ b/src/v8/test/inspector/sessions/runtime-evaluate.js
@@ -0,0 +1,25 @@
+// Copyright 2017 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.
+
+InspectorTest.log('Tests that multiple sessions share the context.');
+
+(async function test() {
+  var contextGroup = new InspectorTest.ContextGroup();
+  var session1 = contextGroup.connect();
+  var session2 = contextGroup.connect();
+
+  InspectorTest.log('Assigning in 1');
+  await session1.Protocol.Runtime.evaluate({expression: 'var a = 42;'});
+  InspectorTest.log('Evaluating in 2');
+  InspectorTest.logMessage(await session2.Protocol.Runtime.evaluate({expression: 'a'}));
+
+  InspectorTest.log('Awaiting in 1');
+  var promise = session1.Protocol.Runtime.evaluate({expression: 'var cb; new Promise(f => cb = f)', awaitPromise: true});
+  InspectorTest.log('Resolving in 2');
+  await session2.Protocol.Runtime.evaluate({expression: 'cb("foo")'});
+  InspectorTest.log('Should resolve in 1');
+  InspectorTest.logMessage(await promise);
+
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/sessions/runtime-remote-object-expected.txt b/src/v8/test/inspector/sessions/runtime-remote-object-expected.txt
new file mode 100644
index 0000000..a8d0ec0
--- /dev/null
+++ b/src/v8/test/inspector/sessions/runtime-remote-object-expected.txt
@@ -0,0 +1,103 @@
+Tests that multiple sessions do not interfere with each other's remote objects.
+Evaluating in 1
+Evaluating in 2
+Retrieving properties in 2
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : a
+                value : {
+                    description : 17
+                    type : number
+                    value : 17
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : true
+                enumerable : false
+                isOwn : true
+                name : __proto__
+                value : {
+                    className : Object
+                    description : Object
+                    objectId : <objectId>
+                    type : object
+                }
+                writable : true
+            }
+        ]
+    }
+}
+Retrieving properties in 1
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : a
+                value : {
+                    description : 42
+                    type : number
+                    value : 42
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : true
+                enumerable : false
+                isOwn : true
+                name : __proto__
+                value : {
+                    className : Object
+                    description : Object
+                    objectId : <objectId>
+                    type : object
+                }
+                writable : true
+            }
+        ]
+    }
+}
+Disconnecting 2
+Retrieving properties in 1
+{
+    id : <messageId>
+    result : {
+        result : [
+            [0] : {
+                configurable : true
+                enumerable : true
+                isOwn : true
+                name : a
+                value : {
+                    description : 42
+                    type : number
+                    value : 42
+                }
+                writable : true
+            }
+            [1] : {
+                configurable : true
+                enumerable : false
+                isOwn : true
+                name : __proto__
+                value : {
+                    className : Object
+                    description : Object
+                    objectId : <objectId>
+                    type : object
+                }
+                writable : true
+            }
+        ]
+    }
+}
diff --git a/src/v8/test/inspector/sessions/runtime-remote-object.js b/src/v8/test/inspector/sessions/runtime-remote-object.js
new file mode 100644
index 0000000..aaaccb4
--- /dev/null
+++ b/src/v8/test/inspector/sessions/runtime-remote-object.js
@@ -0,0 +1,30 @@
+// Copyright 2017 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.
+
+InspectorTest.log('Tests that multiple sessions do not interfere with each other\'s remote objects.');
+
+(async function test() {
+  var contextGroup = new InspectorTest.ContextGroup();
+  var session1 = contextGroup.connect();
+  var session2 = contextGroup.connect();
+
+  InspectorTest.log('Evaluating in 1');
+  var result1 = await session1.Protocol.Runtime.evaluate({expression: '({a: 42})'});
+  InspectorTest.log('Evaluating in 2');
+  var result2 = await session2.Protocol.Runtime.evaluate({expression: '({a: 17})'});
+
+  await print(2, session2, result2);
+  await print(1, session1, result1);
+  InspectorTest.log('Disconnecting 2');
+  session2.disconnect();
+  await print(1, session1, result1);
+
+  InspectorTest.completeTest();
+})();
+
+async function print(num, session, message) {
+  InspectorTest.log('Retrieving properties in ' + num);
+  var objectId = message.result.result.objectId;
+  InspectorTest.logMessage(await session.Protocol.Runtime.getProperties({objectId, ownProperties: true}));
+}
diff --git a/src/v8/test/inspector/task-runner.cc b/src/v8/test/inspector/task-runner.cc
new file mode 100644
index 0000000..921317d
--- /dev/null
+++ b/src/v8/test/inspector/task-runner.cc
@@ -0,0 +1,112 @@
+// Copyright 2016 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.
+
+#include "test/inspector/task-runner.h"
+
+#if !defined(_WIN32) && !defined(_WIN64)
+#include <unistd.h>  // NOLINT
+#endif               // !defined(_WIN32) && !defined(_WIN64)
+
+namespace {
+
+void ReportUncaughtException(v8::Isolate* isolate,
+                             const v8::TryCatch& try_catch) {
+  CHECK(try_catch.HasCaught());
+  v8::HandleScope handle_scope(isolate);
+  std::string message =
+      *v8::String::Utf8Value(isolate, try_catch.Message()->Get());
+  int line = try_catch.Message()
+                 ->GetLineNumber(isolate->GetCurrentContext())
+                 .FromJust();
+  std::string source_line = *v8::String::Utf8Value(
+      isolate, try_catch.Message()
+                   ->GetSourceLine(isolate->GetCurrentContext())
+                   .ToLocalChecked());
+  fprintf(stderr, "Unhandle exception: %s @%s[%d]\n", message.data(),
+          source_line.data(), line);
+}
+
+}  //  namespace
+
+TaskRunner::TaskRunner(IsolateData::SetupGlobalTasks setup_global_tasks,
+                       bool catch_exceptions,
+                       v8::base::Semaphore* ready_semaphore,
+                       v8::StartupData* startup_data, bool with_inspector)
+    : Thread(Options("Task Runner")),
+      setup_global_tasks_(std::move(setup_global_tasks)),
+      startup_data_(startup_data),
+      with_inspector_(with_inspector),
+      catch_exceptions_(catch_exceptions),
+      ready_semaphore_(ready_semaphore),
+      data_(nullptr),
+      process_queue_semaphore_(0),
+      nested_loop_count_(0) {
+  Start();
+}
+
+TaskRunner::~TaskRunner() { Join(); }
+
+void TaskRunner::Run() {
+  data_.reset(new IsolateData(this, std::move(setup_global_tasks_),
+                              startup_data_, with_inspector_));
+  if (ready_semaphore_) ready_semaphore_->Signal();
+  RunMessageLoop(false);
+}
+
+void TaskRunner::RunMessageLoop(bool only_protocol) {
+  int loop_number = ++nested_loop_count_;
+  while (nested_loop_count_ == loop_number && !is_terminated_.Value()) {
+    TaskRunner::Task* task = GetNext(only_protocol);
+    if (!task) return;
+    v8::Isolate::Scope isolate_scope(isolate());
+    if (catch_exceptions_) {
+      v8::TryCatch try_catch(isolate());
+      task->Run(data_.get());
+      delete task;
+      if (try_catch.HasCaught()) {
+        ReportUncaughtException(isolate(), try_catch);
+        fflush(stdout);
+        fflush(stderr);
+        _exit(0);
+      }
+    } else {
+      task->Run(data_.get());
+      delete task;
+    }
+  }
+}
+
+void TaskRunner::QuitMessageLoop() {
+  DCHECK_LT(0, nested_loop_count_);
+  --nested_loop_count_;
+}
+
+void TaskRunner::Append(Task* task) {
+  queue_.Enqueue(task);
+  process_queue_semaphore_.Signal();
+}
+
+void TaskRunner::Terminate() {
+  is_terminated_.Increment(1);
+  process_queue_semaphore_.Signal();
+}
+
+TaskRunner::Task* TaskRunner::GetNext(bool only_protocol) {
+  for (;;) {
+    if (is_terminated_.Value()) return nullptr;
+    if (only_protocol) {
+      Task* task = nullptr;
+      if (queue_.Dequeue(&task)) {
+        if (task->is_priority_task()) return task;
+        deffered_queue_.Enqueue(task);
+      }
+    } else {
+      Task* task = nullptr;
+      if (deffered_queue_.Dequeue(&task)) return task;
+      if (queue_.Dequeue(&task)) return task;
+    }
+    process_queue_semaphore_.Wait();
+  }
+  return nullptr;
+}
diff --git a/src/v8/test/inspector/task-runner.h b/src/v8/test/inspector/task-runner.h
new file mode 100644
index 0000000..353c783
--- /dev/null
+++ b/src/v8/test/inspector/task-runner.h
@@ -0,0 +1,72 @@
+// Copyright 2016 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.
+
+#ifndef V8_TEST_INSPECTOR_PROTOCOL_TASK_RUNNER_H_
+#define V8_TEST_INSPECTOR_PROTOCOL_TASK_RUNNER_H_
+
+#include <map>
+
+#include "include/v8-inspector.h"
+#include "include/v8-platform.h"
+#include "include/v8.h"
+#include "src/base/atomic-utils.h"
+#include "src/base/macros.h"
+#include "src/base/platform/platform.h"
+#include "src/locked-queue-inl.h"
+#include "src/vector.h"
+#include "test/inspector/isolate-data.h"
+
+class TaskRunner : public v8::base::Thread {
+ public:
+  class Task {
+   public:
+    virtual ~Task() {}
+    virtual bool is_priority_task() = 0;
+    virtual void Run(IsolateData* data) = 0;
+  };
+
+  TaskRunner(IsolateData::SetupGlobalTasks setup_global_tasks,
+             bool catch_exceptions, v8::base::Semaphore* ready_semaphore,
+             v8::StartupData* startup_data, bool with_inspector);
+  virtual ~TaskRunner();
+  IsolateData* data() const { return data_.get(); }
+
+  // Thread implementation.
+  void Run() override;
+
+  // Should be called from the same thread and only from task.
+  void RunMessageLoop(bool only_protocol);
+  void QuitMessageLoop();
+
+  // TaskRunner takes ownership.
+  void Append(Task* task);
+
+  void Terminate();
+
+ private:
+  Task* GetNext(bool only_protocol);
+  v8::Isolate* isolate() const { return data_->isolate(); }
+
+  IsolateData::SetupGlobalTasks setup_global_tasks_;
+  v8::StartupData* startup_data_;
+  bool with_inspector_;
+  bool catch_exceptions_;
+  v8::base::Semaphore* ready_semaphore_;
+  std::unique_ptr<IsolateData> data_;
+
+  // deferred_queue_ combined with queue_ (in this order) have all tasks in the
+  // correct order. Sometimes we skip non-protocol tasks by moving them from
+  // queue_ to deferred_queue_.
+  v8::internal::LockedQueue<Task*> queue_;
+  v8::internal::LockedQueue<Task*> deffered_queue_;
+  v8::base::Semaphore process_queue_semaphore_;
+
+  int nested_loop_count_;
+
+  v8::base::AtomicNumber<int> is_terminated_;
+
+  DISALLOW_COPY_AND_ASSIGN(TaskRunner);
+};
+
+#endif  //  V8_TEST_INSPECTOR_PROTOCOL_TASK_RUNNER_H_
diff --git a/src/v8/test/inspector/testcfg.py b/src/v8/test/inspector/testcfg.py
new file mode 100644
index 0000000..9c943d9
--- /dev/null
+++ b/src/v8/test/inspector/testcfg.py
@@ -0,0 +1,113 @@
+# Copyright 2016 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.
+
+import itertools
+import os
+import re
+import shlex
+
+from testrunner.local import testsuite
+from testrunner.local import utils
+from testrunner.objects import testcase
+
+FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
+PROTOCOL_TEST_JS = "protocol-test.js"
+EXPECTED_SUFFIX = "-expected.txt"
+RESOURCES_FOLDER = "resources"
+
+class InspectorProtocolTestSuite(testsuite.TestSuite):
+
+  def __init__(self, name, root):
+    super(InspectorProtocolTestSuite, self).__init__(name, root)
+
+  def ListTests(self, context):
+    tests = []
+    for dirname, dirs, files in os.walk(os.path.join(self.root), followlinks=True):
+      for dotted in [x for x in dirs if x.startswith('.')]:
+        dirs.remove(dotted)
+      if dirname.endswith(os.path.sep + RESOURCES_FOLDER):
+        continue
+      dirs.sort()
+      files.sort()
+      for filename in files:
+        if filename.endswith(".js") and filename != PROTOCOL_TEST_JS:
+          fullpath = os.path.join(dirname, filename)
+          relpath = fullpath[len(self.root) + 1 : -3]
+          testname = relpath.replace(os.path.sep, "/")
+          test = testcase.TestCase(self, testname)
+          tests.append(test)
+    return tests
+
+  def GetFlagsForTestCase(self, testcase, context):
+    source = self.GetSourceForTest(testcase)
+    flags = [] + context.mode_flags
+    flags_match = re.findall(FLAGS_PATTERN, source)
+    for match in flags_match:
+      flags += shlex.split(match.strip())
+    testname = testcase.path.split(os.path.sep)[-1]
+    testfilename = os.path.join(self.root, testcase.path + self.suffix())
+    protocoltestfilename = os.path.join(self.root, PROTOCOL_TEST_JS)
+    return testcase.flags + flags + [ protocoltestfilename, testfilename ]
+
+  def GetSourceForTest(self, testcase):
+    filename = os.path.join(self.root, testcase.path + self.suffix())
+    with open(filename) as f:
+      return f.read()
+
+  def shell(self):
+    return "inspector-test"
+
+  def _IgnoreLine(self, string):
+    """Ignore empty lines, valgrind output and Android output."""
+    if not string: return True
+    return (string.startswith("==") or string.startswith("**") or
+            string.startswith("ANDROID") or
+            # FIXME(machenbach): The test driver shouldn't try to use slow
+            # asserts if they weren't compiled. This fails in optdebug=2.
+            string == "Warning: unknown flag --enable-slow-asserts." or
+            string == "Try --help for options")
+
+  def IsFailureOutput(self, testcase):
+    file_name = os.path.join(self.root, testcase.path) + EXPECTED_SUFFIX
+    with file(file_name, "r") as expected:
+      expected_lines = expected.readlines()
+
+    def ExpIterator():
+      for line in expected_lines:
+        if not line.strip(): continue
+        yield line.strip()
+
+    def ActIterator(lines):
+      for line in lines:
+        if self._IgnoreLine(line.strip()): continue
+        yield line.strip()
+
+    def ActBlockIterator():
+      """Iterates over blocks of actual output lines."""
+      lines = testcase.output.stdout.splitlines()
+      start_index = 0
+      found_eqeq = False
+      for index, line in enumerate(lines):
+        # If a stress test separator is found:
+        if line.startswith("=="):
+          # Iterate over all lines before a separator except the first.
+          if not found_eqeq:
+            found_eqeq = True
+          else:
+            yield ActIterator(lines[start_index:index])
+          # The next block of output lines starts after the separator.
+          start_index = index + 1
+      # Iterate over complete output if no separator was found.
+      if not found_eqeq:
+        yield ActIterator(lines)
+
+    for act_iterator in ActBlockIterator():
+      for (expected, actual) in itertools.izip_longest(
+          ExpIterator(), act_iterator, fillvalue=''):
+        if expected != actual:
+          return True
+      return False
+
+def GetSuite(name, root):
+  return InspectorProtocolTestSuite(name, root)
diff --git a/src/v8/test/inspector/type-profiler/type-profile-disable-expected.txt b/src/v8/test/inspector/type-profiler/type-profile-disable-expected.txt
new file mode 100644
index 0000000..b70acba
--- /dev/null
+++ b/src/v8/test/inspector/type-profiler/type-profile-disable-expected.txt
@@ -0,0 +1,9 @@
+Turn Profiler.startTypeProfile on and off.
+
+function g(/*Object*/a, /*Array*/b, /*null*/c) {
+  return 'bye';
+/*string*/};
+g({}, [], null);
+
+[
+]
\ No newline at end of file
diff --git a/src/v8/test/inspector/type-profiler/type-profile-disable.js b/src/v8/test/inspector/type-profiler/type-profile-disable.js
new file mode 100644
index 0000000..38a3c6f
--- /dev/null
+++ b/src/v8/test/inspector/type-profiler/type-profile-disable.js
@@ -0,0 +1,47 @@
+// Copyright 2017 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.
+
+// Flags: --type-profile
+
+const source =
+  `
+function g(a, b, c) {
+  return 'bye';
+};
+g({}, [], null);
+`;
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Turn " +
+  "Profiler.startTypeProfile on and off.");
+
+(async function testTypeProfile() {
+  Protocol.Runtime.enable();
+   let {result: {scriptId}} = await Protocol.Runtime.compileScript({
+    expression: source,
+    sourceURL: arguments.callee.name, persistScript: true
+  });
+  await Protocol.Profiler.enable();
+  // Start, run, take.
+  await Protocol.Profiler.startTypeProfile();
+  Protocol.Runtime.runScript({scriptId});
+
+  let typeProfiles = await Protocol.Profiler.takeTypeProfile();
+  session.logTypeProfile(typeProfiles.result.result[0],
+    source);
+
+  // This should delete all data.
+  Protocol.Profiler.stopTypeProfile();
+
+  await Protocol.Profiler.startTypeProfile();
+  typeProfiles = await Protocol.Profiler.takeTypeProfile();
+
+  // Should be empty because no code was run since start.
+  InspectorTest.logMessage(typeProfiles.result.result);
+
+  Protocol.Profiler.stopTypeProfile();
+
+  Protocol.Profiler.disable();
+  await Protocol.Runtime.disable();
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/type-profiler/type-profile-expected.txt b/src/v8/test/inspector/type-profiler/type-profile-expected.txt
new file mode 100644
index 0000000..8001d82
--- /dev/null
+++ b/src/v8/test/inspector/type-profiler/type-profile-expected.txt
@@ -0,0 +1,8 @@
+Test collecting type profile data with Profiler.takeTypeProfile.
+
+function f(/*Object, number, undefined*/a, /*Array, number, null*/b, /*boolean, Object, symbol*/c) {
+  return 'bye';
+/*string*/};
+f({}, [], true);
+f(3, 2.3, {a: 42});
+f(undefined, null, Symbol('hello'));/*string*/
diff --git a/src/v8/test/inspector/type-profiler/type-profile-start-stop-expected.txt b/src/v8/test/inspector/type-profiler/type-profile-start-stop-expected.txt
new file mode 100644
index 0000000..0db7882
--- /dev/null
+++ b/src/v8/test/inspector/type-profiler/type-profile-start-stop-expected.txt
@@ -0,0 +1,49 @@
+Turn Profiler.startTypeProfile on and off.
+
+Running test: testTypeProfile
+
+function g(/*Object*/a, /*Array*/b, /*null*/c) {
+  return 'first';
+/*string*/};
+g({}, [], null);
+
+
+Running test: testTypeProfileFromDifferentSource
+
+function f(/*null*/a) {
+  return 'second';
+/*string*/};
+f(null);
+
+
+Running test: testStopTypeProfileDeletesFeedback
+[
+]
+
+Running test: testTypeProfileWithoutStartingItFirst
+Type profile has not been started.
+
+Running test: testTypeProfileAfterStoppingIt
+Type profile has not been started.
+
+Running test: testStartTypeProfileAfterRunning
+{
+    id : <messageId>
+    result : {
+        result : [
+        ]
+    }
+}
+
+Running test: testTypeProfileForTwoSources
+
+function g(/*Object*/a, /*Array*/b, /*null*/c) {
+  return 'first';
+/*string*/};
+g({}, [], null);
+
+
+function f(/*null*/a) {
+  return 'second';
+/*string*/};
+f(null);
diff --git a/src/v8/test/inspector/type-profiler/type-profile-start-stop.js b/src/v8/test/inspector/type-profiler/type-profile-start-stop.js
new file mode 100644
index 0000000..dad9874
--- /dev/null
+++ b/src/v8/test/inspector/type-profiler/type-profile-start-stop.js
@@ -0,0 +1,170 @@
+// Copyright 2017 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.
+
+// Flags: --type-profile
+
+const source1 =
+  `
+function g(a, b, c) {
+  return 'first';
+};
+g({}, [], null);
+`;
+
+const source2 =
+  `
+function f(a) {
+  return 'second';
+};
+f(null);
+`;
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Turn " +
+  "Profiler.startTypeProfile on and off.");
+
+InspectorTest.runAsyncTestSuite([
+  async function testTypeProfile() {
+    Protocol.Runtime.enable();
+    let {result: {scriptId}} = await Protocol.Runtime.compileScript({
+      expression: source1,
+      sourceURL: arguments.callee.name, persistScript: true
+    });
+    await Protocol.Profiler.enable();
+
+    // Start, run, take.
+    await Protocol.Profiler.startTypeProfile();
+    Protocol.Runtime.runScript({scriptId});
+
+    let typeProfiles = await Protocol.Profiler.takeTypeProfile();
+    await session.logTypeProfile(typeProfiles.result.result[0],
+      source1);
+
+    Protocol.Profiler.stopTypeProfile();
+    Protocol.Profiler.disable();
+    await Protocol.Runtime.disable();
+  },
+  async function testTypeProfileFromDifferentSource() {
+    Protocol.Runtime.enable();
+    let {result: {scriptId}} = await Protocol.Runtime.compileScript({
+      expression: source2,
+      sourceURL: arguments.callee.name, persistScript: true
+    });
+    await Protocol.Profiler.enable();
+
+    // Start, run different script, take.
+    await Protocol.Profiler.startTypeProfile();
+    Protocol.Runtime.runScript({scriptId});
+
+    let typeProfiles = await Protocol.Profiler.takeTypeProfile();
+    await session.logTypeProfile(typeProfiles.result.result[0],
+      source2);
+
+    Protocol.Profiler.stopTypeProfile();
+    Protocol.Profiler.disable();
+    await Protocol.Runtime.disable();
+  },
+  async function testStopTypeProfileDeletesFeedback() {
+    Protocol.Runtime.enable();
+    let {result: {scriptId}} = await Protocol.Runtime.compileScript({
+      expression: source1,
+      sourceURL: arguments.callee.name, persistScript: true
+    });
+    await Protocol.Profiler.enable();
+
+    // Start, run, stop.
+    await Protocol.Profiler.startTypeProfile();
+    Protocol.Runtime.runScript({scriptId});
+    await Protocol.Profiler.stopTypeProfile();
+
+    // Start, take. Should be empty, because no code was run.
+    await Protocol.Profiler.startTypeProfile();
+    let typeProfiles = await Protocol.Profiler.takeTypeProfile();
+    InspectorTest.logMessage(typeProfiles.result.result);
+    await Protocol.Profiler.stopTypeProfile();
+
+    Protocol.Profiler.disable();
+    await Protocol.Runtime.disable();
+  },
+  async function testTypeProfileWithoutStartingItFirst() {
+    Protocol.Runtime.enable();
+    let {result: {scriptId}} = await Protocol.Runtime.compileScript({ expression: source1,
+      sourceURL: arguments.callee.name, persistScript: true });
+    Protocol.Runtime.runScript({ scriptId });
+    await Protocol.Profiler.enable();
+
+    // This should return an error because type profile was never started.
+    let typeProfiles = await Protocol.Profiler.takeTypeProfile();
+    InspectorTest.logObject(typeProfiles.error.message);
+
+    Protocol.Profiler.disable();
+    await Protocol.Runtime.disable();
+  },
+  async function testTypeProfileAfterStoppingIt() {
+    Protocol.Runtime.enable();
+    let {result: {scriptId}} = await Protocol.Runtime.compileScript({ expression: source1,
+      sourceURL: arguments.callee.name, persistScript: true });
+    Protocol.Runtime.runScript({ scriptId });
+    await Protocol.Profiler.enable();
+    await Protocol.Profiler.startTypeProfile();
+
+    // Make sure that this turns off type profile.
+    await Protocol.Profiler.stopTypeProfile();
+
+    // This should return an error because type profile was stopped.
+    let typeProfiles = await Protocol.Profiler.takeTypeProfile();
+    InspectorTest.logObject(typeProfiles.error.message);
+
+    Protocol.Profiler.disable();
+    await Protocol.Runtime.disable();
+  },
+  async function testStartTypeProfileAfterRunning() {
+    Protocol.Runtime.enable();
+    let {result: {scriptId}} = await Protocol.Runtime.compileScript({
+      expression: source1,
+      sourceURL: arguments.callee.name, persistScript: true
+    });
+    Protocol.Runtime.runScript({scriptId});
+
+    await Protocol.Profiler.enable();
+    await Protocol.Profiler.startTypeProfile();
+
+    let typeProfiles = await Protocol.Profiler.takeTypeProfile();
+
+    // This should be empty because type profile was started after compilation.
+    // Only the outer script is annotated with return value "string" because
+    // that does not depend on runScript().
+    InspectorTest.logMessage(typeProfiles);
+
+    Protocol.Profiler.stopTypeProfile();
+    Protocol.Profiler.disable();
+    await Protocol.Runtime.disable();
+  },
+  async function testTypeProfileForTwoSources() {
+    Protocol.Runtime.enable();
+    let {result: {scriptId: scriptId1}} = await Protocol.Runtime.compileScript({
+      expression: source1,
+      sourceURL: arguments.callee.name, persistScript: true
+    });
+    let {result: {scriptId: scriptId2}} = await Protocol.Runtime.compileScript({
+      expression: source2,
+      sourceURL: arguments.callee.name, persistScript: true
+    });
+    await Protocol.Profiler.enable();
+
+    // Start, run different script, take.
+    await Protocol.Profiler.startTypeProfile();
+    Protocol.Runtime.runScript({scriptId: scriptId1});
+    Protocol.Runtime.runScript({scriptId: scriptId2});
+
+    let typeProfiles = await Protocol.Profiler.takeTypeProfile();
+    await session.logTypeProfile(typeProfiles.result.result[0],
+      source1);
+    await session.logTypeProfile(typeProfiles.result.result[1],
+      source2);
+
+    Protocol.Profiler.stopTypeProfile();
+    Protocol.Profiler.disable();
+    await Protocol.Runtime.disable();
+  }
+]);
diff --git a/src/v8/test/inspector/type-profiler/type-profile-with-classes-expected.txt b/src/v8/test/inspector/type-profiler/type-profile-with-classes-expected.txt
new file mode 100644
index 0000000..3c1cb36
--- /dev/null
+++ b/src/v8/test/inspector/type-profiler/type-profile-with-classes-expected.txt
@@ -0,0 +1,15 @@
+Test collecting type profile data with Profiler.takeTypeProfile.
+
+function f(/*number*/n) {
+/*undefined*/};
+f(5);
+function g(/*Object, number*/a, /*Array, number*/b, /*Flower, Object*/c) {
+  return 'bye';
+/*string*/};
+/*undefined*/class Tree {};
+/*Flower*/class Flower extends Tree{};
+var f = new Flower();
+f.constructor = {};
+f.constructor.name = "Not a flower.";
+g({}, [], f);
+g(3, 2.3, {a: 42});/*string*/
diff --git a/src/v8/test/inspector/type-profiler/type-profile-with-classes.js b/src/v8/test/inspector/type-profiler/type-profile-with-classes.js
new file mode 100644
index 0000000..b697ebf
--- /dev/null
+++ b/src/v8/test/inspector/type-profiler/type-profile-with-classes.js
@@ -0,0 +1,43 @@
+// Copyright 2017 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.
+
+// Flags: --type-profile
+
+const source =
+  `
+function f(n) {
+};
+f(5);
+function g(a, b, c) {
+  return 'bye';
+};
+class Tree {};
+class Flower extends Tree{};
+var f = new Flower();
+f.constructor = {};
+f.constructor.name = "Not a flower.";
+g({}, [], f);
+g(3, 2.3, {a: 42});
+`;
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Test collecting type profile data with Profiler.takeTypeProfile.");
+
+(async function testTypeProfile(next) {
+  await Protocol.Profiler.enable();
+  await Protocol.Profiler.startTypeProfile();
+
+  Protocol.Runtime.enable();
+  let {result: {scriptId}} = await Protocol.Runtime.compileScript({ expression: source,
+    sourceURL: arguments.callee.name, persistScript: true });
+
+  Protocol.Runtime.runScript({ scriptId });
+
+  let typeProfiles = await Protocol.Profiler.takeTypeProfile();
+  await session.logTypeProfile(typeProfiles.result.result[0],
+    source);
+
+  Protocol.Profiler.disable();
+  await Protocol.Runtime.disable();
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/type-profiler/type-profile-with-to-string-tag-expected.txt b/src/v8/test/inspector/type-profiler/type-profile-with-to-string-tag-expected.txt
new file mode 100644
index 0000000..fdba165
--- /dev/null
+++ b/src/v8/test/inspector/type-profiler/type-profile-with-to-string-tag-expected.txt
@@ -0,0 +1,16 @@
+Test collecting type profile data with Profiler.takeTypeProfile.
+
+function g(/*Object, number*/a, /*Array, number*/b, /*Dog, Object*/c) {
+  return 'bye';
+/*string*/};
+/*undefined*/class Tree {};
+/*Flower*/class Flower extends Tree{};
+var f = new Flower();
+// We store the type when a variable is used. If a toStringTag is
+// changes the type, we want to collect that changed feedback.
+// This tests ensures that we collect that information rather than
+// for example infer the types from the internal map, which wouldn't
+// know about a toStringTag.
+f[Symbol.toStringTag] = 'Dog';
+g({}, [], f);
+g(3, 2.3, {a: 42});/*string*/
diff --git a/src/v8/test/inspector/type-profiler/type-profile-with-to-string-tag.js b/src/v8/test/inspector/type-profiler/type-profile-with-to-string-tag.js
new file mode 100644
index 0000000..654f18a
--- /dev/null
+++ b/src/v8/test/inspector/type-profiler/type-profile-with-to-string-tag.js
@@ -0,0 +1,46 @@
+// Copyright 2017 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.
+
+// Flags: --type-profile
+
+const source =
+  `
+function g(a, b, c) {
+  return 'bye';
+};
+class Tree {};
+class Flower extends Tree{};
+var f = new Flower();
+// We store the type when a variable is used. If a toStringTag is
+// changes the type, we want to collect that changed feedback.
+// This tests ensures that we collect that information rather than
+// for example infer the types from the internal map, which wouldn't
+// know about a toStringTag.
+f[Symbol.toStringTag] = 'Dog';
+g({}, [], f);
+g(3, 2.3, {a: 42});
+`;
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Test collecting " +
+  "type profile data with Profiler.takeTypeProfile.");
+
+(async function testTypeProfile() {
+  await Protocol.Profiler.enable();
+  await Protocol.Profiler.startTypeProfile();
+
+  Protocol.Runtime.enable();
+  let {result: {scriptId}} = await Protocol.Runtime.compileScript({ expression: source,
+    sourceURL: arguments.callee.name, persistScript: true });
+  Protocol.Runtime.runScript({ scriptId });
+  await Protocol.Profiler.startTypeProfile();
+
+  let typeProfiles = await Protocol.Profiler.takeTypeProfile();
+  await session.logTypeProfile(typeProfiles.result.result[0],
+    source);
+
+  Protocol.Profiler.stopTypeProfile();
+  Protocol.Profiler.disable();
+  await Protocol.Runtime.disable();
+  InspectorTest.completeTest();
+})();
diff --git a/src/v8/test/inspector/type-profiler/type-profile.js b/src/v8/test/inspector/type-profiler/type-profile.js
new file mode 100644
index 0000000..e912a4b
--- /dev/null
+++ b/src/v8/test/inspector/type-profiler/type-profile.js
@@ -0,0 +1,39 @@
+// Copyright 2017 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.
+
+// Flags: --type-profile
+
+const source =
+  `
+function f(a, b, c) {
+  return 'bye';
+};
+f({}, [], true);
+f(3, 2.3, {a: 42});
+f(undefined, null, Symbol('hello'));
+`;
+
+let {session, contextGroup, Protocol} = InspectorTest.start("Test collecting type profile data with Profiler.takeTypeProfile.");
+
+(async function testTypeProfile() {
+  await Protocol.Profiler.enable();
+  await Protocol.Profiler.startTypeProfile();
+
+  Protocol.Runtime.enable();
+  let {result: {scriptId}} = await Protocol.Runtime.compileScript({
+    expression: source,
+    sourceURL: arguments.callee.name,
+    persistScript: true
+  });
+  Protocol.Runtime.runScript({ scriptId });
+
+  let typeProfiles = await Protocol.Profiler.takeTypeProfile();
+  await session.logTypeProfile(typeProfiles.result.result[0],
+    source);
+
+  Protocol.Profiler.stoptTypeProfile();
+  Protocol.Profiler.disable();
+  await Protocol.Runtime.disable();
+  InspectorTest.completeTest();
+})();