Import Cobalt 13.102542

Change-Id: I6bda7b03a2e33edfd735efcb981e2a731696b90d
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']);
+}