anchor.diff:      assert(program.libraries.isEmpty);
       Procedure mainMethod = program.mainMethod;
       Statement statementBlock = mainMethod.function.body;
  -    Continuation cont = new Continuation(statementBlock, new State.initial());
  -    visitor.trampolinedExecution(cont);
  +    StatementConfiguration configuration =
  +        new StatementConfiguration(statementBlock, new State.initial());
  +    visitor.trampolinedExecution(configuration);
     }
   }
   
  
positive.code:   }
  }
  
  /// Represent the continuation for execution of statement.
  class Continuation {
    final Statement statement;
    final State state;
  
    Continuation(this.statement, this.state);
  }
  
  /// Represents a labeled statement, the corresponding continuation and the
  /// enclosing label.
  class Label {
    final LabeledStatement statement;
    final Continuation continuation;
    final Label enclosingLabel;
  
    Label(this.statement, this.continuation, this.enclosingLabel);
  
    Label lookupLabel(LabeledStatement s) {
      if (identical(s, statement)) return this;
      assert(enclosingLabel != null);
      return enclosingLabel.lookupLabel(s);
    }
  }
  
  
negative.code: /// returned and applied
  /// - it returns with or without value, TBD
  /// - it throws, TBD
  class StatementExecuter extends StatementVisitor1<Configuration> {
    Evaluator evaluator = new Evaluator();
  
    void trampolinedExecution(Configuration configuration) {
      while (configuration != null) {
        configuration = configuration.step(this);
      }
    }
  
    Configuration exec(Statement statement, State state) =>
        statement.accept1(this, state);
    Configuration eval(Expression expression, ExpressionState state) =>
        evaluator.eval(expression, state);
  
    Configuration defaultStatement(Statement node, state) {
      throw notImplemented(
          m: "Execution is not implemented for statement:\n$node ");
    }
  
    Configuration visitInvalidStatement(InvalidStatement node, state) {
      throw "Invalid statement at ${node.location}";
    }
  
    Configuration visitExpressionStatement(ExpressionStatement node, state) {
      return new ExpressionConfiguration(
          node.expression, new ExpressionState.fromStatementState(state));
    }
  
    Configuration visitBlock(Block node, state) {
      if (node.statements.isEmpty) {
        return state.statementConfiguration;
      }
      State blockState =
          state.withEnvironment(new Environment(state.environment));
      StatementConfiguration configuration = state.statementConfiguration;
      for (Statement s in node.statements.reversed) {
        configuration = new StatementConfiguration(
            s, blockState.withConfiguration(configuration));
      }
      return configuration;
    }
  
    Configuration visitEmptyStatement(EmptyStatement node, state) {
      return state.statementConfiguration;
    }
  
    Configuration visitIfStatement(IfStatement node, state) {
      var expState = new ExpressionState.fromStatementState(state);
      var cont = new IfConditionContinuation(node.then, node.otherwise, state);
      return new ExpressionConfiguration(
          node.condition, expState.withContinuation(cont));
    }
  
    Configuration visitLabeledStatement(LabeledStatement node, state) {
      return new StatementConfiguration(node.body, state.withBreak(node));
    }
  
    Configuration visitBreakStatement(BreakStatement node, state) {
      return state.lookupLabel(node.target).configuration;
    }
  
    Configuration visitWhileStatement(WhileStatement node, state) {
      var expState = new ExpressionState.fromStatementState(state);
      var cont = new WhileConditionContinuation(node, state);
  
      return new ExpressionConfiguration(
          node.condition, expState.withContinuation(cont));
    }
  
    Configuration visitDoStatement(DoStatement node, state) {
      WhileStatement whileStatement =
          new WhileStatement(node.condition, node.body);
      StatementConfiguration configuration =
          new StatementConfiguration(whileStatement, state);
  
      return new StatementConfiguration(
          node.body, state.withConfiguration(configuration));
    }
  
    Configuration visitReturnStatement(ReturnStatement node, state) {
      assert(state.returnContinuation != null);
      // The new ExpressionState contains the next expression continuation.
      var expState = new ExpressionState.fromStatementState(state)
          .withContinuation(state.returnContinuation);
      return new ExpressionConfiguration(
          node.expression ?? new NullLiteral(), expState);
    }
  
    Configuration visitVariableDeclaration(VariableDeclaration node, state) {
      if (node.initializer != null) {
        var expState = new ExpressionState.fromStatementState(state);
        var cont = new VariableInitializerContinuation(
            node, state.environment, state.statementConfiguration);
        return new ExpressionConfiguration(
            node.initializer, expState.withContinuation(cont));
      }
      state.environment.expand(node, Value.nullInstance);
      return state.statementConfiguration;
    }
  }
  
  // ------------------------------------------------------------------------
  //                                VALUES
  // ------------------------------------------------------------------------
  
  typedef Value Getter(Value receiver);
  typedef void Setter(Value receiver, Value value);
  