anchor.diff:            ]).manyUntil(char(']')).record) ^
         (String label) => label.substring(0, label.length - 1);
   
  -  Parser get linkBalancedParenthesis => ((char("(") >
  +  static final Parser linkBalancedParenthesis = ((char("(") >
                 (noneOf('&\\\n ()') | escapedChar1 | htmlEntity1 | oneOf('&\\'))
                     .many1) <
             char(')')) ^
         (i) => "(${i.join()})";
   
  -  Parser get linkInlineDestination =>
  +  static final Parser linkInlineDestination =
         (((char("<") > noneOf("<>\n").many) < char(">")) |
                 (noneOf("&\\\n ()") |
                     escapedChar1 |
  
positive.code:         return false;
        });
  
    Parser<List<Inline>> _linkOrImage(bool isLink) =>
        new Parser<List<Inline>>((String s, Position pos) {
          ParseResult testRes = char('[').run(s, pos);
          if (!testRes.isSuccess) {
            return testRes;
          }
  
          // Try inline
          ParseResult labelRes = (isLink ? linkText : imageText).run(s, pos);
          if (!labelRes.isSuccess) {
            return labelRes;
          }
          if (isLink && labelRes.value.contains(new RegExp(r"^\s*$"))) {
            return fail.run(s, pos);
          }
          Inlines linkInlines = inlines.parse(labelRes.value, tabStop: tabStop);
          if (isLink && _isContainsLink(linkInlines)) {
            List<Inline> resValue = [new Str('[')];
            resValue.addAll(linkInlines);
            resValue.add(new Str(']'));
            return labelRes.copy(value: resValue);
          }
          ParseResult destRes = linkInline.run(s, labelRes.position);
          if (destRes.isSuccess) {
            // Links inside link content are not allowed
            if (isLink) {
              return destRes.copy(
                  value: [new InlineLink(linkInlines, destRes.value)]);
            } else {
              return destRes.copy(
                  value: [new InlineImage(linkInlines, destRes.value)]);
            }
          }
  
          // Try reference link
          ParseResult refRes = ((blankline | whitespaceChar).maybe > linkLabel)
              .run(s, labelRes.position);
          if (refRes.isSuccess) {
            String reference = refRes.value == "" ? labelRes.value : refRes.value;
            String normalizedReference = _normalizeReference(reference);
            Target target = _references[normalizedReference];
            if (target == null) {
              target = _options.linkResolver(normalizedReference, reference);
            }
            if (target != null) {
              if (isLink) {
                return refRes.copy(
                    value: [new ReferenceLink(reference, linkInlines, target)]);
              } else {
                return refRes.copy(
                    value: [new ReferenceImage(reference, linkInlines, target)]);
              }
            }
          } else {
            // Try again from beginning because reference couldn't contain brackets
            labelRes = linkLabel.run(s, pos);
            if (!labelRes.isSuccess) {
              return labelRes;
            }
            String normalizedReference = _normalizeReference(labelRes.value);
            Target target = _references[normalizedReference];
            if (target == null) {
              target = _options.linkResolver(normalizedReference, labelRes.value);
            }
            if (target != null) {
              if (isLink) {
                return labelRes.copy(value:
                    [new ReferenceLink(labelRes.value, linkInlines, target)]);
              } else {
                return labelRes.copy(value:
                    [new ReferenceImage(labelRes.value, linkInlines, target)]);
              }
            }
          }
  
          return fail.run(s, pos);
        });
  
    Parser<List<Inline>> get image => char('!') > _linkOrImage(false);
    Parser<List<Inline>> get link => _linkOrImage(true);
  
    List<String> allowedSchemes = <String>[
      "coap",
      "doi",
      "javascript",
  
negative.code:           (char("\n").notFollowedBy(spnl) ^ (_) => [new Str("\n")]);
  
    // TODO static ?
    static final Parser linkLabel = (char('[') >
            choice([
              whitespace,
              htmlEntity,
  