anchor.diff:    SetCommand(Debugger debugger)
         : super(debugger, 'set', []);
   
  +  static var _boeValues = ['all', 'none', 'unhandled'];
  +  static var _boolValues = ['false', 'true'];
  +
  +  static var _options = {
  +    'break-on-exception': [_boeValues,
  +                           _setBreakOnException,
  +                           (debugger, _) => debugger.breakOnException],
  +    'up-is-down': [_boolValues,
  +                   _setUpIsDown,
  +                   (debugger, _) => debugger.upIsDown],
  +  };
  +
  +  static Future _setBreakOnException(debugger, name, value) async {
  +    var result = await debugger.isolate.setExceptionPauseInfo(value);
  +    if (result.isError) {
  +      debugger.console.print(result.toString());
  +    } else {
  +      // Printing will occur elsewhere.
  +      debugger.breakOnException = value;
  +    }
  +  }
  +
  +  static Future _setUpIsDown(debugger, name, value) async {
  +    if (value == 'true') {
  +      debugger.upIsDown = true;
  +    } else {
  +      debugger.upIsDown = false;
  +    }
  +    debugger.console.print('${name} = ${value}');
  +  }
  +
     Future run(List<String> args) async {
  +    if (args.length == 0) {
  +      for (var name in _options.keys) {
  +        var getHandler = _options[name][2];
  +        var value = await getHandler(debugger, name);
  +        debugger.console.print("${name} = ${value}");
  +      }
  +    } else if (args.length == 1) {
  +      var name = args[0].trim();
  +      var optionInfo = _options[name];
  +      if (optionInfo == null) {
  +        debugger.console.print("unrecognized option: $name");
  +        return;
  +      } else {
  +        var getHandler = optionInfo[2];
  +        var value = await getHandler(debugger, name);
  +        debugger.console.print("${name} = ${value}");
  +      }
  +    } else if (args.length == 2) {
  +      var name = args[0].trim();
  +      var value = args[1].trim();
  +      var optionInfo = _options[name];
  +      if (optionInfo == null) {
  +        debugger.console.print("unrecognized option: $name");
  +        return;
  +      }
  +      var validValues = optionInfo[0];
  +      if (!validValues.contains(value)) {
  +        debugger.console.print("'${value}' is not in ${validValues}");
  +        return;
  +      }
  +      var setHandler = optionInfo[1];
  +      await setHandler(debugger, name, value);
  +    } else {
  +      debugger.console.print("set expects 0, 1, or 2 arguments");
  +    }
  +  }
  +
  +  Future<List<String>> complete(List<String> args) {
  +    if (args.length < 1 || args.length > 2) {
  +      return new Future.value([args.join('')]);
  +    }
  +    var result = [];
  +    if (args.length == 1) {
  +      var prefix = args[0];
  +      for (var option in _options.keys) {
  +        if (option.startsWith(prefix)) {
  +          result.add('${option} ');
  +        }
  +      }
  +    }
       if (args.length == 2) {
  -      var option = args[0].trim();
  -      if (option == 'break-on-exceptions') {
  -        var result = await debugger.isolate.setExceptionPauseInfo(args[1]);
  -        if (result.isError) {
  -          debugger.console.print(result.toString());
  -        }
  -      } else {
  -        debugger.console.print("unknown option '$option'");
  -      }
  -    } else {
  -      debugger.console.print("set expects 2 arguments");
  -    }
  +      var name = args[0].trim();
  +      var prefix = args[1];
  +      var optionInfo = _options[name];
  +      if (optionInfo != null) {
  +        var validValues = optionInfo[0];
  +        for (var value in validValues) {
  +          if (value.startsWith(prefix)) {
  +            result.add('${args[0]}${value} ');
  +          }
  +        }
  +      }
  +    }
  +    return new Future.value(result);
     }
   
     String helpShort =
         'Set a debugger option';
   
     String helpLong =
  -      'Set a debugger option'
  -      '\n'
  -      'Syntax: set break-on-exceptions "all" | "none" | "unhandled"\n';
  +      'Set a debugger option.\n'
  +      '\n'
  +      'Known options:\n'
  +      '  break-on-exceptions   # Should the debugger break on exceptions?\n'
  +      "                        # ${_boeValues}\n"
  +      '  up-is-down            # Reverse meaning of up/down commands?\n'
  +      "                        # ${_boolValues}\n"
  +      '\n'
  +      'Syntax: set                    # Display all option settings\n'
  +      '        set <option>           # Get current value for option\n'
  +      '        set <option> <value>   # Set value for option';
   }
   
   class BreakCommand extends DebuggerCommand {
  
positive.code:     _consolePrinter = new _ConsoleStreamPrinter(this);
    }
  
    VM get vm => page.app.vm;
  
    void updateIsolate(Isolate iso) {
      _isolate = iso;
      if (_isolate != null) {
        if ((exceptions != iso.exceptionsPauseInfo) &&
            (iso.exceptionsPauseInfo != null)) {
          exceptions = iso.exceptionsPauseInfo;
          console.print("Now pausing for $exceptions exceptions");
        }
  
        _isolate.reload().then((response) {
  
negative.code:           case KeyCode.PAGE_UP:
              e.preventDefault();
              try {
                debugger.upFrame(1);
              } on RangeError catch (e) {
                // Ignore.
              }
  