Import latest markdown library from dartdoc
diff --git a/pkgs/markdown/lib/markdown.dart b/pkgs/markdown/lib/markdown.dart
index 0bcc777..01de970 100644
--- a/pkgs/markdown/lib/markdown.dart
+++ b/pkgs/markdown/lib/markdown.dart
@@ -5,19 +5,18 @@
 /// Parses text in a markdown-like format and renders to HTML.
 library markdown;
 
-import 'src/classify/dart.dart';
-
 // TODO(rnystrom): Use "package:" URL (#4968).
 part 'src/markdown/ast.dart';
 part 'src/markdown/block_parser.dart';
 part 'src/markdown/html_renderer.dart';
 part 'src/markdown/inline_parser.dart';
 
-typedef String ClassifierFunction(String syntax, String source); 
+typedef Node Resolver(String name);
 
 /// Converts the given string of markdown to HTML.
-String markdownToHtml(String markdown, [ClassifierFunction classifier]) {
-  final document = new Document(classifier);
+String markdownToHtml(String markdown, {inlineSyntaxes, linkResolver}) {
+  final document = new Document(inlineSyntaxes: inlineSyntaxes,
+      linkResolver: linkResolver);
 
   // Replace windows line endings with unix line endings, and split.
   final lines = markdown.replaceAll('\r\n','\n').split('\n');
@@ -33,26 +32,15 @@
              .replaceAll('>', '>');
 }
 
-var _implicitLinkResolver;
-
-Node setImplicitLinkResolver(Node resolver(String text)) {
-  _implicitLinkResolver = resolver;
-}
-
 /// Maintains the context needed to parse a markdown document.
 class Document {
   final Map<String, Link> refLinks;
-  final ClassifierFunction classifier;
-  
-  Document(this.classifier)
+  List<InlineSyntax> inlineSyntaxes;
+  Resolver linkResolver;
+
+  Document({this.inlineSyntaxes, this.linkResolver})
     : refLinks = <String, Link>{};
-  
-  String classify(String syntax, String source) {
-    if (syntax == 'dart') return classifyDart(source);
-    if (classifier == null) return source;
-    return classifier(syntax, source);
-  }
-    
+
   parseRefLinks(List<String> lines) {
     // This is a hideous regex. It matches:
     // [id]: http:foo.com "some title"
diff --git a/pkgs/markdown/lib/src/markdown/block_parser.dart b/pkgs/markdown/lib/src/markdown/block_parser.dart
index b59c795..42b9353 100644
--- a/pkgs/markdown/lib/src/markdown/block_parser.dart
+++ b/pkgs/markdown/lib/src/markdown/block_parser.dart
@@ -20,7 +20,7 @@
 final _RE_INDENT = new RegExp(r'^(?:    |\t)(.*)$');
 
 /// GitHub style triple quoted code block.
-final _RE_CODE = new RegExp(r'^```(\w*)$');
+final _RE_CODE = new RegExp(r'^```(.*)$');
 
 /// Three or more hyphens, asterisks or underscores by themselves. Note that
 /// a line like `----` is valid as both HR and SETEXT. In case of a tie,
@@ -238,9 +238,9 @@
     childLines.add('');
 
     // Escape the code.
-    final escaped = childLines.join('n');//classifySource();
+    final escaped = escapeHtml(childLines.join('\n'));
 
-    return new Element.text('pre', escaped);
+    return new Element('pre', [new Element.text('code', escaped)]);
   }
 }
 
@@ -274,9 +274,9 @@
     childLines.add('');
 
     // Escape the code.
-    final escaped = parser.document.classify(syntax, childLines.join('\n').trim());
+    final escaped = escapeHtml(childLines.join('\n'));
 
-    return new Element.text('pre', escaped);
+    return new Element('pre', [new Element.text('code', escaped)]);
   }
 }
 
@@ -315,7 +315,7 @@
       parser.advance();
     }
 
-    return new Text(Strings.join(childLines, '\n'));
+    return new Text(childLines.join('\n'));
   }
 }
 
@@ -497,8 +497,7 @@
       parser.advance();
     }
 
-    final contents = parser.document.parseInline(
-        Strings.join(childLines, '\n'));
+    final contents = parser.document.parseInline(childLines.join('\n'));
     return new Element('p', contents);
   }
 }
diff --git a/pkgs/markdown/lib/src/markdown/html_renderer.dart b/pkgs/markdown/lib/src/markdown/html_renderer.dart
index 1695e96..5494394 100644
--- a/pkgs/markdown/lib/src/markdown/html_renderer.dart
+++ b/pkgs/markdown/lib/src/markdown/html_renderer.dart
@@ -24,17 +24,17 @@
   }
 
   void visitText(Text text) {
-    buffer.add(text.text);
+    buffer.write(text.text);
   }
 
   bool visitElementBefore(Element element) {
     // Hackish. Separate block-level elements with newlines.
     if (!buffer.isEmpty &&
         _BLOCK_TAGS.firstMatch(element.tag) != null) {
-      buffer.add('\n');
+      buffer.write('\n');
     }
 
-    buffer.add('<${element.tag}');
+    buffer.write('<${element.tag}');
 
     // Sort the keys so that we generate stable output.
     // TODO(rnystrom): This assumes keys returns a fresh mutable
@@ -42,20 +42,20 @@
     final attributeNames = element.attributes.keys.toList();
     attributeNames.sort((a, b) => a.compareTo(b));
     for (final name in attributeNames) {
-      buffer.add(' $name="${element.attributes[name]}"');
+      buffer.write(' $name="${element.attributes[name]}"');
     }
 
     if (element.isEmpty) {
       // Empty element like <hr/>.
-      buffer.add(' />');
+      buffer.write(' />');
       return false;
     } else {
-      buffer.add('>');
+      buffer.write('>');
       return true;
     }
   }
 
   void visitElementAfter(Element element) {
-    buffer.add('</${element.tag}>');
+    buffer.write('</${element.tag}>');
   }
 }
diff --git a/pkgs/markdown/lib/src/markdown/inline_parser.dart b/pkgs/markdown/lib/src/markdown/inline_parser.dart
index af42e3e..d3ec7ae 100644
--- a/pkgs/markdown/lib/src/markdown/inline_parser.dart
+++ b/pkgs/markdown/lib/src/markdown/inline_parser.dart
@@ -7,56 +7,51 @@
 /// Maintains the internal state needed to parse inline span elements in
 /// markdown.
 class InlineParser {
-  static List<InlineSyntax> get syntaxes {
-    // Lazy initialize.
-    if (_syntaxes == null) {
-      _syntaxes = <InlineSyntax>[
-        // This first regexp matches plain text to accelerate parsing.  It must
-        // be written so that it does not match any prefix of any following
-        // syntax.  Most markdown is plain text, so it is faster to match one
-        // regexp per 'word' rather than fail to match all the following regexps
-        // at each non-syntax character position.  It is much more important
-        // that the regexp is fast than complete (for example, adding grouping
-        // is likely to slow the regexp down enough to negate its benefit).
-        // Since it is purely for optimization, it can be removed for debugging.
-        new TextSyntax(r'\s*[A-Za-z0-9]+'),
+  static List<InlineSyntax>  defaultSyntaxes = <InlineSyntax>[
+    // This first regexp matches plain text to accelerate parsing.  It must
+    // be written so that it does not match any prefix of any following
+    // syntax.  Most markdown is plain text, so it is faster to match one
+    // regexp per 'word' rather than fail to match all the following regexps
+    // at each non-syntax character position.  It is much more important
+    // that the regexp is fast than complete (for example, adding grouping
+    // is likely to slow the regexp down enough to negate its benefit).
+    // Since it is purely for optimization, it can be removed for debugging.
 
-        // The real syntaxes.
+    // TODO(amouravski): this regex will glom up any custom syntaxes unless
+    // they're at the beginning.
+    new TextSyntax(r'\s*[A-Za-z0-9]+'),
 
-        new AutolinkSyntax(),
-        new LinkSyntax(),
-        // "*" surrounded by spaces is left alone.
-        new TextSyntax(r' \* '),
-        // "_" surrounded by spaces is left alone.
-        new TextSyntax(r' _ '),
-        // Leave already-encoded HTML entities alone. Ensures we don't turn
-        // "&amp;" into "&amp;amp;"
-        new TextSyntax(r'&[#a-zA-Z0-9]*;'),
-        // Encode "&".
-        new TextSyntax(r'&', sub: '&amp;'),
-        // Encode "<". (Why not encode ">" too? Gruber is toying with us.)
-        new TextSyntax(r'<', sub: '&lt;'),
-        // Parse "**strong**" tags.
-        new TagSyntax(r'\*\*', tag: 'strong'),
-        // Parse "__strong__" tags.
-        new TagSyntax(r'__', tag: 'strong'),
-        // Parse "*emphasis*" tags.
-        new TagSyntax(r'\*', tag: 'em'),
-        // Parse "_emphasis_" tags.
-        // TODO(rnystrom): Underscores in the middle of a word should not be
-        // parsed as emphasis like_in_this.
-        new TagSyntax(r'_', tag: 'em'),
-        // Parse inline code within double backticks: "``code``".
-        new CodeSyntax(r'``\s?((?:.|\n)*?)\s?``'),
-        // Parse inline code within backticks: "`code`".
-        new CodeSyntax(r'`([^`]*)`')
-      ];
-    }
+    // The real syntaxes.
 
-    return _syntaxes;
-  }
-
-  static List<InlineSyntax> _syntaxes;
+    new AutolinkSyntax(),
+    new LinkSyntax(),
+    // "*" surrounded by spaces is left alone.
+    new TextSyntax(r' \* '),
+    // "_" surrounded by spaces is left alone.
+    new TextSyntax(r' _ '),
+    // Leave already-encoded HTML entities alone. Ensures we don't turn
+    // "&amp;" into "&amp;amp;"
+    new TextSyntax(r'&[#a-zA-Z0-9]*;'),
+    // Encode "&".
+    new TextSyntax(r'&', sub: '&amp;'),
+    // Encode "<". (Why not encode ">" too? Gruber is toying with us.)
+    new TextSyntax(r'<', sub: '&lt;'),
+    // Parse "**strong**" tags.
+    new TagSyntax(r'\*\*', tag: 'strong'),
+    // Parse "__strong__" tags.
+    new TagSyntax(r'__', tag: 'strong'),
+    // Parse "*emphasis*" tags.
+    new TagSyntax(r'\*', tag: 'em'),
+    // Parse "_emphasis_" tags.
+    // TODO(rnystrom): Underscores in the middle of a word should not be
+    // parsed as emphasis like_in_this.
+    new TagSyntax(r'_', tag: 'em'),
+    // Parse inline code within double backticks: "``code``".
+    new CodeSyntax(r'``\s?((?:.|\n)*?)\s?``'),
+    // Parse inline code within backticks: "`code`".
+    new CodeSyntax(r'`([^`]*)`')
+    // We will add the LinkSyntax once we know about the specific link resolver.
+  ];
 
   /// The string of markdown being parsed.
   final String source;
@@ -64,6 +59,8 @@
   /// The markdown document this parser is parsing.
   final Document document;
 
+  List<InlineSyntax> syntaxes;
+
   /// The current read position.
   int pos = 0;
 
@@ -73,7 +70,18 @@
   final List<TagState> _stack;
 
   InlineParser(this.source, this.document)
-    : _stack = <TagState>[];
+    : _stack = <TagState>[] {
+    /// User specified syntaxes will be the first syntaxes to be evaluated.
+    if (document.inlineSyntaxes != null) {
+      syntaxes = [];
+      syntaxes.addAll(document.inlineSyntaxes);
+      syntaxes.addAll(defaultSyntaxes);
+    } else {
+      syntaxes = defaultSyntaxes;
+    }
+    // Custom link resolver goes after the generic text syntax.
+    syntaxes.insert(1, new LinkSyntax(linkResolver: document.linkResolver));
+  }
 
   List<Node> parse() {
     // Make a fake top tag to hold the results.
@@ -236,6 +244,8 @@
 
 /// Matches inline links like `[blah] [id]` and `[blah] (url)`.
 class LinkSyntax extends TagSyntax {
+  Resolver linkResolver;
+
   /// The regex for the end of a link needs to handle both reference style and
   /// inline styles as well as optional titles for inline links. To make that
   /// a bit more palatable, this breaks it into pieces.
@@ -253,7 +263,7 @@
     // 4: Contains the title, if present, for an inline link.
   }
 
-  LinkSyntax()
+  LinkSyntax({this.linkResolver})
     : super(r'\[', end: linkPattern);
 
   bool onMatchEnd(InlineParser parser, Match match, TagState state) {
@@ -263,10 +273,10 @@
     // If we didn't match refLink or inlineLink, then it means there was
     // nothing after the first square bracket, so it isn't a normal markdown
     // link at all. Instead, we allow users of the library to specify a special
-    // resolver function ([setImplicitLinkResolver]) that may choose to handle
+    // resolver function ([linkResolver]) that may choose to handle
     // this. Otherwise, it's just treated as plain text.
     if ((match[1] == null) || (match[1] == '')) {
-      if (_implicitLinkResolver == null) return false;
+      if (linkResolver == null) return false;
 
       // Only allow implicit links if the content is just text.
       // TODO(rnystrom): Do we want to relax this?
@@ -276,7 +286,7 @@
       Text link = state.children[0];
 
       // See if we have a resolver that will generate a link for us.
-      final node = _implicitLinkResolver(link.text);
+      final node = linkResolver(link.text);
       if (node == null) return false;
 
       parser.addNode(node);
@@ -376,9 +386,8 @@
     int index = parser._stack.indexOf(this);
 
     // Remove the unmatched children.
-    final unmatchedTags = parser._stack.getRange(index + 1,
-        parser._stack.length - index - 1);
-    parser._stack.removeRange(index + 1, parser._stack.length - index - 1);
+    final unmatchedTags = parser._stack.sublist(index + 1);
+    parser._stack.removeRange(index + 1, parser._stack.length);
 
     // Flatten them out onto this tag.
     for (final unmatched in unmatchedTags) {