anchor.diff:     */
     Parser neg([String message]) => not(message).seq(any()).pick(1);
   
  -  Parser wrapper() => new WrapperParser(this);
  -
     /**
      * Returns a parser that discards the result of the receiver, and returns
      * a sub-string of the consumed elements in the string/list being parsed.
  
positive.code:     return new TrimmingParser(this, trimmer == null ? whitespace() : trimmer);
    }
  
    Parser end([String message]) {
      return new EndOfInputParser(this, message == null
          ? 'end of input expected' : message);
  
negative.code:     return this.map((List list) => indexes.map((index) => list[index]));
    }
  
    /**
     * Returns a parser that consumes the receiver one or more times separated
     * by the [separator] parser. The resulting parser returns a flat list of
     * the parse results of the receiver and interleaved with the parse result
     * of the separator parser. If the optional argument [includeSeparators] is
     * set to [:false:], then the separators are not included in the parse result.
     * If the optional argument [optionalSeparatorAtEnd] is set to [:true:] the
     * parser also accepts an optional separator at the end.
     */
    Parser separatedBy(Parser separator, {bool includeSeparators: true,
        bool optionalSeparatorAtEnd: false}) {
      var repeater = new SequenceParser([separator, this]).star();
      var parser = new SequenceParser(optionalSeparatorAtEnd
          ? [this, repeater, separator.optional(separator)]
          : [this, repeater]);
      return parser.map((List list) {
        var result = new List();
        result.add(list[0]);
        for (var i = 0; i < list[1].length; i += includeSeparators ? 1 : 2) {
          result.add(list[1][i]);
        }
        if (includeSeparators && optionalSeparatorAtEnd && list[2] != separator) {
          result.add(list[2]);
        }
        return result;
      });
  