Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestBugInSomething.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestBugInSomething.java	(revision 1339562)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestBugInSomething.java	(working copy)
@@ -3,18 +3,27 @@
 import java.io.IOException;
 import java.io.Reader;
 import java.nio.CharBuffer;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.BaseTokenStreamTestCase;
+import org.apache.lucene.analysis.CharReader;
 import org.apache.lucene.analysis.CharStream;
 import org.apache.lucene.analysis.MockCharFilter;
 import org.apache.lucene.analysis.MockTokenFilter;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenFilter;
+import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.ValidatingTokenFilter;
 import org.apache.lucene.analysis.charfilter.MappingCharFilter;
 import org.apache.lucene.analysis.charfilter.NormalizeCharMap;
 import org.apache.lucene.analysis.commongrams.CommonGramsFilter;
+import org.apache.lucene.analysis.pattern.PatternReplaceCharFilter;
+import org.apache.lucene.analysis.shingle.ShingleFilter;
+import org.apache.lucene.analysis.standard.UAX29URLEmailTokenizer;
 import org.apache.lucene.analysis.util.CharArraySet;
 
 /**
@@ -195,4 +204,38 @@
       assertEquals("read(char[], int, int)", e.getMessage());
     }
   }
+  
+  public void testGraphCorruption() throws Exception {
+    // 'do' => 'ycxpcdcy', 'lh' => 'zjbmpyli', 'pov' => 'jitdej', 'tnikbwzv' => 'rfelowuyy'
+    NormalizeCharMap.Builder builder = new NormalizeCharMap.Builder();
+    builder.add("do", "ycxpcdcy");
+    builder.add("lh", "zjbmpyli");
+    builder.add("pov", "jitdej");
+    builder.add("tnikbwzv", "rfelowuyy");
+    final NormalizeCharMap map = builder.build();
+    
+    final Set<String> types = new HashSet<String>() {{
+      add("<APOSTROPHE>");
+      add("<EMAIL>");
+      add("<IDEOGRAPHIC>");
+    }};
+    
+    Analyzer a = new Analyzer() {
+      @Override
+      protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
+        Tokenizer tokenizer = new UAX29URLEmailTokenizer(TEST_VERSION_CURRENT, reader);
+        TokenStream filter = new ShingleFilter(tokenizer, 76);
+        filter = new TypeTokenFilter(false, filter, types, false);
+        return new TokenStreamComponents(tokenizer, filter);
+      }
+
+      @Override
+      protected Reader initReader(Reader reader) {
+        CharStream stream = new MappingCharFilter(map, CharReader.get(reader));
+        return new PatternReplaceCharFilter(Pattern.compile("a"), "x", stream);
+      }
+    };
+    
+    checkAnalysisConsistency(random(), a, true, "N`\u4d9f\u3560\u9b830\u6627\u001d\ued87 ");
+  }
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/NormalizeCharMap.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/NormalizeCharMap.java	(revision 1339562)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/NormalizeCharMap.java	(working copy)
@@ -27,6 +27,8 @@
 import org.apache.lucene.util.fst.Builder;
 import org.apache.lucene.util.fst.CharSequenceOutputs;
 import org.apache.lucene.util.fst.FST;
+import org.apache.lucene.util.fst.IntsRefFSTEnum;
+import org.apache.lucene.util.fst.IntsRefFSTEnum.InputOutput;
 import org.apache.lucene.util.fst.Outputs;
 import org.apache.lucene.util.fst.Util;
 
@@ -70,6 +72,38 @@
     }
   }
 
+  // nocommit: i think we should leave this commented out
+  // to aid debugging, but expensive toString is something we should avoid?
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    sb.append("NormalizeCharMap {");
+    if (map != null) {
+      IntsRefFSTEnum<CharsRef> iterator = new IntsRefFSTEnum<CharsRef>(map);
+      try {
+        boolean first = true;
+        while (iterator.next() != null) {
+          InputOutput<CharsRef> io = iterator.current();
+          if (!first) {
+            sb.append(", ");
+          }
+          sb.append("'");
+          for (int i = io.input.offset; i < io.input.offset + io.input.length; i++) {
+            sb.append((char)io.input.ints[i]); // byte2 fst
+          }
+          sb.append("' => '");
+          sb.append(io.output);
+          sb.append("'");
+          first = false;
+        }
+      } catch (IOException bogus) {
+        throw new RuntimeException(bogus);
+      }
+    }
+    sb.append("}");
+    return sb.toString();
+  }
+
   /**
    * Builds an NormalizeCharMap.
    * <p>
