Better escaping of $ and "
diff --git a/compiler/psi/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java b/compiler/psi/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java
index cac5ef6..7cd3bc8 100644
--- a/compiler/psi/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java
+++ b/compiler/psi/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java
@@ -1,4 +1,5 @@
-/* The following code was generated by JFlex 1.7.0 tweaked for IntelliJ platform */
+// Generated by JFlex 1.9.2 http://jflex.de/  (tweaked for IntelliJ platform)
+// source: src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex
 
 package org.jetbrains.kotlin.kdoc.lexer;
 
@@ -10,11 +11,6 @@
 import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag;
 
 
-/**
- * This class is a scanner generated by 
- * <a href="http://www.jflex.de/">JFlex</a> 1.7.0
- * from the specification file <tt>/Users/victor.petukhov/IdeaProjects/kotlin-jps/compiler/psi/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex</tt>
- */
 class _KDocLexer implements FlexLexer {
 
   /** This character denotes the end of file */
@@ -41,115 +37,260 @@
    *                  at the beginning of a line
    * l is of the form l = 2*k, k a non negative integer
    */
-  private static final int ZZ_LEXSTATE[] = { 
+  private static final int ZZ_LEXSTATE[] = {
      0,  0,  1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  7, 
      8,  8,  6, 6
   };
 
-  /** 
-   * Translates characters to character classes
-   * Chosen bits are [12, 6, 3]
-   * Total runtime size is 12752 bytes
+  /**
+   * Top-level table for translating characters to character classes
    */
-  public static int ZZ_CMAP(int ch) {
-    return ZZ_CMAP_A[(ZZ_CMAP_Y[(ZZ_CMAP_Z[ch>>9]<<6)|((ch>>3)&0x3f)]<<3)|(ch&0x7)];
+  private static final int [] ZZ_CMAP_TOP = zzUnpackcmap_top();
+
+  private static final String ZZ_CMAP_TOP_PACKED_0 =
+    "\1\0\1\u0100\1\u0200\1\u0300\1\u0400\1\u0500\1\u0600\1\u0700"+
+    "\1\u0800\1\u0900\1\u0a00\1\u0b00\1\u0c00\1\u0d00\1\u0e00\1\u0f00"+
+    "\1\u1000\1\u0100\1\u1100\1\u1200\1\u1300\1\u0100\1\u1400\1\u1500"+
+    "\1\u1600\1\u1700\1\u1800\1\u1900\1\u1a00\1\u1b00\1\u0100\1\u1c00"+
+    "\1\u1d00\1\u1e00\12\u1f00\1\u2000\1\u2100\1\u2200\1\u1f00\1\u2300"+
+    "\1\u2400\2\u1f00\31\u0100\1\u1b00\121\u0100\1\u2500\4\u0100\1\u2600"+
+    "\1\u0100\1\u2700\1\u2800\1\u2900\1\u2a00\1\u2b00\1\u2c00\53\u0100"+
+    "\1\u2d00\10\u2e00\31\u1f00\1\u0100\1\u2f00\1\u3000\1\u0100\1\u3100"+
+    "\1\u3200\1\u3300\1\u3400\1\u3500\1\u3600\1\u3700\1\u3800\1\u3900"+
+    "\1\u0100\1\u3a00\1\u3b00\1\u3c00\1\u3d00\1\u3e00\1\u3f00\1\u4000"+
+    "\1\u4100\1\u4200\1\u4300\1\u4400\1\u4500\1\u4600\1\u4700\1\u4800"+
+    "\1\u4900\1\u4a00\1\u4b00\1\u4c00\1\u4d00\1\u1f00\1\u4e00\1\u4f00"+
+    "\1\u5000\1\u5100\3\u0100\1\u5200\1\u5300\1\u5400\12\u1f00\4\u0100"+
+    "\1\u5500\17\u1f00\2\u0100\1\u5600\41\u1f00\2\u0100\1\u5700\1\u5800"+
+    "\2\u1f00\1\u5900\1\u5a00\27\u0100\1\u5b00\4\u0100\1\u5c00\1\u5d00"+
+    "\42\u1f00\1\u0100\1\u5e00\1\u5f00\11\u1f00\1\u6000\27\u1f00\1\u6100"+
+    "\1\u6200\1\u6300\1\u6400\11\u1f00\1\u6500\1\u6600\5\u1f00\1\u6700"+
+    "\1\u6800\2\u1f00\1\u6900\1\u1f00\1\u6a00\21\u1f00\246\u0100\1\u6b00"+
+    "\20\u0100\1\u6c00\1\u6d00\25\u0100\1\u6e00\34\u0100\1\u6f00\14\u1f00"+
+    "\2\u0100\1\u7000\5\u1f00\23\u0100\1\u7100\u0dec\u1f00";
+
+  private static int [] zzUnpackcmap_top() {
+    int [] result = new int[4352];
+    int offset = 0;
+    offset = zzUnpackcmap_top(ZZ_CMAP_TOP_PACKED_0, offset, result);
+    return result;
   }
 
-  /* The ZZ_CMAP_Z table has 2176 entries */
-  static final char ZZ_CMAP_Z[] = zzUnpackCMap(
-    "\1\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1\16\1\17\1"+
-    "\20\5\21\1\22\1\23\1\24\1\21\14\25\1\26\50\25\1\27\2\25\1\30\1\31\1\32\1\33"+
-    "\25\25\1\34\20\21\1\35\1\36\1\37\1\40\1\41\1\42\1\43\1\21\1\44\1\45\1\46\1"+
-    "\21\1\47\2\21\1\50\4\21\1\25\1\51\1\52\5\21\2\25\1\53\31\21\1\25\1\54\1\21"+
-    "\1\55\40\21\1\56\21\21\1\57\1\60\13\21\1\61\10\21\123\25\1\62\7\25\1\63\1"+
-    "\64\37\21\1\25\1\64\u0702\21");
+  private static int zzUnpackcmap_top(String packed, int offset, int [] result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
 
-  /* The ZZ_CMAP_Y table has 3392 entries */
-  static final char ZZ_CMAP_Y[] = zzUnpackCMap(
-    "\1\0\1\1\2\0\1\2\1\3\1\4\1\5\1\6\2\7\1\10\1\11\2\7\1\12\1\13\3\0\1\14\1\15"+
-    "\1\16\1\15\2\7\1\17\3\7\1\17\71\7\1\20\1\7\1\21\1\0\1\22\1\23\20\0\1\24\1"+
-    "\14\1\25\1\26\2\7\1\27\11\7\1\30\21\7\1\21\1\31\23\7\1\0\1\32\3\7\1\17\1\33"+
-    "\1\32\4\7\1\34\10\0\3\7\2\35\2\0\1\36\2\0\5\7\1\35\3\0\1\37\1\32\13\7\1\40"+
-    "\1\0\1\41\1\37\1\0\1\42\2\0\1\43\3\7\3\0\1\44\12\7\1\45\1\0\1\33\2\0\1\31"+
-    "\3\7\1\35\1\46\1\15\2\7\1\45\1\15\1\47\1\50\2\0\3\7\1\50\10\0\1\43\1\22\12"+
-    "\0\1\51\6\7\1\52\2\0\1\50\1\7\1\21\1\0\2\32\1\44\1\53\1\54\2\7\1\43\1\55\1"+
-    "\52\1\0\1\25\1\0\1\56\1\21\1\0\1\57\1\36\1\44\1\60\1\54\2\7\1\43\1\61\1\21"+
-    "\3\0\1\62\2\0\1\63\1\0\1\44\1\30\1\27\2\7\1\43\1\64\1\52\2\0\1\50\1\0\1\21"+
-    "\1\0\1\33\1\0\1\44\1\53\1\54\2\7\1\43\1\64\1\52\3\0\1\56\1\21\1\0\1\33\1\0"+
-    "\1\65\1\66\1\67\1\70\1\71\1\66\1\7\1\21\2\0\1\50\4\0\1\33\1\44\1\24\1\43\2"+
-    "\7\1\43\1\72\1\52\3\0\2\21\3\0\1\44\1\24\1\43\2\7\1\43\1\72\1\52\3\0\1\25"+
-    "\1\21\1\0\1\73\1\0\1\44\1\24\1\43\4\7\1\74\1\0\1\25\2\0\1\21\2\0\1\31\1\44"+
-    "\1\7\1\17\1\31\2\7\1\27\1\40\1\17\7\0\1\32\5\7\1\75\1\34\1\17\7\0\1\76\1\77"+
-    "\1\51\1\32\1\100\1\101\1\75\1\16\1\102\2\0\1\51\4\0\1\50\7\0\1\7\1\32\3\7"+
-    "\1\22\3\0\1\22\16\0\5\7\1\35\1\0\1\34\2\0\1\45\1\14\1\103\1\37\1\104\1\7\1"+
-    "\21\1\25\2\0\4\7\1\30\1\16\5\7\1\105\51\7\1\67\1\17\1\67\5\7\1\67\4\7\1\67"+
-    "\1\17\1\67\1\7\1\17\7\7\1\67\10\7\1\35\4\0\2\7\2\0\12\7\1\22\1\0\1\32\114"+
-    "\7\1\53\2\7\1\32\2\7\1\35\11\7\1\66\1\50\1\0\1\7\1\24\1\21\1\0\2\7\1\21\1"+
-    "\0\2\7\1\21\1\0\1\7\1\24\1\50\1\0\6\7\1\57\3\0\1\34\1\71\10\0\13\7\1\0\5\7"+
-    "\1\106\10\7\1\45\1\0\3\7\1\22\6\0\3\7\1\45\1\22\1\0\5\7\1\57\2\0\1\32\7\0"+
-    "\2\7\1\17\1\0\6\7\1\22\11\0\1\34\13\0\1\44\5\7\1\57\1\0\1\44\1\57\6\0\1\107"+
-    "\3\7\1\50\1\37\1\0\1\31\4\7\1\45\3\0\4\7\1\57\4\0\1\44\1\0\1\31\3\7\1\45\15"+
-    "\0\1\110\1\111\1\0\30\7\10\0\42\7\2\45\4\7\2\45\1\7\1\112\3\7\1\45\6\7\1\24"+
-    "\1\102\1\113\1\22\1\114\1\57\1\7\1\22\1\113\1\22\5\0\1\115\1\0\1\34\1\50\1"+
-    "\0\1\47\3\0\1\33\1\34\2\0\1\7\1\22\3\7\1\35\10\0\1\116\1\31\1\40\1\117\1\23"+
-    "\1\120\1\7\1\121\1\44\1\122\2\0\5\7\1\50\116\0\5\7\1\17\5\7\1\17\20\7\1\22"+
-    "\1\123\1\124\1\0\4\7\1\30\1\16\7\7\1\34\2\0\2\7\1\17\1\0\10\17\11\0\1\34\72"+
-    "\0\1\44\3\0\1\32\1\21\1\117\1\22\1\32\11\7\1\17\1\44\1\32\12\7\1\105\1\44"+
-    "\4\7\1\45\1\32\12\7\1\17\2\0\3\7\1\35\6\0\170\7\1\45\11\0\71\7\1\22\6\0\21"+
-    "\7\1\22\10\0\5\7\1\45\41\7\1\22\2\7\1\0\1\124\2\0\5\7\1\17\1\0\1\34\3\7\1"+
-    "\0\12\7\4\0\1\34\1\7\1\31\14\7\1\125\1\57\1\0\1\7\1\35\11\0\1\7\1\126\1\105"+
-    "\2\7\1\35\2\0\1\50\6\7\1\57\1\0\1\31\5\7\1\57\7\0\1\31\1\36\1\0\1\31\2\7\1"+
-    "\45\1\0\2\7\1\17\3\0\3\7\1\22\1\51\5\7\1\35\2\0\1\34\6\0\5\7\1\50\2\0\1\105"+
-    "\1\57\2\0\2\7\1\17\1\15\6\7\1\103\1\117\1\106\2\0\1\127\1\7\1\35\1\63\1\0"+
-    "\3\130\1\0\2\17\22\0\4\7\1\35\3\0\64\7\1\57\1\0\2\7\1\17\1\107\5\7\1\57\40"+
-    "\0\55\7\1\45\15\7\1\21\4\0\1\17\1\0\1\107\1\131\1\7\1\43\1\17\1\102\1\132"+
-    "\15\7\1\21\3\0\1\107\54\7\1\45\2\0\10\7\1\31\6\7\5\0\1\7\1\22\6\0\1\71\2\0"+
-    "\1\44\3\0\1\33\1\24\20\7\1\22\1\47\3\0\1\32\2\7\1\60\1\32\2\7\1\35\1\37\12"+
-    "\7\1\17\3\31\1\63\1\111\3\0\1\7\1\72\2\7\1\17\2\7\1\133\1\7\1\45\1\7\1\45"+
-    "\4\0\17\7\1\35\10\0\6\7\1\22\41\0\3\7\1\22\6\7\1\50\5\0\3\7\1\17\2\0\3\7\1"+
-    "\35\6\0\3\7\1\45\4\7\1\57\1\7\1\117\5\0\23\7\1\45\54\0\1\45\1\43\4\7\1\30"+
-    "\1\134\2\7\1\45\25\0\2\7\1\45\1\0\3\7\1\21\10\0\7\7\1\37\10\0\1\50\1\0\1\72"+
-    "\1\32\2\7\1\57\5\0\3\7\1\22\20\0\6\7\1\45\1\0\2\7\1\45\1\0\2\7\1\35\21\0\11"+
-    "\7\1\50\66\0\1\107\6\7\11\0\1\107\5\7\4\0\3\7\1\50\2\0\1\107\3\7\1\17\13\0"+
-    "\1\107\5\7\1\35\1\0\1\135\27\0\5\7\1\35\52\0\55\7\1\17\22\0\14\7\1\35\63\0"+
-    "\5\7\1\17\72\0\7\7\1\50\130\0\10\7\1\22\1\0\1\50\7\0\1\107\1\7\14\0\1\21\77"+
-    "\0\12\7\1\24\10\7\1\24\1\136\1\110\1\7\1\137\1\72\7\7\1\30\1\140\2\24\3\7"+
-    "\1\141\1\102\1\31\1\43\51\7\1\45\3\7\1\43\2\7\1\105\3\7\1\105\2\7\1\24\3\7"+
-    "\1\24\2\7\1\17\3\7\1\17\3\7\1\43\3\7\1\43\2\7\1\105\1\57\6\0\1\72\3\7\1\76"+
-    "\1\32\1\105\1\142\1\116\1\143\1\76\1\112\1\76\2\105\1\62\1\7\1\27\1\7\1\57"+
-    "\1\144\1\27\1\7\1\57\50\0\32\7\1\17\5\0\106\7\1\22\1\0\33\7\1\45\74\0");
 
-  /* The ZZ_CMAP_A table has 808 entries */
-  static final char ZZ_CMAP_A[] = zzUnpackCMap(
-    "\11\0\1\1\1\11\1\12\1\13\1\12\2\0\1\17\3\0\1\3\3\0\1\21\1\22\1\15\3\0\1\4"+
-    "\1\14\12\2\6\0\1\16\22\3\1\5\1\20\1\6\1\0\1\3\1\7\12\3\3\0\1\10\6\0\1\12\4"+
-    "\0\4\3\4\0\1\3\12\0\1\3\2\0\7\3\1\0\2\3\4\0\4\3\6\0\5\3\7\0\1\3\1\0\1\3\1"+
-    "\0\5\3\1\0\2\3\6\0\1\3\1\0\3\3\1\0\1\3\1\0\4\3\1\0\13\3\1\0\1\3\2\0\6\3\1"+
-    "\0\7\3\1\0\1\3\15\0\4\3\10\0\1\3\12\0\6\3\1\0\1\3\7\0\2\3\3\0\3\3\2\0\2\3"+
-    "\1\0\6\3\5\0\11\3\6\0\2\3\6\0\1\3\3\0\1\3\13\0\6\3\3\0\1\3\2\0\5\3\2\0\2\3"+
-    "\2\0\6\3\1\0\1\3\3\0\2\3\4\0\2\3\1\0\5\3\4\0\3\3\4\0\2\3\1\0\2\3\1\0\2\3\2"+
-    "\0\4\3\1\0\1\3\3\0\3\3\3\0\1\3\1\0\2\3\1\0\3\3\3\0\1\3\1\0\6\3\3\0\3\3\1\0"+
-    "\4\3\3\0\2\3\1\0\1\3\1\0\2\3\3\0\2\3\3\0\4\3\1\0\3\3\1\0\2\3\5\0\3\3\2\0\1"+
-    "\3\2\0\1\3\1\0\2\3\5\0\2\3\1\0\1\3\2\0\2\3\1\0\1\3\2\0\1\3\3\0\3\3\1\0\1\3"+
-    "\1\0\1\3\2\0\2\3\1\0\10\3\1\0\1\3\2\0\1\3\3\0\2\3\1\0\1\3\4\0\6\3\1\0\5\3"+
-    "\1\0\1\3\10\0\5\3\1\0\4\3\1\0\4\3\3\0\2\3\2\0\1\3\1\0\1\3\1\0\1\3\1\0\1\3"+
-    "\2\0\3\3\1\0\6\3\2\0\2\3\2\12\10\0\1\3\4\0\1\3\1\0\5\3\2\0\1\3\1\0\4\3\1\0"+
-    "\3\3\2\0\6\3\4\0\1\3\4\0\4\3\3\0\2\3\4\0\1\3\2\0\4\3\1\0\2\3\1\0\3\3\1\0\1"+
-    "\3\3\0\3\3\3\0\6\3\6\0\1\3\1\0\3\3\1\0\2\3\1\0\5\3\1\0\2\3\1\0\2\3\3\0\1\3"+
-    "\2\0\1\3\1\0\4\3\5\0\1\3\2\0\2\3\1\0\2\3\1\0\1\3\1\0\6\3\2\0\5\3\1\0\4\3\2"+
-    "\0\1\3\1\0\1\3\5\0\1\3\1\0\1\3\1\0\3\3\1\0\3\3\1\0\3\3");
+  /**
+   * Second-level tables for translating characters to character classes
+   */
+  private static final int [] ZZ_CMAP_BLOCKS = zzUnpackcmap_blocks();
 
-  /** 
+  private static final String ZZ_CMAP_BLOCKS_PACKED_0 =
+    "\11\0\1\1\1\2\1\3\1\4\1\3\22\0\1\5"+
+    "\3\0\1\6\3\0\1\7\1\10\1\11\3\0\1\12"+
+    "\1\13\12\14\6\0\1\15\32\6\1\16\1\17\1\20"+
+    "\1\0\1\6\1\21\32\6\3\0\1\22\6\0\1\3"+
+    "\34\0\4\6\4\0\1\6\12\0\1\6\4\0\1\6"+
+    "\5\0\27\6\1\0\37\6\1\0\u01ca\6\4\0\14\6"+
+    "\16\0\5\6\7\0\1\6\1\0\1\6\201\0\5\6"+
+    "\1\0\2\6\2\0\4\6\1\0\1\6\6\0\1\6"+
+    "\1\0\3\6\1\0\1\6\1\0\24\6\1\0\123\6"+
+    "\1\0\213\6\10\0\246\6\1\0\46\6\2\0\1\6"+
+    "\6\0\51\6\6\0\1\6\100\0\33\6\4\0\4\6"+
+    "\30\0\1\6\24\0\53\6\43\0\2\6\1\0\143\6"+
+    "\1\0\1\6\17\0\2\6\7\0\2\6\12\0\3\6"+
+    "\2\0\1\6\20\0\1\6\1\0\36\6\35\0\131\6"+
+    "\13\0\1\6\30\0\41\6\11\0\2\6\4\0\1\6"+
+    "\3\0\30\6\4\0\1\6\11\0\1\6\3\0\1\6"+
+    "\27\0\31\6\7\0\13\6\65\0\25\6\1\0\22\6"+
+    "\74\0\66\6\3\0\1\6\22\0\1\6\7\0\12\6"+
+    "\17\0\20\6\4\0\10\6\2\0\2\6\2\0\26\6"+
+    "\1\0\7\6\1\0\1\6\3\0\4\6\3\0\1\6"+
+    "\20\0\1\6\15\0\2\6\1\0\3\6\16\0\4\6"+
+    "\7\0\2\6\10\0\6\6\4\0\2\6\2\0\26\6"+
+    "\1\0\7\6\1\0\2\6\1\0\2\6\1\0\2\6"+
+    "\37\0\4\6\1\0\1\6\23\0\3\6\20\0\11\6"+
+    "\1\0\3\6\1\0\26\6\1\0\7\6\1\0\2\6"+
+    "\1\0\5\6\3\0\1\6\22\0\1\6\17\0\2\6"+
+    "\17\0\1\6\7\0\1\6\13\0\10\6\2\0\2\6"+
+    "\2\0\26\6\1\0\7\6\1\0\2\6\1\0\5\6"+
+    "\3\0\1\6\36\0\2\6\1\0\3\6\17\0\1\6"+
+    "\21\0\1\6\1\0\6\6\3\0\3\6\1\0\4\6"+
+    "\3\0\2\6\1\0\1\6\1\0\2\6\3\0\2\6"+
+    "\3\0\3\6\3\0\14\6\26\0\1\6\50\0\1\6"+
+    "\13\0\10\6\1\0\3\6\1\0\27\6\1\0\20\6"+
+    "\3\0\1\6\32\0\3\6\5\0\2\6\36\0\1\6"+
+    "\4\0\10\6\1\0\3\6\1\0\27\6\1\0\12\6"+
+    "\1\0\5\6\3\0\1\6\40\0\1\6\1\0\2\6"+
+    "\17\0\2\6\21\0\11\6\1\0\3\6\1\0\51\6"+
+    "\2\0\1\6\20\0\1\6\5\0\3\6\10\0\3\6"+
+    "\30\0\6\6\5\0\22\6\3\0\30\6\1\0\11\6"+
+    "\1\0\1\6\2\0\7\6\72\0\60\6\1\0\2\6"+
+    "\13\0\10\6\72\0\2\6\1\0\1\6\1\0\5\6"+
+    "\1\0\30\6\1\0\1\6\1\0\12\6\1\0\2\6"+
+    "\11\0\1\6\2\0\5\6\1\0\1\6\25\0\4\6"+
+    "\40\0\1\6\77\0\10\6\1\0\44\6\33\0\5\6"+
+    "\163\0\53\6\24\0\1\6\20\0\6\6\4\0\4\6"+
+    "\3\0\1\6\3\0\2\6\7\0\3\6\4\0\15\6"+
+    "\14\0\1\6\21\0\46\6\1\0\1\6\5\0\1\6"+
+    "\2\0\53\6\1\0\115\6\1\0\4\6\2\0\7\6"+
+    "\1\0\1\6\1\0\4\6\2\0\51\6\1\0\4\6"+
+    "\2\0\41\6\1\0\4\6\2\0\7\6\1\0\1\6"+
+    "\1\0\4\6\2\0\17\6\1\0\71\6\1\0\4\6"+
+    "\2\0\103\6\45\0\20\6\20\0\126\6\2\0\6\6"+
+    "\3\0\u016c\6\2\0\21\6\1\0\32\6\5\0\113\6"+
+    "\3\0\13\6\7\0\15\6\1\0\4\6\16\0\22\6"+
+    "\16\0\22\6\16\0\15\6\1\0\3\6\17\0\64\6"+
+    "\43\0\1\6\3\0\2\6\103\0\131\6\7\0\5\6"+
+    "\2\0\42\6\1\0\1\6\5\0\106\6\12\0\37\6"+
+    "\61\0\36\6\2\0\5\6\13\0\54\6\4\0\32\6"+
+    "\66\0\27\6\11\0\65\6\122\0\1\6\135\0\57\6"+
+    "\21\0\7\6\67\0\36\6\15\0\2\6\12\0\54\6"+
+    "\32\0\44\6\51\0\3\6\12\0\44\6\2\0\11\6"+
+    "\7\0\53\6\2\0\3\6\51\0\4\6\1\0\6\6"+
+    "\1\0\2\6\3\0\1\6\5\0\300\6\100\0\26\6"+
+    "\2\0\6\6\2\0\46\6\2\0\6\6\2\0\10\6"+
+    "\1\0\1\6\1\0\1\6\1\0\1\6\1\0\37\6"+
+    "\2\0\65\6\1\0\7\6\1\0\1\6\3\0\3\6"+
+    "\1\0\7\6\3\0\4\6\2\0\6\6\4\0\15\6"+
+    "\5\0\3\6\1\0\7\6\53\0\2\3\25\0\2\6"+
+    "\23\0\1\6\34\0\1\6\15\0\1\6\20\0\15\6"+
+    "\3\0\40\6\102\0\1\6\4\0\1\6\2\0\12\6"+
+    "\1\0\1\6\3\0\5\6\6\0\1\6\1\0\1\6"+
+    "\1\0\1\6\1\0\4\6\1\0\13\6\2\0\4\6"+
+    "\5\0\5\6\4\0\1\6\21\0\51\6\u0177\0\57\6"+
+    "\1\0\57\6\1\0\205\6\6\0\4\6\3\0\2\6"+
+    "\14\0\46\6\1\0\1\6\5\0\1\6\2\0\70\6"+
+    "\7\0\1\6\20\0\27\6\11\0\7\6\1\0\7\6"+
+    "\1\0\7\6\1\0\7\6\1\0\7\6\1\0\7\6"+
+    "\1\0\7\6\1\0\7\6\120\0\1\6\325\0\3\6"+
+    "\31\0\11\6\7\0\5\6\2\0\5\6\4\0\126\6"+
+    "\6\0\3\6\1\0\132\6\1\0\4\6\5\0\53\6"+
+    "\1\0\136\6\21\0\40\6\60\0\u010d\6\3\0\215\6"+
+    "\103\0\56\6\2\0\15\6\3\0\20\6\12\0\2\6"+
+    "\24\0\57\6\20\0\37\6\2\0\120\6\47\0\11\6"+
+    "\2\0\147\6\2\0\65\6\2\0\11\6\52\0\15\6"+
+    "\1\0\3\6\1\0\4\6\1\0\27\6\25\0\1\6"+
+    "\7\0\64\6\16\0\62\6\76\0\6\6\3\0\1\6"+
+    "\1\0\2\6\13\0\34\6\12\0\27\6\31\0\35\6"+
+    "\7\0\57\6\34\0\1\6\20\0\5\6\1\0\12\6"+
+    "\12\0\5\6\1\0\51\6\27\0\3\6\1\0\10\6"+
+    "\24\0\27\6\3\0\1\6\3\0\62\6\1\0\1\6"+
+    "\3\0\2\6\2\0\5\6\2\0\1\6\1\0\1\6"+
+    "\30\0\3\6\2\0\13\6\7\0\3\6\14\0\6\6"+
+    "\2\0\6\6\2\0\6\6\11\0\7\6\1\0\7\6"+
+    "\1\0\53\6\1\0\16\6\6\0\163\6\35\0\244\6"+
+    "\14\0\27\6\4\0\61\6\4\0\u0100\3\156\6\2\0"+
+    "\152\6\46\0\7\6\14\0\5\6\5\0\1\6\1\0"+
+    "\12\6\1\0\15\6\1\0\5\6\1\0\1\6\1\0"+
+    "\2\6\1\0\2\6\1\0\154\6\41\0\153\6\22\0"+
+    "\100\6\2\0\66\6\50\0\15\6\66\0\2\6\30\0"+
+    "\3\6\31\0\1\6\6\0\5\6\1\0\207\6\7\0"+
+    "\1\6\34\0\32\6\4\0\1\6\1\0\32\6\13\0"+
+    "\131\6\3\0\6\6\2\0\6\6\2\0\6\6\2\0"+
+    "\3\6\3\0\2\6\3\0\2\6\31\0\14\6\1\0"+
+    "\32\6\1\0\23\6\1\0\2\6\1\0\17\6\2\0"+
+    "\16\6\42\0\173\6\105\0\65\6\u010b\0\35\6\3\0"+
+    "\61\6\57\0\40\6\15\0\36\6\5\0\46\6\12\0"+
+    "\36\6\2\0\44\6\4\0\10\6\1\0\5\6\52\0"+
+    "\236\6\22\0\44\6\4\0\44\6\4\0\50\6\10\0"+
+    "\64\6\234\0\67\6\11\0\26\6\12\0\10\6\230\0"+
+    "\6\6\2\0\1\6\1\0\54\6\1\0\2\6\3\0"+
+    "\1\6\2\0\27\6\12\0\27\6\11\0\37\6\101\0"+
+    "\23\6\1\0\2\6\12\0\26\6\12\0\32\6\106\0"+
+    "\70\6\6\0\2\6\100\0\1\6\17\0\4\6\1\0"+
+    "\3\6\1\0\35\6\52\0\35\6\3\0\35\6\43\0"+
+    "\10\6\1\0\34\6\33\0\66\6\12\0\26\6\12\0"+
+    "\23\6\15\0\22\6\156\0\111\6\67\0\63\6\15\0"+
+    "\63\6\15\0\44\6\u015c\0\52\6\6\0\2\6\116\0"+
+    "\35\6\12\0\1\6\10\0\26\6\152\0\25\6\33\0"+
+    "\27\6\14\0\65\6\113\0\55\6\40\0\31\6\32\0"+
+    "\44\6\35\0\1\6\2\0\1\6\10\0\43\6\3\0"+
+    "\1\6\14\0\60\6\16\0\4\6\25\0\1\6\1\0"+
+    "\1\6\43\0\22\6\1\0\31\6\124\0\7\6\1\0"+
+    "\1\6\1\0\4\6\1\0\17\6\1\0\12\6\7\0"+
+    "\57\6\46\0\10\6\2\0\2\6\2\0\26\6\1\0"+
+    "\7\6\1\0\2\6\1\0\5\6\3\0\1\6\22\0"+
+    "\1\6\14\0\5\6\236\0\65\6\22\0\4\6\24\0"+
+    "\3\6\36\0\60\6\24\0\2\6\1\0\1\6\270\0"+
+    "\57\6\51\0\4\6\44\0\60\6\24\0\1\6\73\0"+
+    "\53\6\15\0\1\6\107\0\33\6\345\0\54\6\164\0"+
+    "\100\6\37\0\10\6\2\0\1\6\2\0\10\6\1\0"+
+    "\2\6\1\0\30\6\17\0\1\6\1\0\1\6\136\0"+
+    "\10\6\2\0\47\6\20\0\1\6\1\0\1\6\34\0"+
+    "\1\6\12\0\50\6\7\0\1\6\25\0\1\6\13\0"+
+    "\56\6\23\0\1\6\42\0\71\6\7\0\11\6\1\0"+
+    "\45\6\21\0\1\6\61\0\36\6\160\0\7\6\1\0"+
+    "\2\6\1\0\46\6\25\0\1\6\31\0\6\6\1\0"+
+    "\2\6\1\0\40\6\16\0\1\6\u0147\0\23\6\275\0"+
+    "\1\6\54\0\4\6\37\0\232\6\146\0\157\6\21\0"+
+    "\304\6\274\0\57\6\321\0\107\6\271\0\71\6\7\0"+
+    "\37\6\161\0\36\6\22\0\60\6\20\0\4\6\37\0"+
+    "\25\6\5\0\23\6\260\0\100\6\200\0\113\6\5\0"+
+    "\1\6\102\0\15\6\100\0\2\6\1\0\1\6\34\0"+
+    "\370\6\10\0\326\6\52\0\11\6\367\0\37\6\61\0"+
+    "\3\6\21\0\4\6\10\0\u018c\6\4\0\153\6\5\0"+
+    "\15\6\3\0\11\6\7\0\12\6\146\0\125\6\1\0"+
+    "\107\6\1\0\2\6\2\0\1\6\2\0\2\6\2\0"+
+    "\4\6\1\0\14\6\1\0\1\6\1\0\7\6\1\0"+
+    "\101\6\1\0\4\6\2\0\10\6\1\0\7\6\1\0"+
+    "\34\6\1\0\4\6\1\0\5\6\1\0\1\6\3\0"+
+    "\7\6\1\0\u0154\6\2\0\31\6\1\0\31\6\1\0"+
+    "\37\6\1\0\31\6\1\0\37\6\1\0\31\6\1\0"+
+    "\37\6\1\0\31\6\1\0\37\6\1\0\31\6\1\0"+
+    "\10\6\64\0\55\6\12\0\7\6\20\0\1\6\u0171\0"+
+    "\54\6\23\0\306\6\73\0\104\6\7\0\1\6\u0164\0"+
+    "\1\6\117\0\4\6\1\0\33\6\1\0\2\6\1\0"+
+    "\1\6\2\0\1\6\1\0\12\6\1\0\4\6\1\0"+
+    "\1\6\1\0\1\6\6\0\1\6\4\0\1\6\1\0"+
+    "\1\6\1\0\1\6\1\0\3\6\1\0\2\6\1\0"+
+    "\1\6\2\0\1\6\1\0\1\6\1\0\1\6\1\0"+
+    "\1\6\1\0\1\6\1\0\2\6\1\0\1\6\2\0"+
+    "\4\6\1\0\7\6\1\0\4\6\1\0\4\6\1\0"+
+    "\1\6\1\0\12\6\1\0\21\6\5\0\3\6\1\0"+
+    "\5\6\1\0\21\6\104\0\336\6\42\0\65\6\13\0"+
+    "\336\6\2\0\u0182\6\16\0\u0131\6\37\0\36\6\342\0"+
+    "\113\6\265\0";
+
+  private static int [] zzUnpackcmap_blocks() {
+    int [] result = new int[29184];
+    int offset = 0;
+    offset = zzUnpackcmap_blocks(ZZ_CMAP_BLOCKS_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackcmap_blocks(String packed, int offset, int [] result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
+
+  /**
    * Translates DFA states to action switch labels.
    */
   private static final int [] ZZ_ACTION = zzUnpackAction();
 
   private static final String ZZ_ACTION_PACKED_0 =
-    "\11\0\3\1\1\2\1\3\3\2\1\4\1\5\1\4"+
-    "\3\2\1\6\1\7\2\2\1\10\1\11\3\10\1\12"+
-    "\1\0\1\13\6\0\1\4\1\14\1\15\4\0\1\16"+
-    "\2\0\1\17\1\4\1\20\1\21\1\0\2\22\1\0"+
-    "\1\23\1\3\1\24\1\23";
+    "\11\0\3\1\1\2\1\3\2\4\1\5\6\2\1\6"+
+    "\1\7\2\2\1\10\1\11\1\10\1\12\2\10\1\0"+
+    "\1\13\1\0\1\4\3\0\1\14\2\0\1\15\4\0"+
+    "\1\16\1\4\2\0\1\17\1\20\1\21\1\0\1\3"+
+    "\2\22\1\23\1\0\1\24\1\23";
 
   private static int [] zzUnpackAction() {
     int [] result = new int[63];
@@ -171,7 +312,7 @@
   }
 
 
-  /** 
+  /**
    * Translates a state to a row index in the transition table
    */
   private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
@@ -179,12 +320,12 @@
   private static final String ZZ_ROWMAP_PACKED_0 =
     "\0\0\0\23\0\46\0\71\0\114\0\137\0\162\0\205"+
     "\0\230\0\253\0\276\0\321\0\253\0\344\0\367\0\u010a"+
-    "\0\u011d\0\u0130\0\u0143\0\u0156\0\u0169\0\321\0\u017c\0\u018f"+
-    "\0\u01a2\0\u01b5\0\u01c8\0\253\0\u01db\0\321\0\u01ee\0\u0201"+
-    "\0\u0214\0\u0227\0\253\0\321\0\u023a\0\u024d\0\u0260\0\u0273"+
-    "\0\u0286\0\u0299\0\253\0\u02ac\0\u02bf\0\u02d2\0\u02e5\0\u02f8"+
+    "\0\u011d\0\u0130\0\u0143\0\u0156\0\u0169\0\276\0\u017c\0\u018f"+
+    "\0\u01a2\0\u01b5\0\u01c8\0\253\0\u01db\0\276\0\u01ee\0\u0201"+
+    "\0\u0214\0\276\0\253\0\u0227\0\u023a\0\u024d\0\u0260\0\u0273"+
+    "\0\253\0\u0286\0\u0299\0\u02ac\0\u02bf\0\u02d2\0\u02e5\0\u02f8"+
     "\0\253\0\u030b\0\u031e\0\u0331\0\u0344\0\253\0\253\0\u0357"+
-    "\0\u023a\0\u0260\0\u036a\0\u023a\0\u0344\0\u037d\0\253";
+    "\0\u030b\0\u024d\0\u0273\0\u024d\0\u036a\0\u037d\0\253";
 
   private static int [] zzUnpackRowMap() {
     int [] result = new int[63];
@@ -196,7 +337,7 @@
   private static int zzUnpackRowMap(String packed, int offset, int [] result) {
     int i = 0;  /* index in packed string  */
     int j = offset;  /* index in unpacked array */
-    int l = packed.length();
+    int l = packed.length() - 1;
     while (i < l) {
       int high = packed.charAt(i++) << 16;
       result[j++] = high | packed.charAt(i++);
@@ -204,55 +345,53 @@
     return j;
   }
 
-  /** 
+  /**
    * The transition table of the DFA
    */
-  private static final int [] ZZ_TRANS = zzUnpackTrans();
+  private static final int [] ZZ_TRANS = zzUnpacktrans();
 
   private static final String ZZ_TRANS_PACKED_0 =
-    "\14\12\1\13\1\14\5\12\1\15\1\16\3\15\1\17"+
-    "\1\15\1\20\1\21\1\22\1\15\1\22\1\15\1\23"+
-    "\1\15\1\24\1\25\3\15\1\16\3\15\1\17\1\15"+
-    "\1\20\1\21\1\22\1\15\1\22\1\15\1\26\1\27"+
-    "\1\24\1\25\3\15\1\30\1\15\1\31\1\15\1\32"+
-    "\3\15\1\30\1\15\1\30\1\15\1\26\1\15\1\30"+
-    "\4\15\1\30\3\15\1\33\3\15\1\30\1\15\1\30"+
-    "\1\15\1\26\1\15\1\30\4\15\1\16\3\15\1\17"+
-    "\1\15\1\20\1\21\1\22\1\15\1\22\1\15\1\26"+
-    "\1\15\1\24\1\25\2\15\1\34\1\35\7\34\1\35"+
-    "\1\34\1\35\1\34\1\36\1\34\1\35\4\34\1\35"+
-    "\5\34\1\37\1\40\1\35\1\34\1\35\1\34\1\41"+
-    "\1\34\1\35\4\34\1\35\5\34\1\37\1\40\1\35"+
-    "\1\34\1\35\1\34\1\36\1\34\1\35\3\34\40\0"+
-    "\1\42\21\0\1\43\1\44\6\0\1\16\7\0\1\22"+
-    "\1\0\1\22\3\0\1\22\3\0\3\45\1\46\1\45"+
-    "\1\0\1\47\14\45\7\0\1\50\23\0\1\51\13\0"+
-    "\1\22\7\0\1\22\1\0\1\22\3\0\1\22\17\0"+
-    "\1\43\1\23\6\0\1\22\7\0\1\22\1\0\1\22"+
-    "\3\0\1\52\10\0\2\53\17\0\1\54\20\0\1\30"+
-    "\7\0\1\30\1\0\1\30\3\0\1\30\5\0\3\31"+
-    "\21\0\1\55\22\0\1\56\20\0\1\35\7\0\1\35"+
-    "\1\0\1\35\3\0\1\35\12\0\1\57\23\0\1\60"+
-    "\26\0\1\43\1\41\22\0\1\61\5\0\5\45\1\0"+
-    "\1\47\16\45\3\46\1\0\1\62\21\45\1\0\1\47"+
-    "\12\45\1\63\1\45\7\0\1\64\23\0\1\64\13\0"+
-    "\1\22\7\0\1\22\1\0\1\22\3\0\1\65\5\0"+
-    "\2\54\21\0\3\55\1\0\1\66\16\0\3\56\1\0"+
-    "\1\67\23\0\1\70\23\0\1\70\12\0\5\71\1\0"+
-    "\1\72\12\71\1\63\1\71\5\63\1\73\14\63\1\74"+
-    "\11\64\3\0\7\64\1\0\1\22\7\0\1\22\1\0"+
-    "\1\22\3\0\1\75\4\0\1\70\7\0\1\76\1\0"+
-    "\1\70\3\0\1\70\3\0\22\73\1\77\1\0\1\76"+
-    "\11\0\1\76\3\0\1\76\3\0";
+    "\11\12\1\13\1\12\1\14\7\12\1\15\1\16\1\17"+
+    "\1\15\1\17\1\20\3\15\1\21\4\15\1\22\1\23"+
+    "\1\15\1\24\1\25\1\15\1\16\1\17\1\15\1\17"+
+    "\1\20\3\15\1\26\3\15\1\27\1\22\1\23\1\15"+
+    "\1\24\1\25\1\15\2\30\1\15\2\30\1\31\2\15"+
+    "\1\26\4\15\1\32\5\15\2\30\1\15\2\30\3\15"+
+    "\1\26\4\15\1\33\5\15\1\16\1\17\1\15\1\17"+
+    "\1\20\3\15\1\26\4\15\1\22\1\23\1\15\1\24"+
+    "\1\25\1\34\2\35\1\34\2\35\3\34\1\36\12\34"+
+    "\2\35\1\34\2\35\3\34\1\37\7\34\1\40\1\41"+
+    "\1\34\2\35\1\34\2\35\3\34\1\36\7\34\1\40"+
+    "\1\41\34\0\1\42\1\0\1\43\20\0\1\44\12\0"+
+    "\1\16\1\17\1\0\2\17\16\0\2\17\1\0\2\17"+
+    "\16\0\2\17\1\0\1\17\1\45\26\0\1\21\1\0"+
+    "\1\43\7\0\6\46\1\47\7\46\1\0\1\46\1\50"+
+    "\2\46\16\0\1\51\1\0\1\51\23\0\1\52\23\0"+
+    "\1\53\6\0\1\54\15\0\2\30\1\0\2\30\23\0"+
+    "\1\31\3\0\1\31\1\0\1\31\14\0\1\55\22\0"+
+    "\1\56\15\0\2\35\1\0\2\35\26\0\1\37\1\0"+
+    "\1\43\30\0\1\57\23\0\1\60\11\0\1\61\12\0"+
+    "\2\17\1\0\1\17\1\62\15\0\16\46\1\0\1\46"+
+    "\1\50\10\46\1\47\3\46\1\47\1\46\1\47\1\46"+
+    "\1\0\1\46\1\63\11\46\1\64\6\46\1\0\1\46"+
+    "\1\50\2\46\21\0\1\65\23\0\1\65\6\0\1\54"+
+    "\5\0\1\54\14\0\1\55\3\0\1\55\1\0\1\55"+
+    "\3\0\1\66\10\0\1\56\3\0\1\56\1\0\1\56"+
+    "\3\0\1\67\23\0\1\70\23\0\1\70\1\0\2\17"+
+    "\1\0\1\17\1\71\15\0\7\72\1\64\6\72\1\0"+
+    "\1\72\1\73\2\72\10\64\1\74\5\64\1\75\4\64"+
+    "\2\65\3\0\16\65\1\0\1\70\1\76\1\0\2\70"+
+    "\15\0\10\75\1\77\12\75\1\0\1\76\2\0\2\76"+
+    "\15\0";
 
-  private static int [] zzUnpackTrans() {
+  private static int [] zzUnpacktrans() {
     int [] result = new int[912];
     int offset = 0;
-    offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
+    offset = zzUnpacktrans(ZZ_TRANS_PACKED_0, offset, result);
     return result;
   }
 
-  private static int zzUnpackTrans(String packed, int offset, int [] result) {
+  private static int zzUnpacktrans(String packed, int offset, int [] result) {
     int i = 0;       /* index in packed string  */
     int j = offset;  /* index in unpacked array */
     int l = packed.length();
@@ -279,14 +418,15 @@
   };
 
   /**
-   * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
+   * ZZ_ATTRIBUTE[aState] contains the attributes of state {@code aState}
    */
   private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
 
   private static final String ZZ_ATTRIBUTE_PACKED_0 =
     "\11\0\1\11\2\1\1\11\16\1\1\11\5\1\1\0"+
-    "\1\11\6\0\1\1\1\11\1\1\4\0\1\11\2\0"+
-    "\2\1\2\11\1\0\2\1\1\0\3\1\1\11";
+    "\1\11\1\0\1\1\3\0\1\11\2\0\1\1\4\0"+
+    "\1\11\1\1\2\0\1\1\2\11\1\0\4\1\1\0"+
+    "\1\1\1\11";
 
   private static int [] zzUnpackAttribute() {
     int [] result = new int[63];
@@ -333,15 +473,26 @@
       from input */
   private int zzEndRead;
 
-  /**
-   * zzAtBOL == true <=> the scanner is currently at the beginning of a line
-   */
-  private boolean zzAtBOL = true;
-
   /** zzAtEOF == true <=> the scanner is at the EOF */
   private boolean zzAtEOF;
 
-  /** denotes if the user-EOF-code has already been executed */
+  /** Number of newlines encountered up to the start of the matched text. */
+  @SuppressWarnings("unused")
+  private int yyline;
+
+  /** Number of characters from the last newline up to the start of the matched text. */
+  @SuppressWarnings("unused")
+  protected int yycolumn;
+
+  /** Number of characters up to the start of the matched text. */
+  @SuppressWarnings("unused")
+  private long yychar;
+
+  /** Whether the scanner is currently at the beginning of a line. */
+  @SuppressWarnings("unused")
+  private boolean zzAtBOL = true;
+
+  /** Whether the user-EOF-code has already been executed. */
   private boolean zzEOFDone;
 
   /* user code: */
@@ -376,26 +527,22 @@
   }
 
 
-  /** 
-   * Unpacks the compressed character translation table.
-   *
-   * @param packed   the packed character translation table
-   * @return         the unpacked character translation table
+  /** Returns the maximum size of the scanner buffer, which limits the size of tokens. */
+  private int zzMaxBufferLen() {
+    return Integer.MAX_VALUE;
+  }
+
+  /**  Whether the scanner buffer can grow to accommodate a larger token. */
+  private boolean zzCanGrow() {
+    return true;
+  }
+
+  /**
+   * Translates raw input code points to DFA table row
    */
-  private static char [] zzUnpackCMap(String packed) {
-    int size = 0;
-    for (int i = 0, length = packed.length(); i < length; i += 2) {
-      size += packed.charAt(i);
-    }
-    char[] map = new char[size];
-    int i = 0;  /* index in packed string  */
-    int j = 0;  /* index in unpacked array */
-    while (i < packed.length()) {
-      int  count = packed.charAt(i++);
-      char value = packed.charAt(i++);
-      do map[j++] = value; while (--count > 0);
-    }
-    return map;
+  private static int zzCMap(int input) {
+    int offset = input & 255;
+    return offset == input ? ZZ_CMAP_BLOCKS[offset] : ZZ_CMAP_BLOCKS[ZZ_CMAP_TOP[input >> 8] | offset];
   }
 
   public final int getTokenStart() {
@@ -527,8 +674,8 @@
   private void zzDoEOF() {
     if (!zzEOFDone) {
       zzEOFDone = true;
-      return;
-
+    
+  return;
     }
   }
 
@@ -540,7 +687,8 @@
    * @return      the next token
    * @exception   java.io.IOException  if any I/O-Error occurs
    */
-  public IElementType advance() throws java.io.IOException {
+  public IElementType advance() throws java.io.IOException
+  {
     int zzInput;
     int zzAction;
 
@@ -574,7 +722,7 @@
         while (true) {
 
           if (zzCurrentPosL < zzEndReadL) {
-            zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL/*, zzEndReadL*/);
+            zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL);
             zzCurrentPosL += Character.charCount(zzInput);
           }
           else if (zzAtEOF) {
@@ -596,11 +744,11 @@
               break zzForAction;
             }
             else {
-              zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL/*, zzEndReadL*/);
+              zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL);
               zzCurrentPosL += Character.charCount(zzInput);
             }
           }
-          int zzNext = zzTransL[ zzRowMapL[zzState] + ZZ_CMAP(zzInput) ];
+          int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMap(zzInput) ];
           if (zzNext == -1) break zzForAction;
           zzState = zzNext;
 
@@ -619,31 +767,31 @@
 
       if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
         zzAtEOF = true;
-        zzDoEOF();
+            zzDoEOF();
         return null;
       }
       else {
         switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
-          case 1: 
+          case 1:
             { return TokenType.BAD_CHARACTER;
-            } 
-            // fall through
+            }
+          // fall through
           case 21: break;
-          case 2: 
+          case 2:
             { yybegin(CONTENTS);
         return KDocTokens.TEXT;
-            } 
-            // fall through
+            }
+          // fall through
           case 22: break;
-          case 3: 
+          case 3:
             { if(yystate() == CONTENTS_BEGINNING) {
             yybegin(INDENTED_CODE_BLOCK);
             return KDocTokens.CODE_BLOCK_TEXT;
         }
-            } 
-            // fall through
+            }
+          // fall through
           case 23: break;
-          case 4: 
+          case 4:
             { if (yytextContainLineBreaks()) {
             yybegin(LINE_BEGINNING);
             return TokenType.WHITE_SPACE;
@@ -651,117 +799,117 @@
             yybegin(yystate() == CONTENTS_BEGINNING ? CONTENTS_BEGINNING : CONTENTS);
             return KDocTokens.TEXT;  // internal white space
         }
-            } 
-            // fall through
+            }
+          // fall through
           case 24: break;
-          case 5: 
+          case 5:
             { yybegin(CONTENTS_BEGINNING);
                                             return KDocTokens.LEADING_ASTERISK;
-            } 
-            // fall through
+            }
+          // fall through
           case 25: break;
-          case 6: 
+          case 6:
             { if (yytextContainLineBreaks()) {
             yybegin(LINE_BEGINNING);
         }
         return TokenType.WHITE_SPACE;
-            } 
-            // fall through
+            }
+          // fall through
           case 26: break;
-          case 7: 
+          case 7:
             { yybegin(TAG_TEXT_BEGINNING);
         return KDocTokens.MARKDOWN_LINK;
-            } 
-            // fall through
+            }
+          // fall through
           case 27: break;
-          case 8: 
+          case 8:
             { yybegin(yystate() == INDENTED_CODE_BLOCK ? INDENTED_CODE_BLOCK : CODE_BLOCK);
         return KDocTokens.CODE_BLOCK_TEXT;
-            } 
-            // fall through
+            }
+          // fall through
           case 28: break;
-          case 9: 
+          case 9:
             { if (yytextContainLineBreaks()) {
             yybegin(yystate() == INDENTED_CODE_BLOCK ? LINE_BEGINNING : CODE_BLOCK_LINE_BEGINNING);
             return TokenType.WHITE_SPACE;
         }
         return KDocTokens.CODE_BLOCK_TEXT;
-            } 
-            // fall through
+            }
+          // fall through
           case 29: break;
-          case 10: 
+          case 10:
             { yybegin(CODE_BLOCK_CONTENTS_BEGINNING);
         return KDocTokens.LEADING_ASTERISK;
-            } 
-            // fall through
+            }
+          // fall through
           case 30: break;
-          case 11: 
+          case 11:
             { if (isLastToken()) return KDocTokens.END;
                                             else return KDocTokens.TEXT;
-            } 
-            // fall through
+            }
+          // fall through
           case 31: break;
-          case 12: 
+          case 12:
             { yybegin(CONTENTS);
         return KDocTokens.MARKDOWN_ESCAPED_CHAR;
-            } 
-            // fall through
+            }
+          // fall through
           case 32: break;
-          case 13: 
+          case 13:
             { KDocKnownTag tag = KDocKnownTag.Companion.findByTagName(zzBuffer.subSequence(zzStartRead, zzMarkedPos));
     yybegin(tag != null && tag.isReferenceRequired() ? TAG_BEGINNING : TAG_TEXT_BEGINNING);
     return KDocTokens.TAG_NAME;
-            } 
-            // fall through
+            }
+          // fall through
           case 33: break;
-          case 14: 
+          case 14:
             { yybegin(CONTENTS_BEGINNING);
                                             return KDocTokens.START;
-            } 
-            // fall through
+            }
+          // fall through
           case 34: break;
-          case 15: 
+          case 15:
             { yybegin(CODE_BLOCK_LINE_BEGINNING);
         return KDocTokens.TEXT;
-            } 
-            // fall through
+            }
+          // fall through
           case 35: break;
-          case 16: 
+          case 16:
             { yybegin(TAG_TEXT_BEGINNING);
                   return KDocTokens.MARKDOWN_LINK;
-            } 
-            // fall through
+            }
+          // fall through
           case 36: break;
-          case 17: 
+          case 17:
             { yybegin(CONTENTS);
                   return KDocTokens.MARKDOWN_LINK;
-            } 
-            // fall through
+            }
+          // fall through
           case 37: break;
-          case 18: 
+          case 18:
             // lookahead expression with fixed lookahead length
             zzMarkedPos = Character.offsetByCodePoints
-                (zzBufferL/*, zzStartRead, zzEndRead - zzStartRead*/, zzMarkedPos, -1);
+                (zzBufferL, zzMarkedPos, -1);
             { yybegin(CONTENTS);
         return KDocTokens.MARKDOWN_LINK;
-            } 
-            // fall through
+            }
+          // fall through
           case 38: break;
-          case 19: 
+          case 19:
             { yybegin(CONTENTS);
         return KDocTokens.MARKDOWN_INLINE_LINK;
-            } 
-            // fall through
+            }
+          // fall through
           case 39: break;
-          case 20: 
+          case 20:
             // lookahead expression with fixed base length
             zzMarkedPos = Character.offsetByCodePoints
-                (zzBufferL/*, zzStartRead, zzEndRead - zzStartRead*/, zzStartRead, 3);
+                (zzBufferL, zzStartRead, 3);
             { // Code fence end
         yybegin(CONTENTS);
         return KDocTokens.TEXT;
-            } 
-            // fall through
+            }
+          // fall through
           case 40: break;
           default:
             zzScanError(ZZ_NO_MATCH);
diff --git a/compiler/psi/src/org/jetbrains/kotlin/lexer/Kotlin.flex b/compiler/psi/src/org/jetbrains/kotlin/lexer/Kotlin.flex
index 6bd8be7..262f713 100644
--- a/compiler/psi/src/org/jetbrains/kotlin/lexer/Kotlin.flex
+++ b/compiler/psi/src/org/jetbrains/kotlin/lexer/Kotlin.flex
@@ -19,14 +19,26 @@
         final int lBraceCount;
         final int state;
 
-        public State(int state, int lBraceCount) {
+        final int dollarCount;
+        final int quotesCount;
+
+        public State(int state, int lBraceCount, int dollarCount, int quotesCount) {
             this.state = state;
             this.lBraceCount = lBraceCount;
+            this.dollarCount = dollarCount;
+            this.quotesCount = quotesCount;
+        }
+
+        public State(int state, int lBraceCount) {
+            this(state, lBraceCount, 0, 0);
         }
 
         @Override
         public String toString() {
-            return "yystate = " + state + (lBraceCount == 0 ? "" : "lBraceCount = " + lBraceCount);
+            return "yystate = " + state
+              + (lBraceCount == 0 ? "" : "lBraceCount = " + lBraceCount)
+              + (dollarCount == 0 ? "" : "dollarCount = " + dollarCount)
+              + (quotesCount == 0 ? "" : "quotesCount = " + quotesCount);
         }
     }
 
@@ -37,11 +49,26 @@
     private int commentDepth;
 
     private void pushState(int state) {
-        states.push(new State(yystate(), lBraceCount));
+        states.push(new State(yystate(), lBraceCount, 0, 0));
         lBraceCount = 0;
         yybegin(state);
     }
 
+    private void pushState(int state, int dollarCount, int quotesCount) {
+        states.push(new State(yystate(), lBraceCount, dollarCount, quotesCount));
+        lBraceCount = 0;
+        yybegin(state);
+    }
+
+    private int peekQuotes() {
+        return states.peek().quotesCount;
+    }
+
+    private int peekDollars() {
+        // we should always have at least one dollar
+        return Math.max(1, states.peek().dollarCount);
+    }
+
     private void popState() {
         State state = states.pop();
         lBraceCount = state.lBraceCount;
@@ -114,45 +141,70 @@
 ESCAPE_SEQUENCE=\\(u{HEX_DIGIT}{HEX_DIGIT}{HEX_DIGIT}{HEX_DIGIT}|[^\n])
 
 // ANY_ESCAPE_SEQUENCE = \\[^]
-THREE_QUO = (\"\"\")
-THREE_OR_MORE_QUO = ({THREE_QUO}\"*)
 
 REGULAR_STRING_PART=[^\\\"\n\$]+
-SHORT_TEMPLATE_ENTRY=\${IDENTIFIER}
+SHORT_TEMPLATE_ENTRY=\$+{IDENTIFIER}
 LONELY_DOLLAR=\$
-LONG_TEMPLATE_ENTRY_START=\$\{
+LONG_TEMPLATE_ENTRY_START=\$+\{
 LONELY_BACKTICK=`
 
 %%
 
 // String templates
 
-{THREE_QUO}                      { pushState(RAW_STRING); return KtTokens.OPEN_QUOTE; }
-<RAW_STRING> \n                  { return KtTokens.REGULAR_STRING_PART; }
-<RAW_STRING> \"                  { return KtTokens.REGULAR_STRING_PART; }
-<RAW_STRING> \\                  { return KtTokens.REGULAR_STRING_PART; }
-<RAW_STRING> {THREE_OR_MORE_QUO} {
-                                    int length = yytext().length();
-                                    if (length <= 3) { // closing """
-                                        popState();
-                                        return KtTokens.CLOSING_QUOTE;
-                                    }
-                                    else { // some quotes at the end of a string, e.g. """ "foo""""
-                                        yypushback(3); // return the closing quotes (""") to the stream
-                                        return KtTokens.REGULAR_STRING_PART;
-                                    }
-                                 }
+\$*\"{3}\"*                 {
+                              String matched = yytext().toString();
+                              int dollarCount = matched.lastIndexOf('$') + 1;
+                              int quotesCount = matched.length() - dollarCount;
+                              pushState(RAW_STRING, dollarCount, quotesCount);
+                              return KtTokens.OPEN_QUOTE;
+                            }
+<RAW_STRING> \n             { return KtTokens.REGULAR_STRING_PART; }
+<RAW_STRING> \"             { return KtTokens.REGULAR_STRING_PART; }
+<RAW_STRING> \\             { return KtTokens.REGULAR_STRING_PART; }
+<RAW_STRING> \"{3}\"*       {
+                              int length = yytext().length();
+                              int closingQuotes = peekQuotes();
+                              if (length < closingQuotes) {
+                                // not enough quotes
+                                return KtTokens.REGULAR_STRING_PART;
+                              }
+                              else if (length == closingQuotes) { // closing """
+                                popState();
+                                return KtTokens.CLOSING_QUOTE;
+                              }
+                              else { // some quotes at the end of a string, e.g. """ "foo""""
+                                yypushback(closingQuotes); // return the closing quotes (""") to the stream
+                                return KtTokens.REGULAR_STRING_PART;
+                              }
+                            }
 
-\"                          { pushState(STRING); return KtTokens.OPEN_QUOTE; }
+\$*\"                       {
+                              pushState(STRING, yytext().length() - 1, 1);
+                              return KtTokens.OPEN_QUOTE;
+                            }
 <STRING> \n                 { popState(); yypushback(1); return KtTokens.DANGLING_NEWLINE; }
 <STRING> \"                 { popState(); return KtTokens.CLOSING_QUOTE; }
 <STRING> {ESCAPE_SEQUENCE}  { return KtTokens.ESCAPE_SEQUENCE; }
 
 <STRING, RAW_STRING> {REGULAR_STRING_PART}         { return KtTokens.REGULAR_STRING_PART; }
 <STRING, RAW_STRING> {SHORT_TEMPLATE_ENTRY}        {
-                                                        pushState(SHORT_TEMPLATE_ENTRY);
-                                                        yypushback(yylength() - 1);
-                                                        return KtTokens.SHORT_TEMPLATE_ENTRY_START;
+                                                     int dollarCount = yytext().toString().lastIndexOf('$') + 1;
+                                                     int escape = peekDollars();
+                                                     if (dollarCount < escape) {
+                                                       // not enough dollars
+                                                       return KtTokens.REGULAR_STRING_PART;
+                                                     }
+                                                     else if (dollarCount == escape) {
+                                                       pushState(SHORT_TEMPLATE_ENTRY);
+                                                       yypushback(yylength() - dollarCount);
+                                                       return KtTokens.SHORT_TEMPLATE_ENTRY_START;
+                                                     }
+                                                     else {
+                                                       // too many dollars
+                                                       yypushback(yylength() - dollarCount + escape);
+                                                       return KtTokens.REGULAR_STRING_PART;
+                                                     }
                                                    }
 // Only *this* keyword is itself an expression valid in this position
 // *null*, *true* and *false* are also keywords and expression, but it does not make sense to put them
@@ -161,7 +213,23 @@
 <SHORT_TEMPLATE_ENTRY> {IDENTIFIER}    { popState(); return KtTokens.IDENTIFIER; }
 
 <STRING, RAW_STRING> {LONELY_DOLLAR}               { return KtTokens.REGULAR_STRING_PART; }
-<STRING, RAW_STRING> {LONG_TEMPLATE_ENTRY_START}   { pushState(LONG_TEMPLATE_ENTRY); return KtTokens.LONG_TEMPLATE_ENTRY_START; }
+<STRING, RAW_STRING> {LONG_TEMPLATE_ENTRY_START}   {
+                                                      int dollarCount = yytext().toString().lastIndexOf('$') + 1;
+                                                      int escape = peekDollars();
+                                                      if (dollarCount < escape) {
+                                                        // not enough dollars
+                                                        return KtTokens.REGULAR_STRING_PART;
+                                                      }
+                                                      else if (dollarCount == escape) {
+                                                        pushState(LONG_TEMPLATE_ENTRY);
+                                                        return KtTokens.LONG_TEMPLATE_ENTRY_START;
+                                                      }
+                                                      else {
+                                                        // too many dollars
+                                                        yypushback(yylength() - dollarCount + escape);
+                                                        return KtTokens.REGULAR_STRING_PART;
+                                                      }
+                                                   }
 
 <LONG_TEMPLATE_ENTRY> "{"              { lBraceCount++; return KtTokens.LBRACE; }
 <LONG_TEMPLATE_ENTRY> "}"              {
diff --git a/compiler/psi/src/org/jetbrains/kotlin/lexer/_JetLexer.java b/compiler/psi/src/org/jetbrains/kotlin/lexer/_JetLexer.java
index 525d4d8..85f084a 100644
--- a/compiler/psi/src/org/jetbrains/kotlin/lexer/_JetLexer.java
+++ b/compiler/psi/src/org/jetbrains/kotlin/lexer/_JetLexer.java
@@ -1,4 +1,5 @@
-/* The following code was generated by JFlex 1.7.0 tweaked for IntelliJ platform */
+// Generated by JFlex 1.9.2 http://jflex.de/  (tweaked for IntelliJ platform)
+// source: src/org/jetbrains/kotlin/lexer/Kotlin.flex
 
 package org.jetbrains.kotlin.lexer;
 
@@ -11,11 +12,6 @@
 import org.jetbrains.kotlin.lexer.KtTokens;
 
 
-/**
- * This class is a scanner generated by 
- * <a href="http://www.jflex.de/">JFlex</a> 1.7.0
- * from the specification file <tt>/Users/Denis.Zharkov/work/kotlin-jps-4/compiler/psi/src/org/jetbrains/kotlin/lexer/Kotlin.flex</tt>
- */
 class _JetLexer implements FlexLexer {
 
   /** This character denotes the end of file */
@@ -40,164 +36,287 @@
    *                  at the beginning of a line
    * l is of the form l = 2*k, k a non negative integer
    */
-  private static final int ZZ_LEXSTATE[] = { 
+  private static final int ZZ_LEXSTATE[] = {
      0,  0,  1,  1,  2,  2,  3,  3,  4,  4,  4,  4,  5,  5,  0, 0
   };
 
-  /** 
-   * Translates characters to character classes
-   * Chosen bits are [11, 6, 4]
-   * Total runtime size is 14336 bytes
+  /**
+   * Top-level table for translating characters to character classes
    */
-  public static int ZZ_CMAP(int ch) {
-    return ZZ_CMAP_A[(ZZ_CMAP_Y[(ZZ_CMAP_Z[ch>>10]<<6)|((ch>>4)&0x3f)]<<4)|(ch&0xf)];
+  private static final int [] ZZ_CMAP_TOP = zzUnpackcmap_top();
+
+  private static final String ZZ_CMAP_TOP_PACKED_0 =
+    "\1\0\1\u0100\1\u0200\1\u0300\1\u0400\1\u0500\1\u0600\1\u0700"+
+    "\1\u0800\1\u0900\1\u0a00\1\u0b00\1\u0c00\1\u0d00\1\u0e00\1\u0f00"+
+    "\1\u1000\1\u0100\1\u1100\1\u1200\1\u1300\1\u0100\1\u1400\1\u1500"+
+    "\1\u1600\1\u1700\1\u1800\1\u1900\1\u1a00\1\u1b00\1\u0100\1\u1c00"+
+    "\1\u1d00\1\u1e00\12\u1f00\1\u2000\1\u2100\1\u2200\1\u1f00\1\u2300"+
+    "\1\u2400\2\u1f00\31\u0100\1\u2500\121\u0100\1\u2600\4\u0100\1\u2700"+
+    "\1\u0100\1\u2800\1\u2900\1\u2a00\1\u2b00\1\u2c00\1\u2d00\53\u0100"+
+    "\1\u2e00\10\u2f00\31\u1f00\1\u0100\1\u3000\1\u3100\1\u0100\1\u3200"+
+    "\1\u3300\1\u3400\1\u3500\1\u1f00\1\u3600\1\u3700\1\u3800\1\u3900"+
+    "\1\u0100\1\u3a00\1\u3b00\1\u3c00\1\u3d00\1\u3e00\1\u3f00\1\u4000"+
+    "\1\u1f00\1\u4100\1\u4200\1\u4300\1\u4400\1\u4500\1\u4600\1\u4700"+
+    "\1\u4800\1\u4900\1\u4a00\1\u4b00\1\u4c00\1\u1f00\1\u4d00\1\u4e00"+
+    "\1\u4f00\1\u1f00\3\u0100\1\u5000\1\u5100\1\u5200\12\u1f00\4\u0100"+
+    "\1\u5300\17\u1f00\2\u0100\1\u5400\41\u1f00\2\u0100\1\u5500\1\u5600"+
+    "\2\u1f00\1\u5700\1\u5800\27\u0100\1\u5900\2\u0100\1\u5a00\45\u1f00"+
+    "\1\u0100\1\u5b00\1\u5c00\11\u1f00\1\u5d00\27\u1f00\1\u5e00\1\u5f00"+
+    "\1\u6000\1\u6100\11\u1f00\1\u6200\1\u6300\5\u1f00\1\u6400\1\u6500"+
+    "\4\u1f00\1\u6600\21\u1f00\246\u0100\1\u6700\20\u0100\1\u6800\1\u6900"+
+    "\25\u0100\1\u6a00\34\u0100\1\u6b00\14\u1f00\2\u0100\1\u6c00\u0e05\u1f00";
+
+  private static int [] zzUnpackcmap_top() {
+    int [] result = new int[4352];
+    int offset = 0;
+    offset = zzUnpackcmap_top(ZZ_CMAP_TOP_PACKED_0, offset, result);
+    return result;
   }
 
-  /* The ZZ_CMAP_Z table has 1088 entries */
-  static final char ZZ_CMAP_Z[] = zzUnpackCMap(
-    "\1\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\2\11\1\12\1\13\6\14\1\15\23\14\1\16"+
-    "\1\14\1\17\1\20\12\14\1\21\10\11\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1"+
-    "\32\1\33\1\34\1\35\2\11\1\14\1\36\3\11\1\37\10\11\1\40\1\41\5\14\1\42\1\43"+
-    "\11\11\1\44\2\11\1\45\5\11\1\46\4\11\1\47\1\50\4\11\51\14\1\51\3\14\1\52\1"+
-    "\53\4\14\1\54\12\11\1\55\u0381\11");
+  private static int zzUnpackcmap_top(String packed, int offset, int [] result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
 
-  /* The ZZ_CMAP_Y table has 2944 entries */
-  static final char ZZ_CMAP_Y[] = zzUnpackCMap(
-    "\1\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\1\1\11\1\12\1\13\1\14\1\13\1\14\34"+
-    "\13\1\15\1\16\1\17\10\1\1\20\1\21\1\13\1\22\4\13\1\23\10\13\1\24\12\13\1\25"+
-    "\1\13\1\26\1\25\1\13\1\27\4\1\1\13\1\30\1\31\2\1\2\13\1\30\1\1\1\32\1\25\5"+
-    "\13\1\33\1\34\1\35\1\1\1\36\1\13\1\1\1\37\5\13\1\40\1\41\1\42\1\13\1\30\1"+
-    "\43\1\13\1\44\1\45\1\1\1\13\1\46\4\1\1\13\1\47\4\1\1\50\2\13\1\51\1\1\1\52"+
-    "\1\53\1\25\1\54\1\55\1\56\1\57\1\60\1\61\1\53\1\16\1\62\1\55\1\56\1\63\1\1"+
-    "\1\64\1\65\1\66\1\67\1\22\1\56\1\70\1\1\1\71\1\53\1\72\1\73\1\55\1\56\1\70"+
-    "\1\1\1\61\1\53\1\41\1\74\1\75\1\76\1\77\1\1\1\71\1\65\1\1\1\100\1\36\1\56"+
-    "\1\51\1\1\1\101\1\53\1\1\1\102\1\36\1\56\1\103\1\1\1\60\1\53\1\104\1\100\1"+
-    "\36\1\13\1\105\1\60\1\106\1\53\1\107\1\110\1\111\1\13\1\112\1\113\1\1\1\65"+
-    "\1\1\1\25\2\13\1\114\1\113\1\115\2\1\1\116\1\117\1\120\1\121\1\122\1\123\2"+
-    "\1\1\71\1\1\1\115\1\1\1\124\1\13\1\125\1\1\1\126\7\1\2\13\1\30\1\127\1\115"+
-    "\1\130\1\131\1\132\1\133\1\115\2\13\1\134\2\13\1\135\24\13\1\136\1\137\2\13"+
-    "\1\136\2\13\1\140\1\141\1\14\3\13\1\141\3\13\1\30\2\1\1\13\1\1\5\13\1\142"+
-    "\1\25\45\13\1\143\1\13\1\25\1\30\4\13\1\30\1\144\1\145\1\16\1\13\1\16\1\13"+
-    "\1\16\1\145\1\71\3\13\1\146\1\1\1\147\1\115\2\1\1\115\5\13\1\27\1\150\1\13"+
-    "\1\151\4\13\1\40\1\13\1\152\2\1\1\65\1\13\1\153\1\154\2\13\1\155\1\13\1\77"+
-    "\1\115\2\1\1\13\1\113\3\13\1\154\2\1\2\115\1\156\5\1\1\110\2\13\1\146\1\157"+
-    "\1\115\2\1\1\160\1\13\1\161\1\42\2\13\1\40\1\1\2\13\1\146\1\1\1\162\1\42\1"+
-    "\13\1\153\1\46\5\1\1\163\1\164\14\13\4\1\21\13\1\142\2\13\1\142\1\165\1\13"+
-    "\1\153\3\13\1\166\1\167\1\170\1\125\1\167\2\1\1\171\4\1\1\172\1\1\1\125\6"+
-    "\1\1\173\1\174\1\175\1\176\1\177\3\1\1\200\147\1\2\13\1\152\2\13\1\152\10"+
-    "\13\1\201\1\202\2\13\1\134\3\13\1\203\1\1\1\13\1\113\4\204\4\1\1\127\35\1"+
-    "\1\205\2\1\1\206\1\25\4\13\1\207\1\25\4\13\1\135\1\110\1\13\1\153\1\25\4\13"+
-    "\1\152\1\1\1\13\1\30\3\1\1\13\40\1\133\13\1\40\4\1\135\13\1\40\2\1\10\13\1"+
-    "\125\4\1\2\13\1\153\20\13\1\125\1\13\1\210\1\1\2\13\1\152\1\127\1\13\1\153"+
-    "\4\13\1\40\2\1\1\211\1\212\5\13\1\213\1\13\1\152\1\27\3\1\1\211\1\214\1\13"+
-    "\1\31\1\1\3\13\1\146\1\212\2\13\1\146\1\1\1\115\1\1\1\215\1\42\1\13\1\40\1"+
-    "\13\1\113\1\1\1\13\1\125\1\50\2\13\1\31\1\127\1\115\1\216\1\217\2\13\1\46"+
-    "\1\1\1\220\1\115\1\13\1\221\3\13\1\222\1\223\1\224\1\30\1\66\1\225\1\226\1"+
-    "\204\2\13\1\135\1\40\7\13\1\31\1\115\72\13\1\146\1\13\1\227\2\13\1\155\20"+
-    "\1\26\13\1\153\6\13\1\77\2\1\1\113\1\230\1\56\1\231\1\232\6\13\1\16\1\1\1"+
-    "\160\25\13\1\153\1\1\4\13\1\212\2\13\1\27\2\1\1\155\7\1\1\216\7\13\1\125\1"+
-    "\1\1\115\1\25\1\30\1\25\1\30\1\233\4\13\1\152\1\234\1\235\2\1\1\236\1\13\1"+
-    "\14\1\237\2\153\2\1\7\13\1\30\30\1\1\13\1\125\3\13\1\71\2\1\2\13\1\1\1\13"+
-    "\1\240\2\13\1\40\1\13\1\153\2\13\1\241\3\1\11\13\1\153\1\115\2\13\1\241\1"+
-    "\13\1\155\2\13\1\27\3\13\1\146\11\1\23\13\1\113\1\13\1\40\1\27\11\1\1\242"+
-    "\2\13\1\243\1\13\1\40\1\13\1\113\1\13\1\152\4\1\1\13\1\244\1\13\1\40\1\13"+
-    "\1\77\4\1\3\13\1\245\4\1\1\71\1\246\1\13\1\146\2\1\1\13\1\125\1\13\1\125\2"+
-    "\1\1\124\1\13\1\154\1\1\3\13\1\40\1\13\1\40\1\13\1\31\1\13\1\16\6\1\4\13\1"+
-    "\46\3\1\3\13\1\31\3\13\1\31\60\1\1\160\2\13\1\27\2\1\1\65\1\1\1\160\2\13\2"+
-    "\1\1\13\1\46\1\115\1\160\1\13\1\113\1\65\1\1\2\13\1\247\1\160\2\13\1\31\1"+
-    "\250\1\251\2\1\1\13\1\22\1\155\5\1\1\252\1\253\1\46\2\13\1\152\1\1\1\115\1"+
-    "\73\1\55\1\56\1\70\1\1\1\254\1\16\11\1\3\13\1\154\1\255\1\115\2\1\3\13\1\1"+
-    "\1\256\1\115\12\1\2\13\1\152\2\1\1\257\2\1\3\13\1\1\1\260\1\115\2\1\2\13\1"+
-    "\30\1\1\1\115\3\1\1\13\1\77\1\1\1\115\26\1\4\13\1\115\1\127\34\1\3\13\1\46"+
-    "\20\1\1\56\1\13\1\152\1\1\1\71\1\115\1\1\1\212\1\13\67\1\71\13\1\77\16\1\14"+
-    "\13\1\146\53\1\2\13\1\152\75\1\44\13\1\113\33\1\43\13\1\46\1\13\1\152\1\115"+
-    "\6\1\1\13\1\153\1\1\3\13\1\1\1\146\1\115\1\160\1\261\1\13\67\1\4\13\1\154"+
-    "\1\71\3\1\1\160\4\1\1\71\1\1\76\13\1\125\1\1\57\13\1\31\20\1\1\16\77\1\6\13"+
-    "\1\30\1\125\1\46\1\77\66\1\5\13\1\216\3\13\1\145\1\262\1\263\1\264\3\13\1"+
-    "\265\1\266\1\13\1\267\1\270\1\36\24\13\1\271\1\13\1\36\1\135\1\13\1\135\1"+
-    "\13\1\216\1\13\1\216\1\152\1\13\1\152\1\13\1\56\1\13\1\56\1\13\1\272\3\273"+
-    "\14\13\1\154\3\1\4\13\1\146\1\115\112\1\1\264\1\13\1\274\1\275\1\276\1\277"+
-    "\1\300\1\301\1\302\1\155\1\303\1\155\24\1\55\13\1\113\2\1\103\13\1\154\15"+
-    "\13\1\153\150\13\1\16\25\1\41\13\1\153\36\1");
 
-  /* The ZZ_CMAP_A table has 3136 entries */
-  static final char ZZ_CMAP_A[] = zzUnpackCMap(
-    "\11\0\1\4\1\10\1\102\1\103\1\102\22\0\1\4\1\14\1\31\1\13\1\11\1\71\1\67\1"+
-    "\26\1\75\1\76\1\40\1\64\1\100\1\25\1\22\1\12\1\15\11\1\1\72\1\77\1\65\1\62"+
-    "\1\66\1\63\1\101\1\3\1\17\2\3\1\24\1\23\5\5\1\20\10\5\1\21\2\5\1\16\2\5\1"+
-    "\73\1\27\1\74\1\0\1\2\1\7\1\44\1\55\1\51\1\61\1\43\1\50\1\54\1\34\1\35\1\56"+
-    "\1\53\1\45\1\5\1\46\1\52\1\42\1\5\1\47\1\36\1\33\1\30\1\60\1\57\1\16\1\41"+
-    "\1\5\1\32\1\70\1\37\7\0\1\102\24\0\1\5\12\0\1\5\4\0\1\5\5\0\27\5\1\0\12\5"+
-    "\4\0\14\5\16\0\5\5\7\0\1\5\1\0\1\5\1\0\5\5\1\0\2\5\2\0\4\5\1\0\1\5\6\0\1\5"+
-    "\1\0\3\5\1\0\1\5\1\0\4\5\1\0\23\5\1\0\13\5\10\0\6\5\1\0\26\5\2\0\1\5\6\0\10"+
-    "\5\10\0\13\5\5\0\3\5\15\0\12\6\4\0\6\5\1\0\1\5\17\0\2\5\7\0\2\5\12\6\3\5\2"+
-    "\0\2\5\1\0\16\5\15\0\11\5\13\0\1\5\16\0\12\6\6\5\4\0\2\5\4\0\1\5\5\0\6\5\4"+
-    "\0\1\5\11\0\1\5\3\0\1\5\7\0\11\5\7\0\5\5\1\0\10\5\6\0\26\5\3\0\1\5\2\0\1\5"+
-    "\7\0\12\5\4\0\12\6\1\5\4\0\10\5\2\0\2\5\2\0\26\5\1\0\7\5\1\0\1\5\3\0\4\5\3"+
-    "\0\1\5\20\0\1\5\15\0\2\5\1\0\1\5\5\0\6\5\4\0\2\5\1\0\2\5\1\0\2\5\1\0\2\5\17"+
-    "\0\4\5\1\0\1\5\7\0\12\6\2\0\3\5\20\0\11\5\1\0\2\5\1\0\2\5\1\0\5\5\3\0\1\5"+
-    "\2\0\1\5\30\0\1\5\13\0\10\5\2\0\1\5\3\0\1\5\1\0\6\5\3\0\3\5\1\0\4\5\3\0\2"+
-    "\5\1\0\1\5\1\0\2\5\3\0\2\5\3\0\3\5\3\0\14\5\13\0\10\5\1\0\2\5\10\0\3\5\5\0"+
-    "\1\5\4\0\10\5\1\0\6\5\1\0\5\5\3\0\1\5\3\0\2\5\15\0\13\5\2\0\1\5\6\0\3\5\10"+
-    "\0\1\5\12\0\6\5\5\0\22\5\3\0\10\5\1\0\11\5\1\0\1\5\2\0\7\5\11\0\1\5\1\0\2"+
-    "\5\14\0\12\6\7\0\2\5\1\0\1\5\2\0\2\5\1\0\1\5\2\0\1\5\6\0\4\5\1\0\7\5\1\0\3"+
-    "\5\1\0\1\5\1\0\1\5\2\0\2\5\1\0\4\5\1\0\2\5\11\0\1\5\2\0\5\5\1\0\1\5\11\0\12"+
-    "\6\2\0\14\5\1\0\24\5\13\0\5\5\22\0\7\5\4\0\4\5\3\0\1\5\3\0\2\5\7\0\3\5\4\0"+
-    "\15\5\14\0\1\5\1\0\6\5\1\0\1\5\5\0\1\5\2\0\13\5\1\0\15\5\1\0\4\5\2\0\7\5\1"+
-    "\0\1\5\1\0\4\5\2\0\1\5\1\0\4\5\2\0\7\5\1\0\1\5\1\0\4\5\2\0\16\5\2\0\6\5\2"+
-    "\0\15\5\2\0\1\5\1\0\10\5\7\0\15\5\1\0\6\5\23\0\1\5\4\0\1\5\3\0\5\5\2\0\22"+
-    "\5\1\0\1\5\5\0\17\5\1\0\16\5\2\0\5\5\13\0\14\5\13\0\1\5\15\0\7\5\7\0\16\5"+
-    "\15\0\2\5\12\6\3\0\3\5\11\0\4\5\1\0\4\5\3\0\2\5\11\0\10\5\1\0\1\5\1\0\1\5"+
-    "\1\0\1\5\1\0\6\5\1\0\7\5\1\0\1\5\3\0\3\5\1\0\7\5\3\0\4\5\2\0\6\5\14\0\2\102"+
-    "\7\0\1\5\15\0\1\5\2\0\1\5\4\0\1\5\2\0\12\5\1\0\1\5\3\0\5\5\6\0\1\5\1\0\1\5"+
-    "\1\0\1\5\1\0\4\5\1\0\13\5\2\0\4\5\5\0\5\5\4\0\1\5\4\0\2\5\13\0\5\5\6\0\4\5"+
-    "\3\0\2\5\14\0\10\5\7\0\10\5\1\0\7\5\6\0\2\5\12\0\5\5\5\0\2\5\3\0\7\5\6\0\3"+
-    "\5\12\6\2\5\13\0\11\5\2\0\27\5\2\0\7\5\1\0\3\5\1\0\4\5\1\0\4\5\2\0\6\5\3\0"+
-    "\1\5\1\0\1\5\2\0\5\5\1\0\12\5\12\6\5\5\1\0\3\5\1\0\10\5\4\0\7\5\3\0\1\5\3"+
-    "\0\2\5\1\0\1\5\3\0\2\5\2\0\5\5\2\0\1\5\1\0\1\5\30\0\3\5\3\0\6\5\2\0\6\5\2"+
-    "\0\6\5\11\0\7\5\4\0\5\5\3\0\5\5\5\0\1\5\1\0\10\5\1\0\5\5\1\0\1\5\1\0\2\5\1"+
-    "\0\2\5\1\0\12\5\6\0\12\5\2\0\6\5\2\0\6\5\2\0\6\5\2\0\3\5\3\0\14\5\1\0\16\5"+
-    "\1\0\2\5\1\0\2\5\1\0\10\5\6\0\4\5\4\0\16\5\2\0\1\5\1\0\14\5\1\0\2\5\3\0\1"+
-    "\5\2\0\4\5\1\0\2\5\12\0\10\5\6\0\6\5\1\0\3\5\1\0\12\5\3\0\1\5\12\0\4\5\13"+
-    "\0\12\6\1\5\1\0\1\5\3\0\7\5\1\0\1\5\1\0\4\5\1\0\17\5\1\0\2\5\14\0\3\5\7\0"+
-    "\4\5\11\0\2\5\1\0\1\5\20\0\4\5\10\0\1\5\13\0\10\5\5\0\3\5\2\0\1\5\2\0\2\5"+
-    "\2\0\4\5\1\0\14\5\1\0\1\5\1\0\7\5\1\0\21\5\1\0\4\5\2\0\10\5\1\0\7\5\1\0\14"+
-    "\5\1\0\4\5\1\0\5\5\1\0\1\5\3\0\14\5\2\0\13\5\1\0\10\5\2\0\22\6\1\0\2\5\1\0"+
-    "\1\5\2\0\1\5\1\0\12\5\1\0\4\5\1\0\1\5\1\0\1\5\6\0\1\5\4\0\1\5\1\0\1\5\1\0"+
-    "\1\5\1\0\3\5\1\0\2\5\1\0\1\5\2\0\1\5\1\0\1\5\1\0\1\5\1\0\1\5\1\0\1\5\1\0\2"+
-    "\5\1\0\1\5\2\0\4\5\1\0\7\5\1\0\4\5\1\0\4\5\1\0\1\5\1\0\12\5\1\0\5\5\1\0\3"+
-    "\5\1\0\5\5\1\0\5\5");
+  /**
+   * Second-level tables for translating characters to character classes
+   */
+  private static final int [] ZZ_CMAP_BLOCKS = zzUnpackcmap_blocks();
 
-  /** 
+  private static final String ZZ_CMAP_BLOCKS_PACKED_0 =
+    "\11\0\1\1\1\2\1\3\1\4\1\3\22\0\1\1"+
+    "\1\5\1\6\1\7\1\10\1\11\1\12\1\13\1\14"+
+    "\1\15\1\16\1\17\1\20\1\21\1\22\1\23\1\24"+
+    "\11\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34"+
+    "\1\35\1\36\2\35\1\37\1\40\5\41\1\42\10\41"+
+    "\1\43\2\41\1\44\2\41\1\45\1\46\1\47\1\0"+
+    "\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57"+
+    "\1\60\1\61\1\62\1\63\1\64\1\65\1\41\1\66"+
+    "\1\67\1\70\1\41\1\71\1\72\1\73\1\74\1\75"+
+    "\1\76\1\44\1\77\1\41\1\100\1\101\1\102\7\0"+
+    "\1\3\44\0\1\41\12\0\1\41\4\0\1\41\5\0"+
+    "\27\41\1\0\37\41\1\0\u01ca\41\4\0\14\41\16\0"+
+    "\5\41\7\0\1\41\1\0\1\41\201\0\5\41\1\0"+
+    "\2\41\2\0\4\41\1\0\1\41\6\0\1\41\1\0"+
+    "\3\41\1\0\1\41\1\0\24\41\1\0\123\41\1\0"+
+    "\213\41\10\0\246\41\1\0\46\41\2\0\1\41\6\0"+
+    "\51\41\107\0\33\41\4\0\4\41\55\0\53\41\25\0"+
+    "\12\103\4\0\2\41\1\0\143\41\1\0\1\41\17\0"+
+    "\2\41\7\0\2\41\12\103\3\41\2\0\1\41\20\0"+
+    "\1\41\1\0\36\41\35\0\131\41\13\0\1\41\16\0"+
+    "\12\103\41\41\11\0\2\41\4\0\1\41\5\0\26\41"+
+    "\4\0\1\41\11\0\1\41\3\0\1\41\27\0\31\41"+
+    "\7\0\13\41\65\0\25\41\1\0\10\41\106\0\66\41"+
+    "\3\0\1\41\22\0\1\41\7\0\12\41\4\0\12\103"+
+    "\1\0\20\41\4\0\10\41\2\0\2\41\2\0\26\41"+
+    "\1\0\7\41\1\0\1\41\3\0\4\41\3\0\1\41"+
+    "\20\0\1\41\15\0\2\41\1\0\3\41\4\0\12\103"+
+    "\2\41\12\0\1\41\10\0\6\41\4\0\2\41\2\0"+
+    "\26\41\1\0\7\41\1\0\2\41\1\0\2\41\1\0"+
+    "\2\41\37\0\4\41\1\0\1\41\7\0\12\103\2\0"+
+    "\3\41\20\0\11\41\1\0\3\41\1\0\26\41\1\0"+
+    "\7\41\1\0\2\41\1\0\5\41\3\0\1\41\22\0"+
+    "\1\41\17\0\2\41\4\0\12\103\11\0\1\41\13\0"+
+    "\10\41\2\0\2\41\2\0\26\41\1\0\7\41\1\0"+
+    "\2\41\1\0\5\41\3\0\1\41\36\0\2\41\1\0"+
+    "\3\41\4\0\12\103\1\0\1\41\21\0\1\41\1\0"+
+    "\6\41\3\0\3\41\1\0\4\41\3\0\2\41\1\0"+
+    "\1\41\1\0\2\41\3\0\2\41\3\0\3\41\3\0"+
+    "\14\41\26\0\1\41\25\0\12\103\25\0\10\41\1\0"+
+    "\3\41\1\0\27\41\1\0\20\41\3\0\1\41\32\0"+
+    "\3\41\5\0\2\41\4\0\12\103\20\0\1\41\4\0"+
+    "\10\41\1\0\3\41\1\0\27\41\1\0\12\41\1\0"+
+    "\5\41\3\0\1\41\40\0\1\41\1\0\2\41\4\0"+
+    "\12\103\1\0\2\41\22\0\10\41\1\0\3\41\1\0"+
+    "\51\41\2\0\1\41\20\0\1\41\5\0\3\41\10\0"+
+    "\3\41\4\0\12\103\12\0\6\41\5\0\22\41\3\0"+
+    "\30\41\1\0\11\41\1\0\1\41\2\0\7\41\37\0"+
+    "\12\103\21\0\60\41\1\0\2\41\14\0\7\41\11\0"+
+    "\12\103\47\0\2\41\1\0\1\41\1\0\5\41\1\0"+
+    "\30\41\1\0\1\41\1\0\12\41\1\0\2\41\11\0"+
+    "\1\41\2\0\5\41\1\0\1\41\11\0\12\103\2\0"+
+    "\4\41\40\0\1\41\37\0\12\103\26\0\10\41\1\0"+
+    "\44\41\33\0\5\41\163\0\53\41\24\0\1\41\12\103"+
+    "\6\0\6\41\4\0\4\41\3\0\1\41\3\0\2\41"+
+    "\7\0\3\41\4\0\15\41\14\0\1\41\1\0\12\103"+
+    "\6\0\46\41\1\0\1\41\5\0\1\41\2\0\53\41"+
+    "\1\0\115\41\1\0\4\41\2\0\7\41\1\0\1\41"+
+    "\1\0\4\41\2\0\51\41\1\0\4\41\2\0\41\41"+
+    "\1\0\4\41\2\0\7\41\1\0\1\41\1\0\4\41"+
+    "\2\0\17\41\1\0\71\41\1\0\4\41\2\0\103\41"+
+    "\45\0\20\41\20\0\126\41\2\0\6\41\3\0\u016c\41"+
+    "\2\0\21\41\1\0\32\41\5\0\113\41\6\0\10\41"+
+    "\7\0\15\41\1\0\4\41\16\0\22\41\16\0\22\41"+
+    "\16\0\15\41\1\0\3\41\17\0\64\41\43\0\1\41"+
+    "\4\0\1\41\3\0\12\103\46\0\12\103\6\0\131\41"+
+    "\7\0\5\41\2\0\42\41\1\0\1\41\5\0\106\41"+
+    "\12\0\37\41\47\0\12\103\36\41\2\0\5\41\13\0"+
+    "\54\41\4\0\32\41\6\0\12\103\46\0\27\41\11\0"+
+    "\65\41\53\0\12\103\6\0\12\103\15\0\1\41\135\0"+
+    "\57\41\21\0\7\41\4\0\12\103\51\0\36\41\15\0"+
+    "\2\41\12\103\54\41\32\0\44\41\34\0\12\103\3\0"+
+    "\3\41\12\103\44\41\2\0\11\41\7\0\53\41\2\0"+
+    "\3\41\51\0\4\41\1\0\6\41\1\0\2\41\3\0"+
+    "\1\41\5\0\300\41\100\0\26\41\2\0\6\41\2\0"+
+    "\46\41\2\0\6\41\2\0\10\41\1\0\1\41\1\0"+
+    "\1\41\1\0\1\41\1\0\37\41\2\0\65\41\1\0"+
+    "\7\41\1\0\1\41\3\0\3\41\1\0\7\41\3\0"+
+    "\4\41\2\0\6\41\4\0\15\41\5\0\3\41\1\0"+
+    "\7\41\53\0\2\3\107\0\1\41\15\0\1\41\20\0"+
+    "\15\41\145\0\1\41\4\0\1\41\2\0\12\41\1\0"+
+    "\1\41\3\0\5\41\6\0\1\41\1\0\1\41\1\0"+
+    "\1\41\1\0\4\41\1\0\13\41\2\0\4\41\5\0"+
+    "\5\41\4\0\1\41\64\0\2\41\u017b\0\57\41\1\0"+
+    "\57\41\1\0\205\41\6\0\4\41\3\0\2\41\14\0"+
+    "\46\41\1\0\1\41\5\0\1\41\2\0\70\41\7\0"+
+    "\1\41\20\0\27\41\11\0\7\41\1\0\7\41\1\0"+
+    "\7\41\1\0\7\41\1\0\7\41\1\0\7\41\1\0"+
+    "\7\41\1\0\7\41\120\0\1\41\325\0\2\41\52\0"+
+    "\5\41\5\0\2\41\4\0\126\41\6\0\3\41\1\0"+
+    "\132\41\1\0\4\41\5\0\53\41\1\0\136\41\21\0"+
+    "\33\41\65\0\306\41\112\0\360\41\20\0\215\41\103\0"+
+    "\56\41\2\0\15\41\3\0\20\41\12\103\2\41\24\0"+
+    "\57\41\20\0\37\41\2\0\106\41\61\0\11\41\2\0"+
+    "\147\41\2\0\65\41\2\0\5\41\60\0\13\41\1\0"+
+    "\3\41\1\0\4\41\1\0\27\41\35\0\64\41\16\0"+
+    "\62\41\34\0\12\103\30\0\6\41\3\0\1\41\1\0"+
+    "\2\41\1\0\12\103\34\41\12\0\27\41\31\0\35\41"+
+    "\7\0\57\41\34\0\1\41\12\103\6\0\5\41\1\0"+
+    "\12\41\12\103\5\41\1\0\51\41\27\0\3\41\1\0"+
+    "\10\41\4\0\12\103\6\0\27\41\3\0\1\41\3\0"+
+    "\62\41\1\0\1\41\3\0\2\41\2\0\5\41\2\0"+
+    "\1\41\1\0\1\41\30\0\3\41\2\0\13\41\7\0"+
+    "\3\41\14\0\6\41\2\0\6\41\2\0\6\41\11\0"+
+    "\7\41\1\0\7\41\1\0\53\41\1\0\14\41\10\0"+
+    "\163\41\15\0\12\103\6\0\244\41\14\0\27\41\4\0"+
+    "\61\41\4\0\u0100\3\156\41\2\0\152\41\46\0\7\41"+
+    "\14\0\5\41\5\0\1\41\1\0\12\41\1\0\15\41"+
+    "\1\0\5\41\1\0\1\41\1\0\2\41\1\0\2\41"+
+    "\1\0\154\41\41\0\153\41\22\0\100\41\2\0\66\41"+
+    "\50\0\14\41\164\0\5\41\1\0\207\41\23\0\12\103"+
+    "\7\0\32\41\6\0\32\41\13\0\131\41\3\0\6\41"+
+    "\2\0\6\41\2\0\6\41\2\0\3\41\43\0\14\41"+
+    "\1\0\32\41\1\0\23\41\1\0\2\41\1\0\17\41"+
+    "\2\0\16\41\42\0\173\41\205\0\35\41\3\0\61\41"+
+    "\57\0\40\41\15\0\24\41\1\0\10\41\6\0\46\41"+
+    "\12\0\36\41\2\0\44\41\4\0\10\41\60\0\236\41"+
+    "\2\0\12\103\6\0\44\41\4\0\44\41\4\0\50\41"+
+    "\10\0\64\41\234\0\67\41\11\0\26\41\12\0\10\41"+
+    "\230\0\6\41\2\0\1\41\1\0\54\41\1\0\2\41"+
+    "\3\0\1\41\2\0\27\41\12\0\27\41\11\0\37\41"+
+    "\101\0\23\41\1\0\2\41\12\0\26\41\12\0\32\41"+
+    "\106\0\70\41\6\0\2\41\100\0\1\41\17\0\4\41"+
+    "\1\0\3\41\1\0\35\41\52\0\35\41\3\0\35\41"+
+    "\43\0\10\41\1\0\34\41\33\0\66\41\12\0\26\41"+
+    "\12\0\23\41\15\0\22\41\156\0\111\41\67\0\63\41"+
+    "\15\0\63\41\15\0\44\41\14\0\12\103\306\0\35\41"+
+    "\12\0\1\41\10\0\26\41\232\0\27\41\14\0\65\41"+
+    "\56\0\12\103\23\0\55\41\40\0\31\41\7\0\12\103"+
+    "\11\0\44\41\17\0\12\103\4\0\1\41\13\0\43\41"+
+    "\3\0\1\41\14\0\60\41\16\0\4\41\13\0\12\103"+
+    "\1\41\1\0\1\41\43\0\22\41\1\0\31\41\124\0"+
+    "\7\41\1\0\1\41\1\0\4\41\1\0\17\41\1\0"+
+    "\12\41\7\0\57\41\21\0\12\103\13\0\10\41\2\0"+
+    "\2\41\2\0\26\41\1\0\7\41\1\0\2\41\1\0"+
+    "\5\41\3\0\1\41\22\0\1\41\14\0\5\41\236\0"+
+    "\65\41\22\0\4\41\5\0\12\103\5\0\1\41\40\0"+
+    "\60\41\24\0\2\41\1\0\1\41\10\0\12\103\246\0"+
+    "\57\41\51\0\4\41\44\0\60\41\24\0\1\41\13\0"+
+    "\12\103\46\0\53\41\15\0\1\41\7\0\12\103\66\0"+
+    "\33\41\25\0\12\103\306\0\54\41\164\0\100\41\12\103"+
+    "\25\0\1\41\240\0\10\41\2\0\47\41\20\0\1\41"+
+    "\1\0\1\41\34\0\1\41\12\0\50\41\7\0\1\41"+
+    "\25\0\1\41\13\0\56\41\23\0\1\41\42\0\71\41"+
+    "\7\0\11\41\1\0\45\41\21\0\1\41\17\0\12\103"+
+    "\30\0\36\41\160\0\7\41\1\0\2\41\1\0\46\41"+
+    "\25\0\1\41\11\0\12\103\6\0\6\41\1\0\2\41"+
+    "\1\0\40\41\16\0\1\41\7\0\12\103\u0136\0\23\41"+
+    "\15\0\232\41\346\0\304\41\274\0\57\41\321\0\107\41"+
+    "\271\0\71\41\7\0\37\41\1\0\12\103\146\0\36\41"+
+    "\22\0\60\41\20\0\4\41\14\0\12\103\11\0\25\41"+
+    "\5\0\23\41\260\0\100\41\200\0\113\41\5\0\1\41"+
+    "\102\0\15\41\100\0\2\41\1\0\1\41\34\0\370\41"+
+    "\10\0\363\41\15\0\37\41\61\0\3\41\21\0\4\41"+
+    "\10\0\u018c\41\4\0\153\41\5\0\15\41\3\0\11\41"+
+    "\7\0\12\41\146\0\125\41\1\0\107\41\1\0\2\41"+
+    "\2\0\1\41\2\0\2\41\2\0\4\41\1\0\14\41"+
+    "\1\0\1\41\1\0\7\41\1\0\101\41\1\0\4\41"+
+    "\2\0\10\41\1\0\7\41\1\0\34\41\1\0\4\41"+
+    "\1\0\5\41\1\0\1\41\3\0\7\41\1\0\u0154\41"+
+    "\2\0\31\41\1\0\31\41\1\0\37\41\1\0\31\41"+
+    "\1\0\37\41\1\0\31\41\1\0\37\41\1\0\31\41"+
+    "\1\0\37\41\1\0\31\41\1\0\10\41\2\0\62\103"+
+    "\55\41\12\0\7\41\2\0\12\103\4\0\1\41\u0171\0"+
+    "\54\41\4\0\12\103\6\0\305\41\73\0\104\41\7\0"+
+    "\1\41\4\0\12\103\246\0\4\41\1\0\33\41\1\0"+
+    "\2\41\1\0\1\41\2\0\1\41\1\0\12\41\1\0"+
+    "\4\41\1\0\1\41\1\0\1\41\6\0\1\41\4\0"+
+    "\1\41\1\0\1\41\1\0\1\41\1\0\3\41\1\0"+
+    "\2\41\1\0\1\41\2\0\1\41\1\0\1\41\1\0"+
+    "\1\41\1\0\1\41\1\0\1\41\1\0\2\41\1\0"+
+    "\1\41\2\0\4\41\1\0\7\41\1\0\4\41\1\0"+
+    "\4\41\1\0\1\41\1\0\12\41\1\0\21\41\5\0"+
+    "\3\41\1\0\5\41\1\0\21\41\104\0\327\41\51\0"+
+    "\65\41\13\0\336\41\2\0\u0182\41\16\0\u0131\41\37\0"+
+    "\36\41\342\0";
+
+  private static int [] zzUnpackcmap_blocks() {
+    int [] result = new int[27904];
+    int offset = 0;
+    offset = zzUnpackcmap_blocks(ZZ_CMAP_BLOCKS_PACKED_0, offset, result);
+    return result;
+  }
+
+  private static int zzUnpackcmap_blocks(String packed, int offset, int [] result) {
+    int i = 0;       /* index in packed string  */
+    int j = offset;  /* index in unpacked array */
+    int l = packed.length();
+    while (i < l) {
+      int count = packed.charAt(i++);
+      int value = packed.charAt(i++);
+      do result[j++] = value; while (--count > 0);
+    }
+    return j;
+  }
+
+  /**
    * Translates DFA states to action switch labels.
    */
   private static final int [] ZZ_ACTION = zzUnpackAction();
 
   private static final String ZZ_ACTION_PACKED_0 =
     "\6\0\1\1\1\2\1\3\1\4\1\5\1\1\1\6"+
-    "\1\7\1\10\1\2\1\11\1\12\1\13\1\14\1\15"+
-    "\3\3\1\16\1\17\14\3\1\20\1\21\1\22\1\23"+
-    "\1\24\1\25\1\1\1\26\1\27\1\30\1\31\1\32"+
-    "\1\33\1\34\1\35\1\36\1\37\1\40\1\37\1\1"+
-    "\1\41\2\37\1\42\1\1\1\42\3\43\1\44\1\45"+
-    "\2\2\1\0\2\46\1\0\1\47\1\0\1\50\1\51"+
-    "\1\52\1\53\1\0\1\54\1\0\2\2\1\46\1\55"+
-    "\1\56\1\57\1\60\2\13\1\0\3\3\1\61\1\62"+
-    "\1\63\1\3\1\64\2\3\1\65\13\3\1\66\1\67"+
-    "\1\70\1\71\1\72\1\73\1\74\1\75\1\76\1\77"+
-    "\1\100\1\101\1\102\1\0\1\103\2\104\2\0\1\42"+
-    "\1\105\1\106\1\0\1\107\1\46\1\3\1\0\1\110"+
-    "\1\111\1\112\1\113\1\0\1\114\1\115\1\116\4\3"+
-    "\1\117\4\3\1\120\2\3\1\121\1\3\1\122\6\3"+
-    "\1\123\1\124\1\125\2\0\1\126\2\42\1\47\1\127"+
-    "\1\130\1\131\2\3\1\132\3\3\1\133\1\134\7\3"+
-    "\1\135\1\102\1\0\1\136\1\137\3\3\1\140\2\3"+
-    "\1\141\1\142\2\3\1\143\1\144\1\0\1\3\1\145"+
-    "\2\3\1\146\1\3\1\147\2\3\1\150\3\3\1\151"+
-    "\1\152\1\153";
+    "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1\16"+
+    "\1\17\1\20\2\21\1\22\1\23\1\24\1\25\1\26"+
+    "\1\27\1\30\1\31\1\32\1\33\1\34\17\31\1\35"+
+    "\1\1\1\36\1\37\1\40\1\41\1\37\1\1\2\37"+
+    "\1\42\1\1\1\42\3\43\1\44\1\45\1\46\2\0"+
+    "\1\47\1\0\1\50\1\0\1\51\1\52\2\10\1\53"+
+    "\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63"+
+    "\1\64\1\65\2\0\1\21\2\62\3\21\1\66\1\67"+
+    "\1\70\1\71\1\72\1\73\1\0\1\74\3\31\1\75"+
+    "\4\31\1\76\1\77\1\100\12\31\1\101\1\0\1\102"+
+    "\1\0\1\103\2\104\2\0\1\42\1\105\1\106\1\107"+
+    "\1\110\1\111\1\112\1\0\1\113\1\114\1\115\1\116"+
+    "\2\0\1\62\1\117\1\31\1\120\5\31\1\121\1\122"+
+    "\11\31\1\123\1\31\1\124\1\125\2\31\2\0\1\126"+
+    "\2\42\1\127\1\50\1\130\3\31\1\131\2\31\1\132"+
+    "\4\31\1\133\1\31\1\134\1\31\1\135\1\31\1\102"+
+    "\1\0\1\136\1\137\1\140\1\31\1\141\4\31\1\142"+
+    "\1\143\2\31\1\144\1\0\2\31\1\145\1\31\1\146"+
+    "\1\31\1\147\2\31\1\150\1\31\1\151\2\31\1\152"+
+    "\1\153";
 
   private static int [] zzUnpackAction() {
-    int [] result = new int[233];
+    int [] result = new int[235];
     int offset = 0;
     offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
     return result;
@@ -216,45 +335,45 @@
   }
 
 
-  /** 
+  /**
    * Translates a state to a row index in the transition table
    */
   private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
 
   private static final String ZZ_ROWMAP_PACKED_0 =
     "\0\0\0\104\0\210\0\314\0\u0110\0\u0154\0\u0198\0\u01dc"+
-    "\0\u0220\0\u0264\0\u02a8\0\u02ec\0\u0330\0\u0374\0\u03b8\0\u03fc"+
-    "\0\u0440\0\u0484\0\u04c8\0\u050c\0\u0198\0\u0550\0\u0594\0\u05d8"+
-    "\0\u0198\0\u061c\0\u0660\0\u06a4\0\u06e8\0\u072c\0\u0770\0\u07b4"+
-    "\0\u07f8\0\u083c\0\u0880\0\u08c4\0\u0908\0\u094c\0\u0990\0\u0198"+
-    "\0\u09d4\0\u0a18\0\u0a5c\0\u0aa0\0\u0ae4\0\u0b28\0\u0b6c\0\u0198"+
-    "\0\u0198\0\u0198\0\u0198\0\u0bb0\0\u0198\0\u0198\0\u0bf4\0\u0198"+
-    "\0\u0c38\0\u0c7c\0\u0198\0\u0198\0\u0cc0\0\u0d04\0\u0d48\0\u0d8c"+
+    "\0\u0220\0\u0264\0\u02a8\0\u02ec\0\u0330\0\u0374\0\u03b8\0\u0198"+
+    "\0\u0198\0\u03fc\0\u0440\0\u0198\0\u0484\0\u04c8\0\u050c\0\u0550"+
+    "\0\u0594\0\u05d8\0\u061c\0\u0660\0\u06a4\0\u06e8\0\u0198\0\u0198"+
+    "\0\u072c\0\u0198\0\u0198\0\u0770\0\u07b4\0\u07f8\0\u083c\0\u0880"+
+    "\0\u08c4\0\u0908\0\u094c\0\u0990\0\u09d4\0\u0a18\0\u0a5c\0\u0aa0"+
+    "\0\u0ae4\0\u0b28\0\u0b6c\0\u0198\0\u0bb0\0\u0198\0\u0bf4\0\u0198"+
+    "\0\u0198\0\u0c38\0\u0c7c\0\u0198\0\u0cc0\0\u0d04\0\u0d48\0\u0d8c"+
     "\0\u0198\0\u0dd0\0\u0e14\0\u0198\0\u0198\0\u0e58\0\u0e9c\0\u0ee0"+
-    "\0\u0198\0\u0f24\0\u0f68\0\u0fac\0\u0ff0\0\u1034\0\u1078\0\u0198"+
-    "\0\u10bc\0\u1100\0\u1144\0\u1188\0\u11cc\0\u1210\0\u1254\0\u1298"+
-    "\0\u0198\0\u0198\0\u0198\0\u0198\0\u12dc\0\u1320\0\u1364\0\u13a8"+
-    "\0\u13ec\0\u0220\0\u1430\0\u0220\0\u1474\0\u0198\0\u14b8\0\u14fc"+
-    "\0\u1540\0\u1584\0\u15c8\0\u160c\0\u1650\0\u1694\0\u16d8\0\u171c"+
-    "\0\u1760\0\u17a4\0\u17e8\0\u182c\0\u0220\0\u1870\0\u0198\0\u0198"+
-    "\0\u0198\0\u0198\0\u0198\0\u0198\0\u0198\0\u0198\0\u0198\0\u0198"+
-    "\0\u18b4\0\u18f8\0\u0198\0\u0198\0\u193c\0\u1980\0\u19c4\0\u1a08"+
-    "\0\u0198\0\u0198\0\u1a4c\0\u0198\0\u1a90\0\u0198\0\u1ad4\0\u1b18"+
-    "\0\u1b5c\0\u1b5c\0\u0198\0\u1ba0\0\u0198\0\u0198\0\u0198\0\u1be4"+
-    "\0\u1c28\0\u1c6c\0\u1cb0\0\u0220\0\u1cf4\0\u1d38\0\u1d7c\0\u1dc0"+
-    "\0\u0198\0\u1e04\0\u1e48\0\u0220\0\u1e8c\0\u0220\0\u1ed0\0\u1f14"+
-    "\0\u1f58\0\u1f9c\0\u1fe0\0\u2024\0\u0220\0\u0220\0\u0198\0\u2068"+
-    "\0\u20ac\0\u1980\0\u0198\0\u20f0\0\u0198\0\u0198\0\u0198\0\u0220"+
-    "\0\u2134\0\u2178\0\u0220\0\u21bc\0\u2200\0\u2244\0\u0220\0\u0220"+
-    "\0\u2288\0\u22cc\0\u2310\0\u2354\0\u2398\0\u23dc\0\u2420\0\u0220"+
-    "\0\u0198\0\u2464\0\u0d04\0\u0220\0\u24a8\0\u24ec\0\u2530\0\u0220"+
-    "\0\u2574\0\u25b8\0\u0220\0\u0220\0\u25fc\0\u2640\0\u0220\0\u0220"+
-    "\0\u2684\0\u26c8\0\u0220\0\u270c\0\u2750\0\u0220\0\u2794\0\u0220"+
-    "\0\u27d8\0\u281c\0\u0220\0\u2860\0\u28a4\0\u28e8\0\u0220\0\u0220"+
-    "\0\u0220";
+    "\0\u0f24\0\u0f68\0\u0fac\0\u0ff0\0\u0198\0\u0198\0\u0198\0\u1034"+
+    "\0\u0198\0\u0198\0\u0198\0\u0198\0\u0198\0\u0198\0\u1078\0\u10bc"+
+    "\0\u1100\0\u1144\0\u0198\0\u1188\0\u11cc\0\u1210\0\u1254\0\u0198"+
+    "\0\u1298\0\u12dc\0\u1320\0\u0198\0\u0198\0\u0198\0\u1364\0\u0198"+
+    "\0\u0198\0\u13a8\0\u13ec\0\u1430\0\u1474\0\u14b8\0\u072c\0\u14fc"+
+    "\0\u1540\0\u1584\0\u15c8\0\u072c\0\u160c\0\u072c\0\u1650\0\u1694"+
+    "\0\u16d8\0\u171c\0\u1760\0\u17a4\0\u17e8\0\u182c\0\u1870\0\u18b4"+
+    "\0\u0198\0\u0c38\0\u18f8\0\u193c\0\u0198\0\u0198\0\u1980\0\u19c4"+
+    "\0\u1a08\0\u1a4c\0\u0198\0\u0198\0\u0198\0\u1a90\0\u1a90\0\u0ee0"+
+    "\0\u1ad4\0\u0198\0\u0198\0\u1b18\0\u0198\0\u1b5c\0\u1ba0\0\u1be4"+
+    "\0\u0198\0\u0198\0\u0198\0\u1c28\0\u1c6c\0\u1cb0\0\u1cf4\0\u1d38"+
+    "\0\u072c\0\u072c\0\u1d7c\0\u1dc0\0\u1e04\0\u1e48\0\u1e8c\0\u1ed0"+
+    "\0\u1f14\0\u1f58\0\u1f9c\0\u072c\0\u1fe0\0\u072c\0\u072c\0\u2024"+
+    "\0\u2068\0\u20ac\0\u20f0\0\u19c4\0\u0198\0\u2134\0\u0198\0\u0198"+
+    "\0\u0198\0\u2178\0\u21bc\0\u2200\0\u072c\0\u2244\0\u2288\0\u072c"+
+    "\0\u22cc\0\u2310\0\u2354\0\u2398\0\u072c\0\u23dc\0\u072c\0\u2420"+
+    "\0\u072c\0\u2464\0\u0198\0\u24a8\0\u0d04\0\u072c\0\u072c\0\u24ec"+
+    "\0\u072c\0\u2530\0\u2574\0\u25b8\0\u25fc\0\u072c\0\u072c\0\u2640"+
+    "\0\u2684\0\u072c\0\u26c8\0\u270c\0\u2750\0\u072c\0\u2794\0\u072c"+
+    "\0\u27d8\0\u072c\0\u281c\0\u2860\0\u072c\0\u28a4\0\u072c\0\u28e8"+
+    "\0\u292c\0\u072c\0\u072c";
 
   private static int [] zzUnpackRowMap() {
-    int [] result = new int[233];
+    int [] result = new int[235];
     int offset = 0;
     offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
     return result;
@@ -263,7 +382,7 @@
   private static int zzUnpackRowMap(String packed, int offset, int [] result) {
     int i = 0;  /* index in packed string  */
     int j = offset;  /* index in unpacked array */
-    int l = packed.length();
+    int l = packed.length() - 1;
     while (i < l) {
       int high = packed.charAt(i++) << 16;
       result[j++] = high | packed.charAt(i++);
@@ -271,263 +390,212 @@
     return j;
   }
 
-  /** 
+  /**
    * The transition table of the DFA
    */
-  private static final int [] ZZ_TRANS = zzUnpackTrans();
+  private static final int [] ZZ_TRANS = zzUnpacktrans();
 
   private static final String ZZ_TRANS_PACKED_0 =
-    "\1\7\1\10\2\11\1\12\1\11\1\7\1\13\1\12"+
-    "\1\14\1\15\1\16\1\17\1\20\4\11\1\21\2\11"+
-    "\1\22\1\23\1\7\1\11\1\24\1\25\1\26\1\11"+
-    "\1\27\1\30\1\31\1\32\1\11\1\33\1\34\1\35"+
-    "\1\11\1\36\1\37\1\40\1\41\1\42\2\11\1\43"+
-    "\1\11\1\44\1\45\1\46\1\47\1\50\1\51\1\52"+
-    "\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\62"+
-    "\1\63\1\64\1\65\1\66\1\7\1\12\10\67\1\70"+
-    "\1\71\15\67\1\72\1\67\1\73\62\67\1\74\1\71"+
-    "\15\67\1\74\1\67\1\75\52\67\2\7\2\76\1\7"+
-    "\1\76\1\7\1\77\1\0\5\7\4\76\1\7\2\76"+
-    "\3\7\1\76\2\7\1\100\3\76\2\7\21\76\20\7"+
-    "\2\0\12\101\1\102\25\101\1\103\43\101\1\7\1\10"+
-    "\2\11\1\12\1\11\1\7\1\13\1\12\1\14\1\15"+
-    "\1\16\1\17\1\20\4\11\1\21\2\11\1\22\1\23"+
-    "\1\7\1\11\1\24\1\104\1\26\1\11\1\27\1\30"+
-    "\1\105\1\32\1\11\1\33\1\34\1\35\1\11\1\36"+
-    "\1\37\1\40\1\41\1\42\2\11\1\43\1\11\1\44"+
-    "\1\45\1\46\1\47\1\50\1\51\1\52\1\53\1\54"+
-    "\1\55\1\56\1\57\1\60\1\61\1\62\1\63\1\64"+
-    "\1\65\1\66\1\7\1\12\105\0\2\10\12\0\1\10"+
-    "\2\0\1\106\1\107\1\110\1\111\1\112\3\0\1\107"+
-    "\12\0\1\112\1\0\1\106\2\0\1\111\34\0\3\11"+
-    "\1\0\2\11\6\0\5\11\1\0\2\11\3\0\1\11"+
-    "\2\0\4\11\2\0\21\11\26\0\1\12\3\0\1\12"+
-    "\72\0\1\12\7\113\2\0\73\113\2\0\2\114\1\0"+
-    "\1\114\1\0\1\115\6\0\4\114\1\0\2\114\3\0"+
-    "\1\114\2\0\4\114\2\0\21\114\34\0\1\116\25\0"+
-    "\1\117\21\0\1\120\35\0\1\121\124\0\1\122\24\0"+
-    "\1\123\22\0\2\124\12\0\1\124\1\125\1\126\1\106"+
-    "\1\107\1\110\1\111\1\112\3\0\1\107\12\0\1\112"+
-    "\1\0\1\106\2\0\1\111\4\0\1\126\27\0\1\127"+
-    "\13\0\1\127\4\0\1\130\106\0\1\131\34\0\1\132"+
-    "\3\0\1\133\15\0\10\23\1\0\15\23\1\134\1\135"+
-    "\54\23\31\0\1\136\53\0\3\11\1\0\2\11\6\0"+
-    "\5\11\1\0\2\11\3\0\1\11\2\0\1\11\1\137"+
-    "\2\11\2\0\1\140\5\11\1\141\12\11\23\0\3\11"+
-    "\1\0\2\11\6\0\5\11\1\0\2\11\3\0\1\11"+
-    "\2\0\3\11\1\142\2\0\5\11\1\143\1\11\1\144"+
-    "\11\11\23\0\3\11\1\0\2\11\6\0\5\11\1\0"+
-    "\2\11\3\0\1\145\2\0\4\11\2\0\21\11\104\0"+
-    "\1\146\22\0\3\11\1\0\2\11\6\0\5\11\1\0"+
-    "\2\11\3\0\1\11\2\0\4\11\2\0\3\11\1\147"+
-    "\15\11\23\0\3\11\1\0\2\11\6\0\5\11\1\0"+
-    "\2\11\3\0\1\11\2\0\4\11\2\0\4\11\1\150"+
-    "\14\11\23\0\3\11\1\0\2\11\6\0\5\11\1\0"+
-    "\2\11\3\0\1\11\2\0\3\11\1\151\2\0\21\11"+
-    "\23\0\3\11\1\0\2\11\6\0\5\11\1\0\2\11"+
-    "\3\0\1\152\2\0\4\11\2\0\21\11\23\0\3\11"+
-    "\1\0\2\11\6\0\5\11\1\0\2\11\3\0\1\11"+
-    "\2\0\4\11\2\0\2\11\1\153\16\11\23\0\3\11"+
-    "\1\0\2\11\6\0\5\11\1\0\2\11\3\0\1\154"+
-    "\2\0\4\11\2\0\3\11\1\155\5\11\1\156\7\11"+
-    "\23\0\3\11\1\0\2\11\6\0\5\11\1\0\2\11"+
-    "\3\0\1\11\2\0\4\11\2\0\4\11\1\157\4\11"+
-    "\1\160\7\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\4\11\2\0\14\11"+
-    "\1\161\4\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\4\11\2\0\6\11"+
-    "\1\162\12\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\1\11\1\163\2\11"+
-    "\2\0\21\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\4\11\2\0\3\11"+
-    "\1\164\15\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\4\11\2\0\11\11"+
-    "\1\165\7\11\104\0\1\166\3\0\1\167\77\0\1\170"+
-    "\1\0\1\171\101\0\1\172\103\0\1\173\110\0\1\174"+
-    "\104\0\1\175\75\0\1\176\113\0\1\177\110\0\1\200"+
-    "\4\0\10\67\2\0\15\67\1\0\1\67\1\0\52\67"+
-    "\2\0\2\201\1\0\1\201\1\0\1\202\6\0\4\201"+
-    "\1\0\2\201\3\0\1\201\1\0\1\203\4\201\2\0"+
-    "\21\201\22\0\10\204\1\0\17\204\1\205\53\204\31\0"+
-    "\1\206\53\0\3\76\1\0\2\76\6\0\5\76\1\0"+
-    "\2\76\3\0\1\76\2\0\4\76\2\0\21\76\22\0"+
-    "\7\207\2\0\73\207\1\0\3\76\1\0\2\76\6\0"+
-    "\5\76\1\0\2\76\3\0\1\76\2\0\1\76\1\210"+
-    "\2\76\2\0\21\76\62\0\1\211\55\0\1\212\113\0"+
-    "\1\213\101\0\1\106\1\0\1\213\22\0\1\106\37\0"+
-    "\1\127\13\0\1\127\4\0\1\214\62\0\2\215\12\0"+
-    "\1\215\5\0\1\111\1\0\1\215\22\0\1\111\13\0"+
-    "\1\215\17\0\7\113\1\216\1\0\73\113\1\0\3\114"+
-    "\1\0\2\114\6\0\5\114\1\0\2\114\3\0\1\114"+
-    "\2\0\4\114\2\0\21\114\22\0\7\217\2\0\73\217"+
-    "\10\116\1\0\73\116\40\0\1\220\43\0\10\121\1\0"+
-    "\73\121\36\0\1\221\7\0\1\222\117\0\1\223\22\0"+
-    "\2\124\12\0\1\124\4\0\1\224\1\111\1\112\16\0"+
-    "\1\112\4\0\1\111\34\0\3\125\11\0\1\125\1\0"+
-    "\1\125\1\106\1\107\1\213\2\125\3\0\1\107\12\0"+
-    "\2\125\1\106\2\0\2\125\3\0\1\125\3\0\1\125"+
-    "\23\0\2\126\12\0\1\126\2\0\1\106\1\107\1\213"+
-    "\5\0\1\107\14\0\1\106\37\0\2\127\12\0\1\127"+
-    "\5\0\1\111\1\112\16\0\1\112\4\0\1\111\55\0"+
-    "\1\225\42\0\1\226\16\0\10\23\1\0\73\23\31\0"+
-    "\1\227\53\0\3\11\1\0\2\11\6\0\5\11\1\0"+
-    "\2\11\3\0\1\11\2\0\2\11\1\230\1\11\2\0"+
-    "\6\11\1\231\12\11\23\0\3\11\1\0\2\11\6\0"+
-    "\5\11\1\0\2\11\3\0\1\11\2\0\4\11\2\0"+
-    "\1\11\1\232\17\11\23\0\3\11\1\0\2\11\6\0"+
-    "\5\11\1\0\2\11\3\0\1\233\2\0\4\11\2\0"+
-    "\1\234\20\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\1\235\3\11\2\0"+
-    "\21\11\23\0\3\11\1\0\2\11\6\0\5\11\1\0"+
-    "\2\11\3\0\1\11\2\0\4\11\2\0\1\11\1\236"+
-    "\17\11\23\0\3\11\1\0\2\11\6\0\5\11\1\0"+
-    "\2\11\3\0\1\11\2\0\4\11\2\0\10\11\1\237"+
-    "\10\11\23\0\3\11\1\0\2\11\6\0\5\11\1\0"+
-    "\2\11\3\0\1\11\2\0\3\11\1\240\2\0\21\11"+
-    "\23\0\3\11\1\0\2\11\6\0\5\11\1\0\2\11"+
-    "\3\0\1\11\2\0\4\11\2\0\21\11\1\0\1\241"+
-    "\21\0\3\11\1\0\2\11\6\0\5\11\1\0\2\11"+
-    "\3\0\1\11\2\0\4\11\2\0\4\11\1\242\14\11"+
-    "\23\0\3\11\1\0\2\11\6\0\5\11\1\0\2\11"+
-    "\3\0\1\11\2\0\1\243\3\11\2\0\21\11\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\11\2\0\4\11\2\0\5\11\1\244\13\11\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\11\2\0\4\11\2\0\4\11\1\245\14\11\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\11\2\0\4\11\2\0\6\11\1\246\12\11\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\11\2\0\4\11\2\0\3\11\1\247\15\11\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\11\2\0\4\11\2\0\5\11\1\250\13\11\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\11\2\0\4\11\2\0\15\11\1\251\3\11\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\11\2\0\4\11\2\0\2\11\1\252\16\11\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\11\2\0\2\11\1\253\1\11\2\0\2\11\1\254"+
-    "\16\11\23\0\3\11\1\0\2\11\6\0\5\11\1\0"+
-    "\2\11\3\0\1\11\2\0\4\11\2\0\4\11\1\255"+
-    "\1\11\1\256\12\11\104\0\1\257\22\0\3\201\1\0"+
-    "\2\201\6\0\5\201\1\0\2\201\3\0\1\201\2\0"+
-    "\4\201\2\0\21\201\22\0\7\260\2\0\73\260\1\0"+
-    "\1\261\1\0\1\261\11\0\1\261\1\0\1\261\3\0"+
-    "\2\261\16\0\2\261\3\0\2\261\3\0\1\261\3\0"+
-    "\1\261\53\0\1\262\52\0\7\207\1\263\1\0\73\207"+
-    "\1\0\3\76\1\0\2\76\6\0\5\76\1\0\2\76"+
-    "\3\0\1\76\2\0\2\76\1\264\1\76\2\0\21\76"+
-    "\44\0\1\214\62\0\2\215\12\0\1\215\5\0\1\111"+
-    "\24\0\1\111\33\0\7\217\1\265\1\0\73\217\12\0"+
-    "\1\266\72\0\3\267\1\0\2\267\6\0\5\267\1\0"+
-    "\2\267\3\0\1\267\2\0\4\267\2\0\21\267\23\0"+
-    "\1\127\13\0\1\127\67\0\3\11\1\0\2\11\6\0"+
-    "\5\11\1\0\2\11\3\0\1\11\2\0\3\11\1\270"+
-    "\2\0\21\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\4\11\2\0\11\11"+
-    "\1\271\7\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\4\11\2\0\2\11"+
-    "\1\272\16\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\4\11\2\0\2\11"+
-    "\1\273\16\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\4\11\2\0\2\11"+
-    "\1\274\16\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\4\11\2\0\2\11"+
-    "\1\275\16\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\4\11\2\0\12\11"+
-    "\1\276\6\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\4\11\2\0\2\11"+
-    "\1\277\16\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\11\2\0\4\11\2\0\4\11"+
-    "\1\300\14\11\23\0\3\11\1\0\2\11\6\0\5\11"+
-    "\1\0\2\11\3\0\1\301\2\0\4\11\2\0\21\11"+
-    "\23\0\3\11\1\0\2\11\6\0\5\11\1\0\2\11"+
-    "\3\0\1\11\2\0\3\11\1\302\2\0\21\11\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\11\2\0\3\11\1\303\2\0\21\11\23\0\3\11"+
-    "\1\0\2\11\6\0\5\11\1\0\2\11\3\0\1\11"+
-    "\2\0\1\304\3\11\2\0\21\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\4\11\2\0\2\11\1\305\16\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\4\11\2\0\3\11\1\306\15\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\4\11\2\0\4\11\1\307\14\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\4\11\2\0\5\11\1\310\13\11\22\0\7\260\1\311"+
-    "\1\0\73\260\1\0\1\312\1\0\1\312\11\0\1\312"+
-    "\1\0\1\312\3\0\2\312\16\0\2\312\3\0\2\312"+
-    "\3\0\1\312\3\0\1\312\23\0\3\76\1\0\2\76"+
-    "\6\0\5\76\1\0\2\76\3\0\1\76\2\0\3\76"+
-    "\1\313\2\0\21\76\23\0\3\11\1\0\2\11\6\0"+
-    "\5\11\1\0\2\11\3\0\1\11\2\0\4\11\2\0"+
-    "\16\11\1\314\2\11\23\0\3\11\1\0\2\11\6\0"+
-    "\5\11\1\0\2\11\3\0\1\11\2\0\4\11\2\0"+
-    "\3\11\1\315\5\11\1\316\7\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\4\11\2\0\6\11\1\317\12\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\4\11\2\0\6\11\1\320\12\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\4\11\2\0\3\11\1\321\15\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\4\11\2\0\6\11\1\322\12\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\4\11\2\0\2\11\1\323\16\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\3\11\1\324\2\0\21\11\23\0\3\11\1\0\2\11"+
-    "\6\0\5\11\1\0\2\11\3\0\1\11\2\0\2\11"+
-    "\1\325\1\11\2\0\21\11\23\0\3\11\1\0\2\11"+
-    "\6\0\5\11\1\0\2\11\3\0\1\11\2\0\4\11"+
-    "\2\0\10\11\1\326\10\11\23\0\3\11\1\0\2\11"+
-    "\6\0\5\11\1\0\2\11\3\0\1\11\2\0\4\11"+
-    "\2\0\12\11\1\327\6\11\23\0\3\11\1\0\2\11"+
-    "\6\0\5\11\1\0\2\11\3\0\1\11\2\0\4\11"+
-    "\2\0\2\11\1\330\16\11\23\0\1\331\1\0\1\331"+
-    "\11\0\1\331\1\0\1\331\3\0\2\331\16\0\2\331"+
-    "\3\0\2\331\3\0\1\331\3\0\1\331\23\0\3\11"+
-    "\1\0\2\11\6\0\5\11\1\0\2\11\3\0\1\11"+
-    "\2\0\4\11\2\0\4\11\1\332\14\11\23\0\3\11"+
-    "\1\0\2\11\6\0\5\11\1\0\2\11\3\0\1\11"+
-    "\2\0\4\11\2\0\7\11\1\333\11\11\23\0\3\11"+
-    "\1\0\2\11\6\0\5\11\1\0\2\11\3\0\1\11"+
-    "\2\0\4\11\2\0\7\11\1\334\11\11\23\0\3\11"+
-    "\1\0\2\11\6\0\5\11\1\0\2\11\3\0\1\11"+
-    "\2\0\4\11\2\0\13\11\1\335\5\11\23\0\3\11"+
-    "\1\0\2\11\6\0\5\11\1\0\2\11\3\0\1\11"+
-    "\2\0\4\11\2\0\5\11\1\336\13\11\23\0\3\11"+
-    "\1\0\2\11\6\0\5\11\1\0\2\11\3\0\1\11"+
-    "\2\0\4\11\2\0\5\11\1\337\13\11\23\0\3\11"+
-    "\1\0\2\11\6\0\5\11\1\0\2\11\3\0\1\11"+
-    "\2\0\1\340\3\11\2\0\21\11\23\0\1\204\1\0"+
-    "\1\204\11\0\1\204\1\0\1\204\3\0\2\204\16\0"+
-    "\2\204\3\0\2\204\3\0\1\204\3\0\1\204\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\11\2\0\2\11\1\341\1\11\2\0\21\11\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\11\2\0\4\11\2\0\3\11\1\342\15\11\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\11\2\0\4\11\2\0\2\11\1\343\16\11\23\0"+
-    "\3\11\1\0\2\11\6\0\5\11\1\0\2\11\3\0"+
-    "\1\344\2\0\4\11\2\0\21\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\4\11\2\0\3\11\1\345\15\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\4\11\2\0\10\11\1\346\10\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\4\11\2\0\2\11\1\347\16\11\23\0\3\11\1\0"+
-    "\2\11\6\0\5\11\1\0\2\11\3\0\1\11\2\0"+
-    "\3\11\1\350\2\0\21\11\23\0\3\11\1\0\2\11"+
-    "\6\0\5\11\1\0\2\11\3\0\1\11\2\0\4\11"+
-    "\2\0\2\11\1\351\16\11\22\0";
+    "\1\7\2\10\1\7\1\10\1\11\1\12\1\13\1\14"+
+    "\1\15\1\16\1\17\1\20\1\21\1\22\1\23\1\24"+
+    "\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34"+
+    "\1\35\1\36\1\37\1\40\10\41\1\42\1\7\1\43"+
+    "\1\41\1\44\1\45\1\46\1\47\1\50\1\51\1\52"+
+    "\2\41\1\53\3\41\1\54\1\55\1\56\1\57\1\60"+
+    "\1\61\1\41\1\62\1\63\1\41\1\64\1\65\1\66"+
+    "\1\7\2\67\1\70\3\67\1\71\1\67\1\72\35\67"+
+    "\1\73\37\67\1\74\3\67\1\75\1\67\1\72\35\67"+
+    "\1\74\35\67\2\7\3\0\30\7\10\76\3\7\1\76"+
+    "\1\77\21\76\1\100\4\76\4\7\16\101\1\102\4\101"+
+    "\1\103\60\101\1\7\2\10\1\7\1\10\1\11\1\12"+
+    "\1\13\1\14\1\15\1\16\1\17\1\20\1\21\1\22"+
+    "\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32"+
+    "\1\33\1\34\1\35\1\36\1\37\1\40\10\41\1\42"+
+    "\1\7\1\43\1\41\1\44\1\45\1\46\1\47\1\50"+
+    "\1\51\1\52\2\41\1\53\3\41\1\54\1\55\1\56"+
+    "\1\57\1\60\1\61\1\41\1\62\1\63\1\41\1\104"+
+    "\1\65\1\105\1\7\105\0\2\10\1\0\1\10\130\0"+
+    "\1\106\30\0\1\107\27\0\1\110\102\0\1\111\104\0"+
+    "\1\12\1\0\1\112\24\0\10\113\3\0\1\113\1\114"+
+    "\26\113\35\0\1\115\64\0\1\116\71\0\2\17\1\0"+
+    "\10\17\1\117\32\17\1\120\35\17\31\0\1\121\71\0"+
+    "\1\122\11\0\1\123\73\0\1\124\7\0\1\125\1\126"+
+    "\73\0\1\127\1\0\2\130\74\0\1\131\4\0\1\132"+
+    "\5\0\1\133\74\0\1\134\1\0\2\135\10\0\1\136"+
+    "\1\137\1\140\1\0\1\141\1\142\1\143\3\0\1\135"+
+    "\2\0\1\136\2\0\1\137\1\140\5\0\1\141\6\0"+
+    "\1\142\31\0\1\134\1\0\2\31\11\0\1\137\1\140"+
+    "\1\0\1\141\1\142\4\0\1\31\5\0\1\137\1\140"+
+    "\5\0\1\141\6\0\1\142\35\0\1\144\104\0\1\145"+
+    "\105\0\1\146\103\0\1\147\1\150\102\0\1\151\76\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\26\41\3\0"+
+    "\1\41\2\152\1\0\46\152\1\0\32\152\24\0\2\41"+
+    "\7\0\10\41\3\0\1\41\1\0\20\41\1\153\5\41"+
+    "\3\0\1\41\24\0\2\41\7\0\10\41\3\0\1\41"+
+    "\1\0\17\41\1\154\6\41\3\0\1\41\24\0\2\41"+
+    "\7\0\10\41\3\0\1\41\1\0\13\41\1\155\1\41"+
+    "\1\156\10\41\3\0\1\41\24\0\2\41\7\0\10\41"+
+    "\3\0\1\41\1\0\15\41\1\157\10\41\3\0\1\41"+
+    "\24\0\2\41\7\0\10\41\3\0\1\41\1\0\13\41"+
+    "\1\160\12\41\3\0\1\41\24\0\2\41\7\0\10\41"+
+    "\3\0\1\41\1\0\1\161\14\41\1\162\4\41\1\163"+
+    "\3\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\5\41\1\164\6\41\1\165\3\41\1\166"+
+    "\5\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\22\41\1\167\3\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\1\41\1\170"+
+    "\24\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\1\171\25\41\3\0\1\41\24\0\2\41"+
+    "\7\0\10\41\3\0\1\41\1\0\4\41\1\172\21\41"+
+    "\3\0\1\41\24\0\2\41\7\0\10\41\3\0\1\41"+
+    "\1\0\22\41\1\173\3\41\3\0\1\41\24\0\2\41"+
+    "\7\0\10\41\3\0\1\41\1\0\7\41\1\174\7\41"+
+    "\1\175\5\41\1\176\3\0\1\41\24\0\2\41\7\0"+
+    "\10\41\3\0\1\41\1\0\1\177\25\41\3\0\1\41"+
+    "\24\0\2\41\7\0\10\41\3\0\1\41\1\0\7\41"+
+    "\1\200\16\41\3\0\1\41\101\0\1\201\2\0\2\67"+
+    "\1\0\3\67\1\0\1\67\1\0\35\67\1\0\35\67"+
+    "\10\0\1\202\24\0\10\203\3\0\1\203\1\204\26\203"+
+    "\1\205\3\0\2\206\1\0\71\206\1\207\7\206\6\0"+
+    "\1\210\121\0\2\76\7\0\10\76\3\0\1\76\1\0"+
+    "\26\76\3\0\1\76\2\211\1\0\46\211\1\0\32\211"+
+    "\24\0\2\76\7\0\10\76\3\0\1\76\1\0\7\76"+
+    "\1\212\16\76\3\0\1\76\23\0\1\213\76\0\1\214"+
+    "\116\0\1\215\140\0\1\216\3\0\1\217\17\0\1\220"+
+    "\75\0\2\111\1\0\101\111\6\0\1\12\1\0\1\112"+
+    "\117\0\2\113\7\0\10\113\3\0\1\113\1\0\26\113"+
+    "\3\0\1\113\2\221\1\0\46\221\1\0\32\221\2\17"+
+    "\1\0\101\17\22\0\1\222\5\0\1\223\77\0\2\130"+
+    "\11\0\1\137\1\140\7\0\1\130\5\0\1\137\1\140"+
+    "\42\0\1\224\65\0\2\132\1\0\101\132\22\0\1\225"+
+    "\1\0\2\130\100\0\1\226\1\0\2\135\11\0\1\137"+
+    "\1\140\7\0\1\135\5\0\1\137\1\140\46\0\1\227"+
+    "\1\0\2\136\14\0\1\141\1\142\4\0\1\136\14\0"+
+    "\1\141\6\0\1\142\26\0\1\230\1\0\1\230\2\0"+
+    "\2\230\12\0\1\140\7\0\1\230\6\0\1\140\46\0"+
+    "\1\227\103\0\1\227\17\0\1\141\22\0\1\141\40\0"+
+    "\1\227\1\0\2\143\7\0\4\143\1\0\1\141\1\142"+
+    "\4\0\1\143\1\0\6\143\5\0\1\141\6\0\1\142"+
+    "\40\0\1\231\52\0\2\152\1\0\46\152\1\232\32\152"+
+    "\24\0\2\41\5\0\1\233\1\0\10\41\3\0\1\41"+
+    "\1\0\26\41\3\0\1\41\24\0\2\41\7\0\10\41"+
+    "\3\0\1\41\1\0\4\41\1\234\21\41\3\0\1\41"+
+    "\24\0\2\41\7\0\10\41\3\0\1\41\1\0\1\235"+
+    "\25\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\14\41\1\236\11\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\20\41\1\237"+
+    "\5\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\13\41\1\240\12\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\17\41\1\241"+
+    "\6\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\14\41\1\242\11\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\21\41\1\243"+
+    "\4\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\13\41\1\244\12\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\11\41\1\245"+
+    "\14\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\2\41\1\246\23\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\21\41\1\247"+
+    "\4\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\16\41\1\250\7\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\10\41\1\251"+
+    "\6\41\1\252\6\41\3\0\1\41\24\0\2\41\7\0"+
+    "\10\41\3\0\1\41\1\0\22\41\1\253\2\41\1\254"+
+    "\3\0\1\41\24\0\2\41\7\0\10\41\3\0\1\41"+
+    "\1\0\16\41\1\255\7\41\3\0\1\41\24\0\2\41"+
+    "\7\0\10\41\3\0\1\41\1\0\13\41\1\256\3\41"+
+    "\1\257\6\41\3\0\1\41\24\0\2\41\7\0\10\41"+
+    "\3\0\1\41\1\0\4\41\1\260\3\41\1\261\15\41"+
+    "\3\0\1\41\24\0\2\203\7\0\10\203\3\0\1\203"+
+    "\1\0\26\203\3\0\1\203\2\262\1\0\46\262\1\0"+
+    "\32\262\24\0\2\263\7\0\4\263\11\0\6\263\32\0"+
+    "\1\264\75\0\2\211\1\0\46\211\1\265\32\211\24\0"+
+    "\2\76\7\0\10\76\3\0\1\76\1\0\10\76\1\266"+
+    "\15\76\3\0\1\76\24\0\2\267\7\0\10\267\3\0"+
+    "\1\267\1\0\26\267\3\0\1\267\2\221\1\0\46\221"+
+    "\1\270\32\221\23\0\1\271\104\0\2\130\100\0\1\225"+
+    "\105\0\2\230\12\0\1\140\7\0\1\230\6\0\1\140"+
+    "\50\0\2\41\7\0\10\41\3\0\1\41\1\0\1\272"+
+    "\25\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\20\41\1\273\5\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\21\41\1\274"+
+    "\4\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\4\41\1\275\21\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\20\41\1\276"+
+    "\5\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\4\41\1\277\21\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\13\41\1\300"+
+    "\12\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\4\41\1\301\21\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\12\41\1\302"+
+    "\13\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\22\41\1\303\3\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\4\41\1\304"+
+    "\21\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\20\41\1\305\5\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\15\41\1\306"+
+    "\10\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\4\41\1\307\21\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\4\41\1\310"+
+    "\21\41\3\0\1\41\24\0\2\41\7\0\10\41\3\0"+
+    "\1\41\1\0\14\41\1\311\11\41\3\0\1\41\24\0"+
+    "\2\41\7\0\10\41\3\0\1\41\1\0\13\41\1\312"+
+    "\12\41\3\0\1\41\2\262\1\0\46\262\1\313\32\262"+
+    "\24\0\2\314\7\0\4\314\11\0\6\314\50\0\2\76"+
+    "\7\0\10\76\3\0\1\76\1\0\20\76\1\315\5\76"+
+    "\3\0\1\76\24\0\2\41\7\0\10\41\3\0\1\41"+
+    "\1\0\12\41\1\316\13\41\3\0\1\41\24\0\2\41"+
+    "\7\0\10\41\3\0\1\41\1\0\20\41\1\317\5\41"+
+    "\3\0\1\41\24\0\2\41\7\0\10\41\3\0\1\41"+
+    "\1\0\10\41\1\320\15\41\3\0\1\41\24\0\2\41"+
+    "\7\0\10\41\3\0\1\41\1\0\4\41\1\321\21\41"+
+    "\3\0\1\41\24\0\2\41\7\0\10\41\3\0\1\41"+
+    "\1\0\17\41\1\322\6\41\3\0\1\41\24\0\2\41"+
+    "\7\0\10\41\3\0\1\41\1\0\2\41\1\323\23\41"+
+    "\3\0\1\41\24\0\2\41\7\0\10\41\3\0\1\41"+
+    "\1\0\1\324\25\41\3\0\1\41\24\0\2\41\7\0"+
+    "\10\41\3\0\1\41\1\0\17\41\1\325\6\41\3\0"+
+    "\1\41\24\0\2\41\7\0\10\41\3\0\1\41\1\0"+
+    "\17\41\1\326\6\41\3\0\1\41\24\0\2\41\7\0"+
+    "\10\41\3\0\1\41\1\0\24\41\1\327\1\41\3\0"+
+    "\1\41\24\0\2\41\7\0\10\41\3\0\1\41\1\0"+
+    "\1\330\14\41\1\331\10\41\3\0\1\41\24\0\2\41"+
+    "\7\0\10\41\3\0\1\41\1\0\4\41\1\332\21\41"+
+    "\3\0\1\41\24\0\2\333\7\0\4\333\11\0\6\333"+
+    "\50\0\2\41\7\0\10\41\3\0\1\41\1\0\14\41"+
+    "\1\334\11\41\3\0\1\41\24\0\2\41\7\0\10\41"+
+    "\3\0\1\41\1\0\5\41\1\335\20\41\3\0\1\41"+
+    "\24\0\2\41\7\0\10\41\3\0\1\41\1\0\21\41"+
+    "\1\336\4\41\3\0\1\41\24\0\2\41\7\0\10\41"+
+    "\3\0\1\41\1\0\6\41\1\337\17\41\3\0\1\41"+
+    "\24\0\2\41\7\0\10\41\3\0\1\41\1\0\14\41"+
+    "\1\340\11\41\3\0\1\41\24\0\2\41\7\0\10\41"+
+    "\3\0\1\41\1\0\13\41\1\341\12\41\3\0\1\41"+
+    "\24\0\2\41\7\0\10\41\3\0\1\41\1\0\5\41"+
+    "\1\342\20\41\3\0\1\41\24\0\2\206\7\0\4\206"+
+    "\11\0\6\206\50\0\2\41\7\0\10\41\3\0\1\41"+
+    "\1\0\22\41\1\343\3\41\3\0\1\41\24\0\2\41"+
+    "\7\0\10\41\3\0\1\41\1\0\1\344\25\41\3\0"+
+    "\1\41\24\0\2\41\7\0\10\41\3\0\1\41\1\0"+
+    "\4\41\1\345\21\41\3\0\1\41\24\0\2\41\7\0"+
+    "\10\41\3\0\1\41\1\0\10\41\1\346\15\41\3\0"+
+    "\1\41\24\0\2\41\7\0\10\41\3\0\1\41\1\0"+
+    "\4\41\1\347\21\41\3\0\1\41\24\0\2\41\7\0"+
+    "\10\41\3\0\1\41\1\0\2\41\1\350\23\41\3\0"+
+    "\1\41\24\0\2\41\7\0\10\41\3\0\1\41\1\0"+
+    "\1\351\25\41\3\0\1\41\24\0\2\41\7\0\10\41"+
+    "\3\0\1\41\1\0\4\41\1\352\21\41\3\0\1\41"+
+    "\24\0\2\41\7\0\10\41\3\0\1\41\1\0\20\41"+
+    "\1\353\5\41\3\0\1\41";
 
-  private static int [] zzUnpackTrans() {
-    int [] result = new int[10540];
+  private static int [] zzUnpacktrans() {
+    int [] result = new int[10608];
     int offset = 0;
-    offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
+    offset = zzUnpacktrans(ZZ_TRANS_PACKED_0, offset, result);
     return result;
   }
 
-  private static int zzUnpackTrans(String packed, int offset, int [] result) {
+  private static int zzUnpacktrans(String packed, int offset, int [] result) {
     int i = 0;       /* index in packed string  */
     int j = offset;  /* index in unpacked array */
     int l = packed.length();
@@ -554,23 +622,23 @@
   };
 
   /**
-   * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
+   * ZZ_ATTRIBUTE[aState] contains the attributes of state {@code aState}
    */
   private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
 
   private static final String ZZ_ATTRIBUTE_PACKED_0 =
-    "\6\0\1\11\15\1\1\11\3\1\1\11\16\1\1\11"+
-    "\7\1\4\11\1\1\2\11\1\1\1\11\2\1\2\11"+
-    "\4\1\1\11\2\1\2\11\2\1\1\0\1\11\1\1"+
-    "\1\0\1\1\1\0\2\1\1\11\1\1\1\0\1\1"+
-    "\1\0\4\1\4\11\1\1\1\0\7\1\1\11\20\1"+
-    "\12\11\1\1\1\0\2\11\1\1\2\0\1\1\2\11"+
-    "\1\0\1\11\1\1\1\11\1\0\3\1\1\11\1\0"+
-    "\3\11\11\1\1\11\15\1\1\11\2\0\1\1\1\11"+
-    "\1\1\3\11\21\1\1\11\1\0\16\1\1\0\20\1";
+    "\6\0\1\11\10\1\2\11\2\1\1\11\12\1\2\11"+
+    "\1\1\2\11\20\1\1\11\1\1\1\11\1\1\2\11"+
+    "\2\1\1\11\4\1\1\11\2\1\2\11\1\1\2\0"+
+    "\1\1\1\0\1\1\1\0\3\11\1\1\6\11\4\1"+
+    "\1\11\2\0\2\1\1\11\3\1\3\11\1\1\2\11"+
+    "\1\0\26\1\1\11\1\0\1\1\1\0\2\11\1\1"+
+    "\2\0\1\1\3\11\3\1\1\0\2\11\1\1\1\11"+
+    "\2\0\1\1\3\11\26\1\2\0\1\1\1\11\1\1"+
+    "\3\11\21\1\1\11\1\0\16\1\1\0\20\1";
 
   private static int [] zzUnpackAttribute() {
-    int [] result = new int[233];
+    int [] result = new int[235];
     int offset = 0;
     offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
     return result;
@@ -614,15 +682,26 @@
       from input */
   private int zzEndRead;
 
-  /**
-   * zzAtBOL == true <=> the scanner is currently at the beginning of a line
-   */
-  private boolean zzAtBOL = true;
-
   /** zzAtEOF == true <=> the scanner is at the EOF */
   private boolean zzAtEOF;
 
-  /** denotes if the user-EOF-code has already been executed */
+  /** Number of newlines encountered up to the start of the matched text. */
+  @SuppressWarnings("unused")
+  private int yyline;
+
+  /** Number of characters from the last newline up to the start of the matched text. */
+  @SuppressWarnings("unused")
+  protected int yycolumn;
+
+  /** Number of characters up to the start of the matched text. */
+  @SuppressWarnings("unused")
+  private long yychar;
+
+  /** Whether the scanner is currently at the beginning of a line. */
+  @SuppressWarnings("unused")
+  private boolean zzAtBOL = true;
+
+  /** Whether the user-EOF-code has already been executed. */
   private boolean zzEOFDone;
 
   /* user code: */
@@ -630,14 +709,26 @@
         final int lBraceCount;
         final int state;
 
-        public State(int state, int lBraceCount) {
+        final int dollarCount;
+        final int quotesCount;
+
+        public State(int state, int lBraceCount, int dollarCount, int quotesCount) {
             this.state = state;
             this.lBraceCount = lBraceCount;
+            this.dollarCount = dollarCount;
+            this.quotesCount = quotesCount;
+        }
+
+        public State(int state, int lBraceCount) {
+            this(state, lBraceCount, 0, 0);
         }
 
         @Override
         public String toString() {
-            return "yystate = " + state + (lBraceCount == 0 ? "" : "lBraceCount = " + lBraceCount);
+            return "yystate = " + state
+              + (lBraceCount == 0 ? "" : "lBraceCount = " + lBraceCount)
+              + (dollarCount == 0 ? "" : "dollarCount = " + dollarCount)
+              + (quotesCount == 0 ? "" : "quotesCount = " + quotesCount);
         }
     }
 
@@ -648,11 +739,26 @@
     private int commentDepth;
 
     private void pushState(int state) {
-        states.push(new State(yystate(), lBraceCount));
+        states.push(new State(yystate(), lBraceCount, 0, 0));
         lBraceCount = 0;
         yybegin(state);
     }
 
+    private void pushState(int state, int dollarCount, int quotesCount) {
+        states.push(new State(yystate(), lBraceCount, dollarCount, quotesCount));
+        lBraceCount = 0;
+        yybegin(state);
+    }
+
+    private int peekQuotes() {
+        return states.peek().quotesCount;
+    }
+
+    private int peekDollars() {
+        // we should always have at least one dollar
+        return Math.max(1, states.peek().dollarCount);
+    }
+
     private void popState() {
         State state = states.pop();
         lBraceCount = state.lBraceCount;
@@ -681,26 +787,22 @@
   }
 
 
-  /** 
-   * Unpacks the compressed character translation table.
-   *
-   * @param packed   the packed character translation table
-   * @return         the unpacked character translation table
+  /** Returns the maximum size of the scanner buffer, which limits the size of tokens. */
+  private int zzMaxBufferLen() {
+    return Integer.MAX_VALUE;
+  }
+
+  /**  Whether the scanner buffer can grow to accommodate a larger token. */
+  private boolean zzCanGrow() {
+    return true;
+  }
+
+  /**
+   * Translates raw input code points to DFA table row
    */
-  private static char [] zzUnpackCMap(String packed) {
-    int size = 0;
-    for (int i = 0, length = packed.length(); i < length; i += 2) {
-      size += packed.charAt(i);
-    }
-    char[] map = new char[size];
-    int i = 0;  /* index in packed string  */
-    int j = 0;  /* index in unpacked array */
-    while (i < packed.length()) {
-      int  count = packed.charAt(i++);
-      char value = packed.charAt(i++);
-      do map[j++] = value; while (--count > 0);
-    }
-    return map;
+  private static int zzCMap(int input) {
+    int offset = input & 255;
+    return offset == input ? ZZ_CMAP_BLOCKS[offset] : ZZ_CMAP_BLOCKS[ZZ_CMAP_TOP[input >> 8] | offset];
   }
 
   public final int getTokenStart() {
@@ -832,8 +934,8 @@
   private void zzDoEOF() {
     if (!zzEOFDone) {
       zzEOFDone = true;
-      return;
-
+    
+  return;
     }
   }
 
@@ -845,7 +947,9 @@
    * @return      the next token
    * @exception   java.io.IOException  if any I/O-Error occurs
    */
-  public IElementType advance() throws java.io.IOException, KotlinLexerException {
+  public IElementType advance() throws java.io.IOException,
+     KotlinLexerException
+  {
     int zzInput;
     int zzAction;
 
@@ -879,7 +983,7 @@
         while (true) {
 
           if (zzCurrentPosL < zzEndReadL) {
-            zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL/*, zzEndReadL*/);
+            zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL);
             zzCurrentPosL += Character.charCount(zzInput);
           }
           else if (zzAtEOF) {
@@ -901,11 +1005,11 @@
               break zzForAction;
             }
             else {
-              zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL/*, zzEndReadL*/);
+              zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL);
               zzCurrentPosL += Character.charCount(zzInput);
             }
           }
-          int zzNext = zzTransL[ zzRowMapL[zzState] + ZZ_CMAP(zzInput) ];
+          int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMap(zzInput) ];
           if (zzNext == -1) break zzForAction;
           zzState = zzNext;
 
@@ -924,246 +1028,225 @@
 
       if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
         zzAtEOF = true;
-        zzDoEOF();
-        switch (zzLexicalState) {
+            zzDoEOF();
+            switch (zzLexicalState) {
             case BLOCK_COMMENT: {
               int state = yystate();
         popState();
         zzStartRead = commentStart;
         return commentStateToTokenType(state);
             }  // fall though
-            case 234: break;
+            case 236: break;
             case DOC_COMMENT: {
               int state = yystate();
         popState();
         zzStartRead = commentStart;
         return commentStateToTokenType(state);
             }  // fall though
-            case 235: break;
+            case 237: break;
             default:
         return null;
         }
       }
       else {
         switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
-          case 1: 
+          case 1:
             { return TokenType.BAD_CHARACTER;
-            } 
-            // fall through
+            }
+          // fall through
           case 108: break;
-          case 2: 
-            { return KtTokens.INTEGER_LITERAL;
-            } 
-            // fall through
-          case 109: break;
-          case 3: 
-            { return KtTokens.IDENTIFIER;
-            } 
-            // fall through
-          case 110: break;
-          case 4: 
+          case 2:
             { return KtTokens.WHITE_SPACE;
-            } 
-            // fall through
-          case 111: break;
-          case 5: 
-            { pushState(UNMATCHED_BACKTICK); return TokenType.BAD_CHARACTER;
-            } 
-            // fall through
-          case 112: break;
-          case 6: 
-            { return KtTokens.DIV       ;
-            } 
-            // fall through
-          case 113: break;
-          case 7: 
-            { return KtTokens.HASH      ;
-            } 
-            // fall through
-          case 114: break;
-          case 8: 
+            }
+          // fall through
+          case 109: break;
+          case 3:
             { return KtTokens.EXCL      ;
-            } 
-            // fall through
-          case 115: break;
-          case 9: 
-            { return KtTokens.DOT       ;
-            } 
-            // fall through
-          case 116: break;
-          case 10: 
-            { return KtTokens.MINUS     ;
-            } 
-            // fall through
-          case 117: break;
-          case 11: 
-            { return KtTokens.CHARACTER_LITERAL;
-            } 
-            // fall through
-          case 118: break;
-          case 12: 
-            { pushState(STRING); return KtTokens.OPEN_QUOTE;
-            } 
-            // fall through
-          case 119: break;
-          case 13: 
-            { return KtTokens.LBRACE    ;
-            } 
-            // fall through
-          case 120: break;
-          case 14: 
-            { return KtTokens.RBRACE    ;
-            } 
-            // fall through
-          case 121: break;
-          case 15: 
-            { return KtTokens.MUL       ;
-            } 
-            // fall through
-          case 122: break;
-          case 16: 
-            { return KtTokens.EQ        ;
-            } 
-            // fall through
-          case 123: break;
-          case 17: 
-            { return KtTokens.QUEST     ;
-            } 
-            // fall through
-          case 124: break;
-          case 18: 
-            { return KtTokens.PLUS      ;
-            } 
-            // fall through
-          case 125: break;
-          case 19: 
-            { return KtTokens.LT        ;
-            } 
-            // fall through
-          case 126: break;
-          case 20: 
-            { return KtTokens.GT        ;
-            } 
-            // fall through
-          case 127: break;
-          case 21: 
-            { return KtTokens.AND       ;
-            } 
-            // fall through
-          case 128: break;
-          case 22: 
+            }
+          // fall through
+          case 110: break;
+          case 4:
+            { pushState(STRING, yytext().length() - 1, 1);
+                              return KtTokens.OPEN_QUOTE;
+            }
+          // fall through
+          case 111: break;
+          case 5:
+            { return KtTokens.HASH      ;
+            }
+          // fall through
+          case 112: break;
+          case 6:
             { return KtTokens.PERC      ;
-            } 
-            // fall through
-          case 129: break;
-          case 23: 
-            { return KtTokens.COLON     ;
-            } 
-            // fall through
-          case 130: break;
-          case 24: 
-            { return KtTokens.LBRACKET  ;
-            } 
-            // fall through
-          case 131: break;
-          case 25: 
-            { return KtTokens.RBRACKET  ;
-            } 
-            // fall through
-          case 132: break;
-          case 26: 
+            }
+          // fall through
+          case 113: break;
+          case 7:
+            { return KtTokens.AND       ;
+            }
+          // fall through
+          case 114: break;
+          case 8:
+            { return KtTokens.CHARACTER_LITERAL;
+            }
+          // fall through
+          case 115: break;
+          case 9:
             { return KtTokens.LPAR      ;
-            } 
-            // fall through
-          case 133: break;
-          case 27: 
+            }
+          // fall through
+          case 116: break;
+          case 10:
             { return KtTokens.RPAR      ;
-            } 
-            // fall through
-          case 134: break;
-          case 28: 
-            { return KtTokens.SEMICOLON ;
-            } 
-            // fall through
-          case 135: break;
-          case 29: 
+            }
+          // fall through
+          case 117: break;
+          case 11:
+            { return KtTokens.MUL       ;
+            }
+          // fall through
+          case 118: break;
+          case 12:
+            { return KtTokens.PLUS      ;
+            }
+          // fall through
+          case 119: break;
+          case 13:
             { return KtTokens.COMMA     ;
-            } 
-            // fall through
-          case 136: break;
-          case 30: 
+            }
+          // fall through
+          case 120: break;
+          case 14:
+            { return KtTokens.MINUS     ;
+            }
+          // fall through
+          case 121: break;
+          case 15:
+            { return KtTokens.DOT       ;
+            }
+          // fall through
+          case 122: break;
+          case 16:
+            { return KtTokens.DIV       ;
+            }
+          // fall through
+          case 123: break;
+          case 17:
+            { return KtTokens.INTEGER_LITERAL;
+            }
+          // fall through
+          case 124: break;
+          case 18:
+            { return KtTokens.COLON     ;
+            }
+          // fall through
+          case 125: break;
+          case 19:
+            { return KtTokens.SEMICOLON ;
+            }
+          // fall through
+          case 126: break;
+          case 20:
+            { return KtTokens.LT        ;
+            }
+          // fall through
+          case 127: break;
+          case 21:
+            { return KtTokens.EQ        ;
+            }
+          // fall through
+          case 128: break;
+          case 22:
+            { return KtTokens.GT        ;
+            }
+          // fall through
+          case 129: break;
+          case 23:
+            { return KtTokens.QUEST     ;
+            }
+          // fall through
+          case 130: break;
+          case 24:
             { return KtTokens.AT        ;
-            } 
-            // fall through
+            }
+          // fall through
+          case 131: break;
+          case 25:
+            { return KtTokens.IDENTIFIER;
+            }
+          // fall through
+          case 132: break;
+          case 26:
+            { return KtTokens.LBRACKET  ;
+            }
+          // fall through
+          case 133: break;
+          case 27:
+            { return KtTokens.RBRACKET  ;
+            }
+          // fall through
+          case 134: break;
+          case 28:
+            { pushState(UNMATCHED_BACKTICK); return TokenType.BAD_CHARACTER;
+            }
+          // fall through
+          case 135: break;
+          case 29:
+            { return KtTokens.LBRACE    ;
+            }
+          // fall through
+          case 136: break;
+          case 30:
+            { return KtTokens.RBRACE    ;
+            }
+          // fall through
           case 137: break;
-          case 31: 
+          case 31:
             { return KtTokens.REGULAR_STRING_PART;
-            } 
-            // fall through
+            }
+          // fall through
           case 138: break;
-          case 32: 
+          case 32:
             { popState(); yypushback(1); return KtTokens.DANGLING_NEWLINE;
-            } 
-            // fall through
+            }
+          // fall through
           case 139: break;
-          case 33: 
+          case 33:
             { popState(); return KtTokens.CLOSING_QUOTE;
-            } 
-            // fall through
+            }
+          // fall through
           case 140: break;
-          case 34: 
+          case 34:
             { popState(); return KtTokens.IDENTIFIER;
-            } 
-            // fall through
+            }
+          // fall through
           case 141: break;
-          case 35: 
+          case 35:
             { 
-            } 
-            // fall through
+            }
+          // fall through
           case 142: break;
-          case 36: 
+          case 36:
             { lBraceCount++; return KtTokens.LBRACE;
-            } 
-            // fall through
+            }
+          // fall through
           case 143: break;
-          case 37: 
+          case 37:
             { if (lBraceCount == 0) {
                                              popState();
                                              return KtTokens.LONG_TEMPLATE_ENTRY_END;
                                            }
                                            lBraceCount--;
                                            return KtTokens.RBRACE;
-            } 
-            // fall through
+            }
+          // fall through
           case 144: break;
-          case 38: 
-            { return KtTokens.FLOAT_LITERAL;
-            } 
-            // fall through
+          case 38:
+            { return KtTokens.EXCLEQ    ;
+            }
+          // fall through
           case 145: break;
-          case 39: 
-            { return KtTokens.FIELD_IDENTIFIER;
-            } 
-            // fall through
-          case 146: break;
-          case 40: 
-            { return KtTokens.EOL_COMMENT;
-            } 
-            // fall through
-          case 147: break;
-          case 41: 
-            { pushState(BLOCK_COMMENT);
-    commentDepth = 0;
-    commentStart = getTokenStart();
-            } 
-            // fall through
-          case 148: break;
-          case 42: 
-            { return KtTokens.DIVEQ     ;
-            } 
-            // fall through
-          case 149: break;
-          case 43: 
+          case 39:
             { if (zzCurrentPos == 0) {
                 return KtTokens.SHEBANG_COMMENT;
             }
@@ -1171,142 +1254,186 @@
                 yypushback(yylength() - 1);
                 return KtTokens.HASH;
             }
-            } 
-            // fall through
-          case 150: break;
-          case 44: 
-            { return KtTokens.EXCLEQ    ;
-            } 
-            // fall through
-          case 151: break;
-          case 45: 
-            { return KtTokens.RANGE     ;
-            } 
-            // fall through
-          case 152: break;
-          case 46: 
-            { return KtTokens.MINUSMINUS;
-            } 
-            // fall through
-          case 153: break;
-          case 47: 
-            { return KtTokens.MINUSEQ   ;
-            } 
-            // fall through
-          case 154: break;
-          case 48: 
-            { return KtTokens.ARROW     ;
-            } 
-            // fall through
-          case 155: break;
-          case 49: 
-            { return KtTokens.IS_KEYWORD ;
-            } 
-            // fall through
-          case 156: break;
-          case 50: 
-            { return KtTokens.IN_KEYWORD ;
-            } 
-            // fall through
-          case 157: break;
-          case 51: 
-            { return KtTokens.IF_KEYWORD ;
-            } 
-            // fall through
-          case 158: break;
-          case 52: 
-            { return KtTokens.MULTEQ    ;
-            } 
-            // fall through
-          case 159: break;
-          case 53: 
-            { return KtTokens.AS_KEYWORD ;
-            } 
-            // fall through
-          case 160: break;
-          case 54: 
-            { return KtTokens.DO_KEYWORD ;
-            } 
-            // fall through
-          case 161: break;
-          case 55: 
-            { return KtTokens.EQEQ      ;
-            } 
-            // fall through
-          case 162: break;
-          case 56: 
-            { return KtTokens.DOUBLE_ARROW;
-            } 
-            // fall through
-          case 163: break;
-          case 57: 
-            { return KtTokens.PLUSEQ    ;
-            } 
-            // fall through
-          case 164: break;
-          case 58: 
-            { return KtTokens.PLUSPLUS  ;
-            } 
-            // fall through
-          case 165: break;
-          case 59: 
-            { return KtTokens.LTEQ      ;
-            } 
-            // fall through
-          case 166: break;
-          case 60: 
-            { return KtTokens.GTEQ      ;
-            } 
-            // fall through
-          case 167: break;
-          case 61: 
-            { return KtTokens.ANDAND    ;
-            } 
-            // fall through
-          case 168: break;
-          case 62: 
-            { return KtTokens.OROR      ;
-            } 
-            // fall through
-          case 169: break;
-          case 63: 
+            }
+          // fall through
+          case 146: break;
+          case 40:
+            { return KtTokens.FIELD_IDENTIFIER;
+            }
+          // fall through
+          case 147: break;
+          case 41:
             { return KtTokens.PERCEQ    ;
-            } 
-            // fall through
-          case 170: break;
-          case 64: 
+            }
+          // fall through
+          case 148: break;
+          case 42:
+            { return KtTokens.ANDAND    ;
+            }
+          // fall through
+          case 149: break;
+          case 43:
+            { return KtTokens.MULTEQ    ;
+            }
+          // fall through
+          case 150: break;
+          case 44:
+            { return KtTokens.PLUSPLUS  ;
+            }
+          // fall through
+          case 151: break;
+          case 45:
+            { return KtTokens.PLUSEQ    ;
+            }
+          // fall through
+          case 152: break;
+          case 46:
+            { return KtTokens.MINUSMINUS;
+            }
+          // fall through
+          case 153: break;
+          case 47:
+            { return KtTokens.MINUSEQ   ;
+            }
+          // fall through
+          case 154: break;
+          case 48:
+            { return KtTokens.ARROW     ;
+            }
+          // fall through
+          case 155: break;
+          case 49:
+            { return KtTokens.RANGE     ;
+            }
+          // fall through
+          case 156: break;
+          case 50:
+            { return KtTokens.FLOAT_LITERAL;
+            }
+          // fall through
+          case 157: break;
+          case 51:
+            { pushState(BLOCK_COMMENT);
+    commentDepth = 0;
+    commentStart = getTokenStart();
+            }
+          // fall through
+          case 158: break;
+          case 52:
+            { return KtTokens.EOL_COMMENT;
+            }
+          // fall through
+          case 159: break;
+          case 53:
+            { return KtTokens.DIVEQ     ;
+            }
+          // fall through
+          case 160: break;
+          case 54:
             { return KtTokens.COLONCOLON;
-            } 
-            // fall through
-          case 171: break;
-          case 65: 
+            }
+          // fall through
+          case 161: break;
+          case 55:
             { return KtTokens.DOUBLE_SEMICOLON;
-            } 
-            // fall through
+            }
+          // fall through
+          case 162: break;
+          case 56:
+            { return KtTokens.LTEQ      ;
+            }
+          // fall through
+          case 163: break;
+          case 57:
+            { return KtTokens.EQEQ      ;
+            }
+          // fall through
+          case 164: break;
+          case 58:
+            { return KtTokens.DOUBLE_ARROW;
+            }
+          // fall through
+          case 165: break;
+          case 59:
+            { return KtTokens.GTEQ      ;
+            }
+          // fall through
+          case 166: break;
+          case 60:
+            { return KtTokens.AS_KEYWORD ;
+            }
+          // fall through
+          case 167: break;
+          case 61:
+            { return KtTokens.DO_KEYWORD ;
+            }
+          // fall through
+          case 168: break;
+          case 62:
+            { return KtTokens.IF_KEYWORD ;
+            }
+          // fall through
+          case 169: break;
+          case 63:
+            { return KtTokens.IN_KEYWORD ;
+            }
+          // fall through
+          case 170: break;
+          case 64:
+            { return KtTokens.IS_KEYWORD ;
+            }
+          // fall through
+          case 171: break;
+          case 65:
+            { return KtTokens.OROR      ;
+            }
+          // fall through
           case 172: break;
-          case 66: 
-            { pushState(SHORT_TEMPLATE_ENTRY);
-                                                        yypushback(yylength() - 1);
-                                                        return KtTokens.SHORT_TEMPLATE_ENTRY_START;
-            } 
-            // fall through
+          case 66:
+            { int dollarCount = yytext().toString().lastIndexOf('$') + 1;
+                                                     int escape = peekDollars();
+                                                     if (dollarCount < escape) {
+                                                       // not enough dollars
+                                                       return KtTokens.REGULAR_STRING_PART;
+                                                     }
+                                                     else if (dollarCount == escape) {
+                                                       pushState(SHORT_TEMPLATE_ENTRY);
+                                                       yypushback(yylength() - dollarCount);
+                                                       return KtTokens.SHORT_TEMPLATE_ENTRY_START;
+                                                     }
+                                                     else {
+                                                       // too many dollars
+                                                       yypushback(yylength() - dollarCount + escape);
+                                                       return KtTokens.REGULAR_STRING_PART;
+                                                     }
+            }
+          // fall through
           case 173: break;
-          case 67: 
-            { pushState(LONG_TEMPLATE_ENTRY); return KtTokens.LONG_TEMPLATE_ENTRY_START;
-            } 
-            // fall through
+          case 67:
+            { int dollarCount = yytext().toString().lastIndexOf('$') + 1;
+                                                      int escape = peekDollars();
+                                                      if (dollarCount < escape) {
+                                                        // not enough dollars
+                                                        return KtTokens.REGULAR_STRING_PART;
+                                                      }
+                                                      else if (dollarCount == escape) {
+                                                        pushState(LONG_TEMPLATE_ENTRY);
+                                                        return KtTokens.LONG_TEMPLATE_ENTRY_START;
+                                                      }
+                                                      else {
+                                                        // too many dollars
+                                                        yypushback(yylength() - dollarCount + escape);
+                                                        return KtTokens.REGULAR_STRING_PART;
+                                                      }
+            }
+          // fall through
           case 174: break;
-          case 68: 
+          case 68:
             { return KtTokens.ESCAPE_SEQUENCE;
-            } 
-            // fall through
+            }
+          // fall through
           case 175: break;
-          case 69: 
-            { commentDepth++;
-            } 
-            // fall through
-          case 176: break;
-          case 70: 
+          case 69:
             { if (commentDepth > 0) {
             commentDepth--;
         }
@@ -1316,203 +1443,217 @@
              zzStartRead = commentStart;
              return commentStateToTokenType(state);
         }
-            } 
-            // fall through
+            }
+          // fall through
+          case 176: break;
+          case 70:
+            { commentDepth++;
+            }
+          // fall through
           case 177: break;
-          case 71: 
-            { yypushback(2); return KtTokens.INTEGER_LITERAL;
-            } 
-            // fall through
+          case 71:
+            { return KtTokens.EXCLEQEQEQ;
+            }
+          // fall through
           case 178: break;
-          case 72: 
+          case 72:
+            { return KtTokens.NOT_IN;
+            }
+          // fall through
+          case 179: break;
+          case 73:
+            { return KtTokens.NOT_IS;
+            }
+          // fall through
+          case 180: break;
+          case 74:
+            { String matched = yytext().toString();
+                              int dollarCount = matched.lastIndexOf('$') + 1;
+                              int quotesCount = matched.length() - dollarCount;
+                              pushState(RAW_STRING, dollarCount, quotesCount);
+                              return KtTokens.OPEN_QUOTE;
+            }
+          // fall through
+          case 181: break;
+          case 75:
+            { return KtTokens.RESERVED  ;
+            }
+          // fall through
+          case 182: break;
+          case 76:
+            { return KtTokens.RANGE_UNTIL;
+            }
+          // fall through
+          case 183: break;
+          case 77:
             { pushState(DOC_COMMENT);
     commentDepth = 0;
     commentStart = getTokenStart();
-            } 
-            // fall through
-          case 179: break;
-          case 73: 
-            { return KtTokens.NOT_IS;
-            } 
-            // fall through
-          case 180: break;
-          case 74: 
-            { return KtTokens.NOT_IN;
-            } 
-            // fall through
-          case 181: break;
-          case 75: 
-            { return KtTokens.EXCLEQEQEQ;
-            } 
-            // fall through
-          case 182: break;
-          case 76: 
-            { return KtTokens.RESERVED  ;
-            } 
-            // fall through
-          case 183: break;
-          case 77: 
-            { return KtTokens.RANGE_UNTIL;
-            } 
-            // fall through
+            }
+          // fall through
           case 184: break;
-          case 78: 
-            { pushState(RAW_STRING); return KtTokens.OPEN_QUOTE;
-            } 
-            // fall through
+          case 78:
+            { yypushback(2); return KtTokens.INTEGER_LITERAL;
+            }
+          // fall through
           case 185: break;
-          case 79: 
-            { return KtTokens.TRY_KEYWORD ;
-            } 
-            // fall through
-          case 186: break;
-          case 80: 
-            { return KtTokens.AS_SAFE;
-            } 
-            // fall through
-          case 187: break;
-          case 81: 
-            { return KtTokens.FUN_KEYWORD ;
-            } 
-            // fall through
-          case 188: break;
-          case 82: 
-            { return KtTokens.FOR_KEYWORD ;
-            } 
-            // fall through
-          case 189: break;
-          case 83: 
-            { return KtTokens.VAL_KEYWORD ;
-            } 
-            // fall through
-          case 190: break;
-          case 84: 
-            { return KtTokens.VAR_KEYWORD ;
-            } 
-            // fall through
-          case 191: break;
-          case 85: 
+          case 79:
             { return KtTokens.EQEQEQ    ;
-            } 
-            // fall through
+            }
+          // fall through
+          case 186: break;
+          case 80:
+            { return KtTokens.AS_SAFE;
+            }
+          // fall through
+          case 187: break;
+          case 81:
+            { return KtTokens.FOR_KEYWORD ;
+            }
+          // fall through
+          case 188: break;
+          case 82:
+            { return KtTokens.FUN_KEYWORD ;
+            }
+          // fall through
+          case 189: break;
+          case 83:
+            { return KtTokens.TRY_KEYWORD ;
+            }
+          // fall through
+          case 190: break;
+          case 84:
+            { return KtTokens.VAL_KEYWORD ;
+            }
+          // fall through
+          case 191: break;
+          case 85:
+            { return KtTokens.VAR_KEYWORD ;
+            }
+          // fall through
           case 192: break;
-          case 86: 
+          case 86:
             { int length = yytext().length();
-                                    if (length <= 3) { // closing """
-                                        popState();
-                                        return KtTokens.CLOSING_QUOTE;
-                                    }
-                                    else { // some quotes at the end of a string, e.g. """ "foo""""
-                                        yypushback(3); // return the closing quotes (""") to the stream
-                                        return KtTokens.REGULAR_STRING_PART;
-                                    }
-            } 
-            // fall through
+                              int closingQuotes = peekQuotes();
+                              if (length < closingQuotes) {
+                                // not enough quotes
+                                return KtTokens.REGULAR_STRING_PART;
+                              }
+                              else if (length == closingQuotes) { // closing """
+                                popState();
+                                return KtTokens.CLOSING_QUOTE;
+                              }
+                              else { // some quotes at the end of a string, e.g. """ "foo""""
+                                yypushback(closingQuotes); // return the closing quotes (""") to the stream
+                                return KtTokens.REGULAR_STRING_PART;
+                              }
+            }
+          // fall through
           case 193: break;
-          case 87: 
-            { return KtTokens.BLOCK_COMMENT;
-            } 
-            // fall through
-          case 194: break;
-          case 88: 
+          case 87:
             { yypushback(3); return KtTokens.EXCL;
-            } 
-            // fall through
+            }
+          // fall through
+          case 194: break;
+          case 88:
+            { return KtTokens.BLOCK_COMMENT;
+            }
+          // fall through
           case 195: break;
-          case 89: 
-            { return KtTokens.THIS_KEYWORD ;
-            } 
-            // fall through
-          case 196: break;
-          case 90: 
-            { return KtTokens.TRUE_KEYWORD ;
-            } 
-            // fall through
-          case 197: break;
-          case 91: 
+          case 89:
             { return KtTokens.ELSE_KEYWORD ;
-            } 
-            // fall through
-          case 198: break;
-          case 92: 
+            }
+          // fall through
+          case 196: break;
+          case 90:
             { return KtTokens.NULL_KEYWORD ;
-            } 
-            // fall through
+            }
+          // fall through
+          case 197: break;
+          case 91:
+            { return KtTokens.THIS_KEYWORD ;
+            }
+          // fall through
+          case 198: break;
+          case 92:
+            { return KtTokens.TRUE_KEYWORD ;
+            }
+          // fall through
           case 199: break;
-          case 93: 
+          case 93:
             { return KtTokens.WHEN_KEYWORD ;
-            } 
-            // fall through
+            }
+          // fall through
           case 200: break;
-          case 94: 
+          case 94:
             { popState(); return KtTokens.THIS_KEYWORD;
-            } 
-            // fall through
+            }
+          // fall through
           case 201: break;
-          case 95: 
-            { return KtTokens.THROW_KEYWORD ;
-            } 
-            // fall through
-          case 202: break;
-          case 96: 
-            { return KtTokens.SUPER_KEYWORD ;
-            } 
-            // fall through
-          case 203: break;
-          case 97: 
-            { return KtTokens.FALSE_KEYWORD ;
-            } 
-            // fall through
-          case 204: break;
-          case 98: 
-            { return KtTokens.CLASS_KEYWORD ;
-            } 
-            // fall through
-          case 205: break;
-          case 99: 
+          case 95:
             { return KtTokens.BREAK_KEYWORD ;
-            } 
-            // fall through
+            }
+          // fall through
+          case 202: break;
+          case 96:
+            { return KtTokens.CLASS_KEYWORD ;
+            }
+          // fall through
+          case 203: break;
+          case 97:
+            { return KtTokens.FALSE_KEYWORD ;
+            }
+          // fall through
+          case 204: break;
+          case 98:
+            { return KtTokens.SUPER_KEYWORD ;
+            }
+          // fall through
+          case 205: break;
+          case 99:
+            { return KtTokens.THROW_KEYWORD ;
+            }
+          // fall through
           case 206: break;
-          case 100: 
+          case 100:
             { return KtTokens.WHILE_KEYWORD ;
-            } 
-            // fall through
+            }
+          // fall through
           case 207: break;
-          case 101: 
-            { return KtTokens.TYPEOF_KEYWORD ;
-            } 
-            // fall through
-          case 208: break;
-          case 102: 
-            { return KtTokens.RETURN_KEYWORD ;
-            } 
-            // fall through
-          case 209: break;
-          case 103: 
+          case 101:
             { return KtTokens.OBJECT_KEYWORD ;
-            } 
-            // fall through
+            }
+          // fall through
+          case 208: break;
+          case 102:
+            { return KtTokens.RETURN_KEYWORD ;
+            }
+          // fall through
+          case 209: break;
+          case 103:
+            { return KtTokens.TYPEOF_KEYWORD ;
+            }
+          // fall through
           case 210: break;
-          case 104: 
+          case 104:
             { return KtTokens.PACKAGE_KEYWORD ;
-            } 
-            // fall through
+            }
+          // fall through
           case 211: break;
-          case 105: 
+          case 105:
             { return KtTokens.CONTINUE_KEYWORD ;
-            } 
-            // fall through
+            }
+          // fall through
           case 212: break;
-          case 106: 
-            { return KtTokens.TYPE_ALIAS_KEYWORD ;
-            } 
-            // fall through
-          case 213: break;
-          case 107: 
+          case 106:
             { return KtTokens.INTERFACE_KEYWORD ;
-            } 
-            // fall through
+            }
+          // fall through
+          case 213: break;
+          case 107:
+            { return KtTokens.TYPE_ALIAS_KEYWORD ;
+            }
+          // fall through
           case 214: break;
           default:
             zzScanError(ZZ_NO_MATCH);