Adds dependency information to SOYC reports, so it is clear why
methods that are in the initial download are included there.
This is a merge from /changes/spoon/soyc-withdeps .
Patch by: kprobst
Review by: spoon
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5006 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/CompilationAnalysis.java b/dev/core/src/com/google/gwt/core/ext/linker/CompilationAnalysis.java
index fc7b985..3ee4d18 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/CompilationAnalysis.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/CompilationAnalysis.java
@@ -16,99 +16,87 @@
 package com.google.gwt.core.ext.linker;
 
 import com.google.gwt.core.ext.Linker;
-import com.google.gwt.core.ext.soyc.ClassMember;
-import com.google.gwt.core.ext.soyc.FunctionMember;
 import com.google.gwt.core.ext.soyc.Range;
 import com.google.gwt.core.ext.soyc.Story;
-
-import java.util.Map;
-import java.util.SortedSet;
+import java.io.File;
 
 /**
  * Represents analysis data for a CompilationResult.
  */
 public abstract class CompilationAnalysis extends Artifact<CompilationAnalysis> {
 
-  /**
-   * Associates a Story and a Range of the output. Instances of this interface
-   * are obtained from {@link CompilationAnalysis#getSnippets()}.
-   */
-  public interface Snippet {
-    Range getRange();
-
-    Story getStory();
-  }
-
   protected CompilationAnalysis(Class<? extends Linker> linkerType) {
     super(linkerType);
   }
 
   /**
-   * Returns all ClassMembers present in the CompilationResult. This method
-   * would typically be used by consumers that are interested in the type
-   * hierarchy of the compilation.
+   * @return a file of dependencies
    */
-  public abstract SortedSet<ClassMember> getClasses();
+  public abstract File getDepFile();
 
   /**
-   * Returns the CompilationResult upon which the analysis was performed.
+   * @return a file of stories
    */
-  public abstract CompilationResult getCompilationResult();
+  public abstract File getStoriesFile();
 
   /**
-   * Returns all JavaScript FunctionMembers in the output.
+   * @return a file of split points
    */
-  public abstract SortedSet<FunctionMember> getFunctions();
-
-  /**
-   * Provides access to the assignments of Stories to Ranges for a fragment of
-   * the output. The Ranges are guaranteed not to overlap, and may be used for
-   * exact accounting of bytes. Due to the potential for very large data-sets to
-   * be accessible through this method, it is recommended that Snippets should
-   * be processed in an incremental fashion that does not require all instances
-   * to be retained at once.
-   */
-  /*
-   * NB: The reason that this returns an Iterable, and not a Map, is that we
-   * want to delay the construction of Range objects for as long as possible. If
-   * we were to return a Map for an analysis of N stories, we would also need N
-   * Ranges, plus the overhead of constructing an ordered Map.
-   */
-  public abstract Iterable<Snippet> getSnippets(int fragmentNumber);
-
-  /**
-   * Returns splitPointMap.
-   */
-  public abstract Map<Integer, String> getSplitPointMap();
-
-  /**
-   * Returns all Stories.
-   */
-  public abstract SortedSet<Story> getStories();
-
-  @Override
-  public final int hashCode() {
-    // NB: Identity is keyed to the CompilationResult
-    return getCompilationResult().hashCode();
-  }
-
-  @Override
-  public String toString() {
-    return "Compilation analysis for " + getCompilationResult().toString();
-  }
+  public abstract File getSplitPointsFile();
 
   @Override
   protected final int compareToComparableArtifact(CompilationAnalysis o) {
-    /*
-     * The identity of a CompilationAnalysis is based on the identity of its
-     * associated CompilationResult.
-     */
-    return getCompilationResult().compareToComparableArtifact(
-        o.getCompilationResult());
+    
+    if ((getDepFile() == null)&&(o.getDepFile()==null)){
+      return 0;
+    }
+    else if ((getDepFile() == null)&&(o.getDepFile() != null)){
+      return 1;
+    }
+    else if ((getDepFile() != null)&&(o.getDepFile() == null)){
+      return -1;
+    }
+    else if (getDepFile().getName().compareTo(o.getDepFile().getName()) == 0){
+      if ((getStoriesFile() == null)&&(o.getStoriesFile() == null)){
+        return 0;
+      }
+      else if ((getStoriesFile() == null)&&(o.getStoriesFile() != null)){
+        return 1;
+      }
+      else if ((getStoriesFile() != null)&&(o.getStoriesFile() == null)){
+        return -1;
+      }
+      else if (getStoriesFile().getName().compareTo(o.getStoriesFile().getName()) == 0){
+        if ((getSplitPointsFile() == null)&&(o.getSplitPointsFile() == null)){
+          return 0;
+        }
+        if ((getSplitPointsFile() == null)&&(o.getSplitPointsFile() != null)){
+          return 1;
+        }
+        else if ((getSplitPointsFile() != null)&&(o.getSplitPointsFile() == null)){
+          return -1;
+        }
+        else return getSplitPointsFile().getName().compareTo(o.getSplitPointsFile().getName());
+      }
+      else{
+        return getStoriesFile().getName().compareTo(o.getStoriesFile().getName());
+      }
+    }
+    else return getDepFile().getName().compareTo(o.getDepFile().getName());
   }
 
   @Override
   protected final Class<CompilationAnalysis> getComparableArtifactType() {
     return CompilationAnalysis.class;
   }
+  
+  @Override
+  public final int hashCode() {
+    
+    assert(getDepFile() != null);
+    assert(getStoriesFile() != null);
+    assert(getSplitPointsFile() != null);
+
+    return 17 * (37 + getDepFile().getName().hashCode()) + (37 + getStoriesFile().getName().hashCode()) + (37 + getSplitPointsFile().getName().hashCode());
+  }
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationAnalysis.java b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationAnalysis.java
index 522094a..45ff2f6 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationAnalysis.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardCompilationAnalysis.java
@@ -18,45 +18,7 @@
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.linker.CompilationAnalysis;
-import com.google.gwt.core.ext.linker.CompilationResult;
-import com.google.gwt.core.ext.soyc.ClassMember;
-import com.google.gwt.core.ext.soyc.FunctionMember;
-import com.google.gwt.core.ext.soyc.Member;
-import com.google.gwt.core.ext.soyc.Range;
-import com.google.gwt.core.ext.soyc.Story;
-import com.google.gwt.core.ext.soyc.Story.Origin;
-import com.google.gwt.core.ext.soyc.impl.AbstractMemberWithDependencies;
-import com.google.gwt.core.ext.soyc.impl.MemberFactory;
-import com.google.gwt.core.ext.soyc.impl.OriginImpl;
-import com.google.gwt.core.ext.soyc.impl.SnippetIterator;
-import com.google.gwt.core.ext.soyc.impl.StandardClassMember;
-import com.google.gwt.core.ext.soyc.impl.StandardFieldMember;
-import com.google.gwt.core.ext.soyc.impl.StandardFunctionMember;
-import com.google.gwt.core.ext.soyc.impl.StandardMethodMember;
-import com.google.gwt.core.ext.soyc.impl.StoryImpl;
-import com.google.gwt.dev.jjs.Correlation;
-import com.google.gwt.dev.jjs.SourceInfo;
-import com.google.gwt.dev.jjs.Correlation.Axis;
-import com.google.gwt.dev.jjs.ast.JField;
-import com.google.gwt.dev.jjs.ast.JMethod;
-import com.google.gwt.dev.jjs.ast.JReferenceType;
-import com.google.gwt.dev.js.ast.JsFunction;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.Stack;
-import java.util.TreeMap;
-import java.util.TreeSet;
+import java.io.File;
 
 /**
  * An implementation of CompilationAnalysis. This class transforms SourceInfos
@@ -64,371 +26,50 @@
  * API.
  */
 public class StandardCompilationAnalysis extends CompilationAnalysis {
-  /**
-   * A roll-up struct for all the data produced by the analysis to make
-   * serialization simpler.
-   */
-  private static class Data implements Serializable {
-    SortedSet<ClassMember> classes;
-    SortedSet<FunctionMember> functions;
-
-    /**
-     * These are the Stories in the order in which they should be presented to
-     * the user via {@link CompilationAnalysis#getSnippets()}.
-     */
-    Map<Integer, List<StoryImpl>> orderedStories = new HashMap<Integer, List<StoryImpl>>();
-
-    SortedSet<Story> stories;
-  }
 
   /**
-   * Associates a SourceInfo with a Range.
+   *  File containing method-level control-flow dependencies (corresponding to the current report)
    */
-  private static class RangeInfo {
-    public final SourceInfo info;
-    public final Range range;
-
-    public RangeInfo(Range range, SourceInfo info) {
-      this.range = range;
-      this.info = info;
-    }
-  }
-
-  private Data data;
-
+  private File depFile;
+  
   /**
-   * Used by {@link #popAndRecord(Stack)} to determine start and end ranges.
+   * File containing stories
    */
-  private int lastEnd = 0;
-
-  private CompilationResult result;
-
+  private File storiesFile;
+  
   /**
-   * This is a class field for convenience, but it should be deleted at the end
-   * of the constructor.
+   * File containing split points
    */
-  private transient Map<SourceInfo, StoryImpl> storyCache = new IdentityHashMap<SourceInfo, StoryImpl>();
-
-  /**
-   * This is a class field for convenience, but it should be deleted at the end
-   * of the constructor.
-   */
-  private transient Map<Correlation, Member> membersByCorrelation = new IdentityHashMap<Correlation, Member>();
-
-  /**
-   * Map from split point numbers to the method where they were set.
-   */
-  private Map<Integer, String> splitPointMap = new TreeMap<Integer, String>();
+  private File splitPointsFile;
   
   /**
    * Constructed by PermutationCompiler.
    */
-  public StandardCompilationAnalysis(TreeLogger logger,
-      List<Map<Range, SourceInfo>> sourceInfoMaps,
-      Map<Integer, String> splitPointMap)
+  public StandardCompilationAnalysis(TreeLogger logger, File depFile, File storiesFile, File splitPointsFile)
       throws UnableToCompleteException {
     super(StandardLinkerContext.class);
     logger = logger.branch(TreeLogger.INFO,
-        "Creating CompilationAnalysis (this may take some time)");
-
-    data = new Data();
+        "Creating CompilationAnalysis");
     
-    this.splitPointMap = splitPointMap;
-    
-    /*
-     * Don't retain beyond the constructor to avoid lingering references to AST
-     * nodes.
-     */
-    MemberFactory memberFactory = new MemberFactory();
-
-    // Record what we've seen so far
-    TreeSet<ClassMember> classesMutable = new TreeSet<ClassMember>(
-        Member.SOURCE_NAME_COMPARATOR);
-    TreeSet<FunctionMember> functionsMutable = new TreeSet<FunctionMember>(
-        Member.SOURCE_NAME_COMPARATOR);
-    Set<SourceInfo> sourceInfoSeen = new HashSet<SourceInfo>();
-
-    int fragment = 0;
-    for (Map<Range, SourceInfo> sourceInfoMap : sourceInfoMaps) {
-      lastEnd = 0;
-      analyzeFragment(memberFactory, classesMutable, functionsMutable,
-          sourceInfoMap, sourceInfoSeen, fragment++);
-    }
-
-    data.classes = Collections.unmodifiableSortedSet(classesMutable);
-    data.functions = Collections.unmodifiableSortedSet(functionsMutable);
-
-    // Deduplicate the ordered stories into an ordered set
-    SortedSet<Story> mutableStories = new TreeSet<Story>(
-        StoryImpl.ID_COMPARATOR);
-    for (List<StoryImpl> stories : data.orderedStories.values()) {
-      mutableStories.addAll(stories);
-    }
-    data.stories = Collections.unmodifiableSortedSet(mutableStories);
-
-    /*
-     * Clear the member fields that we don't need anymore to allow GC of the
-     * SourceInfo objects
-     */
-    membersByCorrelation = null;
-    storyCache = null;
+    this.depFile = depFile;
+    this.storiesFile = storiesFile;
+    this.splitPointsFile = splitPointsFile;
 
     logger.log(TreeLogger.INFO, "Done");
   }
 
   @Override
-  public SortedSet<ClassMember> getClasses() {
-    return data.classes;
+  public File getDepFile() {
+    return depFile;
   }
 
   @Override
-  public CompilationResult getCompilationResult() {
-    return result;
+  public File getStoriesFile() {
+    return storiesFile;
   }
 
   @Override
-  public SortedSet<FunctionMember> getFunctions() {
-    return data.functions;
-  }
-
-  @Override
-  public Iterable<Snippet> getSnippets(int fragment) {
-    final List<StoryImpl> stories = data.orderedStories.get(fragment);
-    if (stories == null) {
-      throw new IllegalArgumentException("Unknown fragment id " + fragment);
-    }
-
-    return new Iterable<Snippet>() {
-      public Iterator<Snippet> iterator() {
-        return new SnippetIterator(stories);
-      }
-    };
-  }
-
-  @Override
-  public Map<Integer, String> getSplitPointMap() {
-    return splitPointMap;
-  }
-  
-  @Override
-  public SortedSet<Story> getStories() {
-    return data.stories;
-  }
-
-  /**
-   * Back-channel setter used by PermutationCompiler.
-   */
-  public void setCompilationResult(CompilationResult result) {
-    this.result = result;
-  }
-
-  private void analyzeFragment(MemberFactory memberFactory,
-      TreeSet<ClassMember> classesMutable,
-      TreeSet<FunctionMember> functionsMutable,
-      Map<Range, SourceInfo> sourceInfoMap, Set<SourceInfo> sourceInfoSeen,
-      int fragment) {
-    /*
-     * We want to iterate over the Ranges so that enclosing Ranges come before
-     * their enclosed Ranges...
-     */
-    Range[] dependencyOrder = sourceInfoMap.keySet().toArray(
-        new Range[sourceInfoMap.size()]);
-    Arrays.sort(dependencyOrder, Range.DEPENDENCY_ORDER_COMPARATOR);
-
-    Stack<RangeInfo> dependencyScope = new Stack<RangeInfo>();
-    for (Range range : dependencyOrder) {
-      SourceInfo info = sourceInfoMap.get(range);
-      assert info != null;
-
-      // Infer dependency information
-      if (!dependencyScope.isEmpty()) {
-
-        /*
-         * Pop frames until we get back to a container, using this as a chance
-         * to build up our list of non-overlapping Ranges to report back to the
-         * user.
-         */
-        while (!dependencyScope.peek().range.contains(range)) {
-          popAndRecord(dependencyScope, fragment);
-        }
-      }
-
-      // Possibly create and record Members
-      if (!sourceInfoSeen.contains(info)) {
-        sourceInfoSeen.add(info);
-        for (Correlation c : info.getPrimaryCorrelations()) {
-          if (membersByCorrelation.containsKey(c)) {
-            continue;
-          }
-
-          switch (c.getAxis()) {
-            case CLASS: {
-              JReferenceType type = c.getType();
-              StandardClassMember member = memberFactory.get(type);
-              membersByCorrelation.put(c, member);
-              classesMutable.add(member);
-              break;
-            }
-            case FIELD: {
-              JField field = c.getField();
-              JReferenceType type = c.getType();
-              StandardFieldMember member = memberFactory.get(field);
-              memberFactory.get(type).addField(member);
-              membersByCorrelation.put(c, member);
-              break;
-            }
-            case FUNCTION: {
-              JsFunction function = c.getFunction();
-              StandardFunctionMember member = memberFactory.get(function);
-              membersByCorrelation.put(c, member);
-              functionsMutable.add(member);
-              break;
-            }
-            case METHOD: {
-              JMethod method = c.getMethod();
-              JReferenceType type = c.getType();
-              StandardMethodMember member = memberFactory.get(method);
-              memberFactory.get(type).addMethod(member);
-              membersByCorrelation.put(c, member);
-              break;
-            }
-          }
-        }
-      }
-
-      /*
-       * Record dependencies as observed in the structure of the JS output. This
-       * an an ad-hoc approach that just looks at which SourceInfos are used
-       * within the Range of another SourceInfo.
-       */
-      Set<Correlation> correlationsInScope = new HashSet<Correlation>();
-      for (RangeInfo outer : dependencyScope) {
-        SourceInfo outerInfo = outer.info;
-        correlationsInScope.addAll(outerInfo.getPrimaryCorrelations());
-
-        for (Correlation outerCorrelation : outerInfo.getPrimaryCorrelations()) {
-          Member outerMember = membersByCorrelation.get(outerCorrelation);
-
-          if (outerMember instanceof AbstractMemberWithDependencies) {
-            for (Correlation innerCorrelation : info.getAllCorrelations()) {
-              /*
-               * This check prevents an inlined method from depending on the
-               * method or function into which is was inlined.
-               */
-              if (correlationsInScope.contains(innerCorrelation)) {
-                continue;
-              }
-
-              Member innerMember = membersByCorrelation.get(innerCorrelation);
-
-              /*
-               * The null check is because we may not create Members for all
-               * types of Correlations.
-               */
-              if (innerMember != null) {
-                if (((AbstractMemberWithDependencies) outerMember).addDependency(innerMember)) {
-                  // System.out.println(outerMember + " -> " + innerMember);
-                }
-              }
-            }
-          }
-        }
-      }
-
-      dependencyScope.push(new RangeInfo(range, info));
-    }
-
-    // Unwind the rest of the stack to finish out the ranges
-    while (!dependencyScope.isEmpty()) {
-      popAndRecord(dependencyScope, fragment);
-    }
-
-    /*
-     * Because the first Range corresponds to the SourceInfo of the whole
-     * program, we'll know that we got all of the data if the ends match up. If
-     * this assert passes, we know that we've correctly generated a sequence of
-     * non-overlapping Ranges that encompass the whole program.
-     */
-    assert dependencyOrder[0].getEnd() == lastEnd;
-  }
-
-  /**
-   * Remove an element from the RangeInfo stack and stare a new StoryImpl with
-   * the right length, possibly sub-dividing the super-enclosing Range in the
-   * process.
-   */
-  private void popAndRecord(Stack<RangeInfo> dependencyScope, int fragment) {
-    RangeInfo rangeInfo = dependencyScope.pop();
-    Range toStore = rangeInfo.range;
-
-    /*
-     * Make a new Range for the gap between the popped Range and whatever we
-     * last stored.
-     */
-    if (lastEnd < toStore.getStart()) {
-      Range newRange = new Range(lastEnd, toStore.getStart());
-      assert !dependencyScope.isEmpty();
-
-      SourceInfo gapInfo = dependencyScope.peek().info;
-      recordStory(gapInfo, fragment, newRange.length());
-      lastEnd += newRange.length();
-    }
-
-    /*
-     * Store as much of the current Range as we haven't previously stored. The
-     * Max.max() is there to take care of the tail end of Ranges that have had a
-     * sub-range previously stored.
-     */
-    if (lastEnd < toStore.getEnd()) {
-      Range newRange = new Range(Math.max(lastEnd, toStore.getStart()),
-          toStore.getEnd());
-      recordStory(rangeInfo.info, fragment, newRange.length());
-      lastEnd += newRange.length();
-    }
-  }
-
-  private void recordStory(SourceInfo info, int fragment, int length) {
-    assert storyCache != null;
-
-    StoryImpl theStory;
-    if (!storyCache.containsKey(info)) {
-
-      SortedSet<Member> members = new TreeSet<Member>(
-          Member.TYPE_AND_SOURCE_NAME_COMPARATOR);
-
-      if (info != null) {
-        for (Correlation c : info.getAllCorrelations()) {
-          Member m = membersByCorrelation.get(c);
-          if (m != null) {
-            members.add(m);
-          }
-        }
-      }
-
-      SortedSet<Origin> origins = new TreeSet<Origin>();
-      for (Correlation c : info.getAllCorrelations(Axis.ORIGIN)) {
-        origins.add(new OriginImpl(c.getOrigin()));
-      }
-
-      String literalType = null;
-      Correlation literalCorrelation = info.getPrimaryCorrelation(Axis.LITERAL);
-      if (literalCorrelation != null) {
-        literalType = literalCorrelation.getLiteral().getDescription();
-      }
-
-      theStory = new StoryImpl(storyCache.size(), members, info.getMutations(),
-          origins, literalType, fragment, length);
-      storyCache.put(info, theStory);
-    } else {
-      // Use a copy-constructed instance
-      theStory = new StoryImpl(storyCache.get(info), length);
-    }
-
-    List<StoryImpl> stories = data.orderedStories.get(fragment);
-    if (stories == null) {
-      stories = new ArrayList<StoryImpl>();
-      data.orderedStories.put(fragment, stories);
-    }
-    stories.add(theStory);
+  public File getSplitPointsFile() {
+    return splitPointsFile;
   }
 }
diff --git a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java
index 3666044..0980040 100644
--- a/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java
+++ b/dev/core/src/com/google/gwt/core/ext/linker/impl/StandardLinkerContext.java
@@ -269,7 +269,6 @@
       FileBackedObject<PermutationResult> resultFile)
       throws UnableToCompleteException {
     PermutationResult permutationResult = resultFile.newInstance(logger);
-
     String strongName = Util.computeStrongName(Util.getBytes(permutationResult.getJs()));
     StandardCompilationResult result = resultsByStrongName.get(strongName);
     if (result == null) {
@@ -280,10 +279,6 @@
       // Add any other Permutations
       ArtifactSet otherArtifacts = permutationResult.getArtifacts();
       if (otherArtifacts != null) {
-        // Fixups for StandardCompilationAnalysis objects
-        for (StandardCompilationAnalysis a : otherArtifacts.find(StandardCompilationAnalysis.class)) {
-          a.setCompilationResult(result);
-        }
         artifacts.addAll(otherArtifacts);
       }
     }
@@ -461,6 +456,18 @@
         outFile.setLastModified(artifact.getLastModified());
       }
     }
+    for (StandardCompilationAnalysis soycFiles : artifacts.find(StandardCompilationAnalysis.class)){
+        TreeLogger artifactLogger = logger.branch(TreeLogger.DEBUG,
+            "Emitting soyc resources.", null);
+        File depFile = new File(extraPath + "/soycReport", soycFiles.getDepFile().getName());
+        Util.copy(artifactLogger, soycFiles.getDepFile(), depFile);
+
+        File storiesFile = new File(extraPath + "/soycReport", soycFiles.getStoriesFile().getName());
+        Util.copy(artifactLogger, soycFiles.getStoriesFile(), storiesFile);
+
+        File splitPointsFile = new File(extraPath + "/soycReport", soycFiles.getSplitPointsFile().getName());
+        Util.copy(artifactLogger, soycFiles.getSplitPointsFile(), splitPointsFile);
+    }
   }
 
   /**
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/SplitPointRecorder.java b/dev/core/src/com/google/gwt/core/ext/soyc/SplitPointRecorder.java
new file mode 100644
index 0000000..7acdd04
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/SplitPointRecorder.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.core.ext.soyc;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.jjs.ast.JProgram;
+
+import java.io.File;
+
+public interface SplitPointRecorder {
+  /**
+   * Used to record (runAsync) split points of a program
+   * 
+   * @param jprogram
+   * @param workDir
+   * @param permutationId
+   * @param logger
+   * @return The file that the dependencies are recorded in
+   */
+  public File recordSplitPoints(JProgram jprogram, File workDir, int permutationId, TreeLogger logger);
+
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/Story.java b/dev/core/src/com/google/gwt/core/ext/soyc/Story.java
index a08fd85..7805c26 100644
--- a/dev/core/src/com/google/gwt/core/ext/soyc/Story.java
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/Story.java
@@ -79,13 +79,6 @@
   SortedSet<Member> getMembers();
 
   /**
-   * Gets a list of transformations applied to the original source code in order
-   * to produce the story entry. This method will not return any data unless the
-   * compiler has been configured to collect mutation data.
-   */
-  List<String> getMutations();
-
-  /**
    * Returns the locations of the Story's source. Identical structures (such as
    * string literals) that appear in multiple locations in the source may be
    * merged by the compiler into a single Story.
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/StoryRecorder.java b/dev/core/src/com/google/gwt/core/ext/soyc/StoryRecorder.java
new file mode 100644
index 0000000..85737a5
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/StoryRecorder.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.core.ext.soyc;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.jjs.SourceInfo;
+import com.google.gwt.dev.jjs.ast.JProgram;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+public interface StoryRecorder {
+  /**
+   * Used to record dependencies of a program
+   * 
+   * @param jprogram
+   * @param workDir
+   * @param permutationId
+   * @param logger
+   * @return The file that the dependencies are recorded in
+   */
+  public File recordStories(JProgram jprogram, File workDir, int permutationId,
+      TreeLogger logger, List<Map<Range, SourceInfo>> sourceInfoMaps,
+      String[] js);
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/impl/DependencyRecorderImpl.java b/dev/core/src/com/google/gwt/core/ext/soyc/impl/DependencyRecorderImpl.java
new file mode 100644
index 0000000..1880947
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/impl/DependencyRecorderImpl.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.core.ext.soyc.impl;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.jjs.ast.JMethod;
+import com.google.gwt.dev.jjs.ast.JProgram;
+import com.google.gwt.dev.jjs.impl.ControlFlowAnalyzer;
+import com.google.gwt.dev.util.HtmlTextOutput;
+import com.google.gwt.util.tools.Utility;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.zip.GZIPOutputStream;
+
+public class DependencyRecorderImpl implements ControlFlowAnalyzer.DependencyRecorder {
+
+  private OutputStreamWriter writer;
+  private PrintWriter pw;
+  private HtmlTextOutput htmlOut;
+
+  /**
+   * Used to record the dependencies of a specific method
+   * 
+   * @param liveMethod
+   * @param dependencyChain
+   */
+  public void methodIsLiveBecause(JMethod liveMethod,
+      ArrayList<JMethod> dependencyChain) {
+    printMethodDependency(liveMethod, dependencyChain);
+  }
+
+  /**
+   * Used to record dependencies of a program
+   * 
+   * @param jprogram
+   * @param workDir
+   * @param permutationId
+   * @param logger
+   * @return The file that the dependencies are recorded in
+   */
+  public File recordDependencies(JProgram jprogram, File workDir,
+      int permutationId, TreeLogger logger) {
+    
+    logger = logger.branch(TreeLogger.INFO, "Creating Dependencies file for SOYC");
+    
+    ControlFlowAnalyzer dependencyAnalyzer = new ControlFlowAnalyzer(jprogram);
+    dependencyAnalyzer.setDependencyRecorder(this);
+    
+    File appendDepFile = new File(workDir, "dependencies" + permutationId
+        + ".xml.gz");
+    try {
+      FileOutputStream stream = new FileOutputStream(appendDepFile, true);
+      writer = new OutputStreamWriter(new GZIPOutputStream(stream), "UTF-8");
+      appendDepFile.getParentFile().mkdirs();
+      pw = new PrintWriter(writer);
+      htmlOut = new HtmlTextOutput(pw, false);
+    } catch (Throwable e) {
+      logger.log(TreeLogger.ERROR, "Could not open dependency file.", e);
+    }
+
+    printPre();
+    for (JMethod method : jprogram.getAllEntryMethods()) {
+      dependencyAnalyzer.traverseFrom(method);
+    }
+    printPost();
+    pw.close();
+    Utility.close(writer);
+    
+    logger.log(TreeLogger.INFO, "Done");
+    
+    return appendDepFile;
+  }
+
+  /**
+   * Prints the control-flow dependencies to a file in a specific format
+   * 
+   * @param liveMethod
+   * @param dependencyChain
+   */
+  private void printMethodDependency(JMethod liveMethod,
+      ArrayList<JMethod> dependencyChain) {
+    String curLine;
+    for (int i = dependencyChain.size() - 1; i >= 0; i--) {
+      JMethod curMethod = dependencyChain.get(i);
+      String sFullMethodString = curMethod.getName();
+      if (curMethod.getEnclosingType() != null) {
+        sFullMethodString = curMethod.getEnclosingType().getName() + "::"
+            + curMethod.getName();
+      }
+      if (i == dependencyChain.size() - 1) {
+        curLine = "<method name=\"" + sFullMethodString + "\">";
+        htmlOut.printRaw(curLine);
+        htmlOut.newline();
+        htmlOut.indentIn();
+        htmlOut.indentIn();
+      } else {
+        curLine = "<called by=\"" + sFullMethodString + "\"/>";
+        htmlOut.printRaw(curLine);
+        htmlOut.newline();
+      }
+    }
+    htmlOut.indentOut();
+    htmlOut.indentOut();
+    curLine = "</method>";
+    htmlOut.printRaw(curLine);
+    htmlOut.newline();
+  }
+
+  /**
+   * Prints the preamble necessary for the dependencies file
+   */
+  private void printPre() {
+    String curLine = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+    htmlOut.printRaw(curLine);
+    htmlOut.newline();
+    curLine = "<soyc-dependencies>";
+    htmlOut.printRaw(curLine);
+    htmlOut.newline();
+    htmlOut.indentIn();
+    htmlOut.indentIn();
+  }
+
+  /**
+   * Prints the closing lines necessary for the dependencies file
+   */
+  private void printPost() {
+    String curLine = "</soyc-dependencies>";
+    htmlOut.indentOut();
+    htmlOut.indentOut();
+    htmlOut.printRaw(curLine);
+    htmlOut.newline();
+  }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/impl/SnippetIterator.java b/dev/core/src/com/google/gwt/core/ext/soyc/impl/SnippetIterator.java
deleted file mode 100644
index 7d2fb50..0000000
--- a/dev/core/src/com/google/gwt/core/ext/soyc/impl/SnippetIterator.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.core.ext.soyc.impl;
-
-import com.google.gwt.core.ext.linker.CompilationAnalysis.Snippet;
-import com.google.gwt.core.ext.soyc.Range;
-import com.google.gwt.core.ext.soyc.Story;
-
-import java.util.Iterator;
-
-/**
- * Uses a list of StoryImpls present a sequence of Snippets by synthesizing
- * Range objects based on the length of the StoryImpls.
- */
-public class SnippetIterator implements Iterator<Snippet> {
-  /**
-   * An Iterator over the backing object.
-   */
-  private final Iterator<StoryImpl> iter;
-
-  /**
-   * The starting position for the next Range object generated.
-   */
-  private int start = 0;
-
-  public SnippetIterator(Iterable<StoryImpl> stories) {
-    iter = stories.iterator();
-  }
-
-  public boolean hasNext() {
-    return iter.hasNext();
-  }
-
-  public Snippet next() {
-    final StoryImpl story = iter.next();
-    final Range range = new Range(start, start + story.getLength());
-    start += story.getLength();
-
-    return new Snippet() {
-      public Range getRange() {
-        return range;
-      }
-
-      public Story getStory() {
-        return story;
-      }
-    };
-  }
-
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-}
\ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/impl/SplitPointRecorderImpl.java b/dev/core/src/com/google/gwt/core/ext/soyc/impl/SplitPointRecorderImpl.java
new file mode 100644
index 0000000..de08526
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/impl/SplitPointRecorderImpl.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.core.ext.soyc.impl;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.soyc.SplitPointRecorder;
+import com.google.gwt.dev.jjs.ast.JProgram;
+import com.google.gwt.dev.util.HtmlTextOutput;
+import com.google.gwt.util.tools.Utility;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Map;
+import java.util.zip.GZIPOutputStream;
+
+public class SplitPointRecorderImpl implements SplitPointRecorder {
+
+  private FileOutputStream stream;
+  private OutputStreamWriter writer;
+  private PrintWriter pw;
+  private HtmlTextOutput htmlOut;
+
+  /**
+   * Used to record (runAsync) split points of a program
+   * 
+   * @param jprogram
+   * @param workDir
+   * @param permutationId
+   * @param logger
+   * @return The file that the dependencies are recorded in
+   */
+  public File recordSplitPoints(JProgram jprogram, File workDir,
+      int permutationId, TreeLogger logger) {
+    
+    logger = logger.branch(TreeLogger.INFO, "Creating Split Point Map file for SOYC");
+
+    File splitPointsFile = new File(workDir, "splitPoints"
+        + Integer.toString(permutationId) + ".xml.gz");
+    try {
+      stream = new FileOutputStream(splitPointsFile, true);
+      writer = new OutputStreamWriter(new GZIPOutputStream(stream), "UTF-8");
+      splitPointsFile.getParentFile().mkdirs();
+      pw = new PrintWriter(writer);
+      htmlOut = new HtmlTextOutput(pw, false);
+
+      String curLine = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+
+      curLine = "<soyc>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+      htmlOut.indentIn();
+      htmlOut.indentIn();
+
+      Map<Integer, String> splitPointMap = jprogram.getSplitPointMap();
+      if (splitPointMap.size() > 0) {
+        curLine = "<splitpoints>";
+        htmlOut.printRaw(curLine);
+        htmlOut.newline();
+        htmlOut.indentIn();
+        htmlOut.indentIn();
+        for (Integer splitPointCount : splitPointMap.keySet()) {
+          curLine = "<splitpoint id=\"" + splitPointCount + "\" location=\""
+              + splitPointMap.get(splitPointCount) + "\"/>";
+          htmlOut.printRaw(curLine);
+          htmlOut.newline();
+        }
+        htmlOut.indentOut();
+        htmlOut.indentOut();
+        curLine = "</splitpoints>";
+        htmlOut.printRaw(curLine);
+        htmlOut.newline();
+      }
+
+      htmlOut.indentOut();
+      htmlOut.indentOut();
+      curLine = "</soyc>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+
+      Utility.close(writer);
+      pw.close();
+      
+      logger.log(TreeLogger.INFO, "Done");
+      
+    } catch (Throwable e) {
+      logger.log(TreeLogger.ERROR, "Could not open dependency file.", e);
+    }
+
+    return splitPointsFile;
+
+  }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryImpl.java b/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryImpl.java
index 7aab089..6526b3e 100644
--- a/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryImpl.java
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryImpl.java
@@ -17,13 +17,10 @@
 
 import com.google.gwt.core.ext.soyc.Member;
 import com.google.gwt.core.ext.soyc.Story;
-import com.google.gwt.dev.jjs.SourceInfo.Mutation;
 
 import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.List;
 import java.util.SortedSet;
 
 /**
@@ -46,18 +43,16 @@
   private final int length;
   private final String literalDescription;
   private final SortedSet<Member> members;
-  private final List<String> mutations;
   private final SortedSet<Origin> origins;
 
   /**
    * Standard constructor. This constructor will create unmodifiable versions of
    * the collections passed into it.
    */
-  public StoryImpl(int id, SortedSet<Member> members, List<Mutation> mutations,
+  public StoryImpl(int id, SortedSet<Member> members, 
       SortedSet<Origin> origins, String literalDescription, int fragment,
       int length) {
     assert members != null;
-    assert mutations != null;
     assert origins != null;
     assert fragment >= 0;
     assert length > 0;
@@ -69,12 +64,6 @@
     this.literalDescription = literalDescription == null ? null
         : literalDescription.intern();
     this.members = Collections.unmodifiableSortedSet(members);
-
-    List<String> mutableMutations = new ArrayList<String>(mutations.size());
-    for (Mutation m : mutations) {
-      mutableMutations.add(m.getDescription() + " by " + m.getCaller());
-    }
-    this.mutations = Collections.unmodifiableList(mutableMutations);
     this.origins = Collections.unmodifiableSortedSet(origins);
   }
 
@@ -89,7 +78,6 @@
     this.length = length;
     this.literalDescription = other.literalDescription;
     this.members = other.members;
-    this.mutations = other.mutations;
     this.origins = other.origins;
   }
 
@@ -128,10 +116,6 @@
     return members;
   }
 
-  public List<String> getMutations() {
-    return mutations;
-  }
-
   public SortedSet<Origin> getSourceOrigin() {
     return origins;
   }
diff --git a/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryRecorderImpl.java b/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryRecorderImpl.java
new file mode 100644
index 0000000..b861c32
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryRecorderImpl.java
@@ -0,0 +1,485 @@
+/*
+ * Copyright 2009 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.core.ext.soyc.impl;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.soyc.Range;
+import com.google.gwt.core.ext.soyc.Story;
+import com.google.gwt.core.ext.soyc.StoryRecorder;
+import com.google.gwt.dev.jjs.Correlation;
+import com.google.gwt.dev.jjs.SourceInfo;
+import com.google.gwt.dev.jjs.Correlation.Axis;
+import com.google.gwt.dev.jjs.ast.JField;
+import com.google.gwt.dev.jjs.ast.JMethod;
+import com.google.gwt.dev.jjs.ast.JProgram;
+import com.google.gwt.dev.jjs.ast.JReferenceType;
+import com.google.gwt.dev.js.ast.JsFunction;
+import com.google.gwt.dev.util.HtmlTextOutput;
+import com.google.gwt.util.tools.Utility;
+import com.google.gwt.core.ext.soyc.ClassMember;
+import com.google.gwt.core.ext.soyc.FunctionMember;
+import com.google.gwt.core.ext.soyc.Member;
+import com.google.gwt.core.ext.soyc.Story.Origin;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.Stack;
+import java.util.TreeSet;
+import java.util.zip.GZIPOutputStream;
+
+public class StoryRecorderImpl implements StoryRecorder {
+
+  private FileOutputStream stream;
+  private OutputStreamWriter writer;
+  private PrintWriter pw;
+  private HtmlTextOutput htmlOut;
+
+  private Map<Story, Integer> storyIds = new HashMap<Story, Integer>();
+  private String[] js;
+  private int curHighestFragment = 0;
+
+  /**
+   * Used to record dependencies of a program
+   * 
+   * @param jprogram
+   * @param workDir
+   * @param permutationId
+   * @param logger
+   * @return The file that the dependencies are recorded in
+   */
+  public File recordStories(JProgram jprogram, File workDir, int permutationId,
+      TreeLogger logger, List<Map<Range, SourceInfo>> sourceInfoMaps,
+      String[] js) {
+
+    logger = logger.branch(TreeLogger.INFO, "Creating Stories file for SOYC");
+
+    this.js = js;
+
+    File storiesFile = new File(workDir, "stories"
+        + Integer.toString(permutationId) + ".xml.gz");
+    try {
+      stream = new FileOutputStream(storiesFile, true);
+      writer = new OutputStreamWriter(new GZIPOutputStream(stream), "UTF-8");
+      storiesFile.getParentFile().mkdirs();
+      pw = new PrintWriter(writer);
+      htmlOut = new HtmlTextOutput(pw, false);
+
+      String curLine = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+
+      curLine = "<soyc>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+      htmlOut.indentIn();
+      htmlOut.indentIn();
+
+      curLine = "<stories>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+      htmlOut.indentIn();
+      htmlOut.indentIn();
+
+      /*
+       * Don't retain beyond the constructor to avoid lingering references to
+       * AST nodes.
+       */
+      MemberFactory memberFactory = new MemberFactory();
+
+      // Record what we've seen so far
+      TreeSet<ClassMember> classesMutable = new TreeSet<ClassMember>(
+          Member.SOURCE_NAME_COMPARATOR);
+      TreeSet<FunctionMember> functionsMutable = new TreeSet<FunctionMember>(
+          Member.SOURCE_NAME_COMPARATOR);
+      Set<SourceInfo> sourceInfoSeen = new HashSet<SourceInfo>();
+
+      int fragment = 0;
+      for (Map<Range, SourceInfo> sourceInfoMap : sourceInfoMaps) {
+        lastEnd = 0;
+        analyzeFragment(memberFactory, classesMutable, functionsMutable,
+            sourceInfoMap, sourceInfoSeen, fragment++);
+      }
+
+      /*
+       * Clear the member fields that we don't need anymore to allow GC of the
+       * SourceInfo objects
+       */
+      membersByCorrelation = null;
+      storyCache = null;
+
+      htmlOut.indentOut();
+      htmlOut.indentOut();
+      curLine = "</stories>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+
+      htmlOut.indentOut();
+      htmlOut.indentOut();
+      curLine = "</soyc>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+
+      Utility.close(writer);
+      pw.close();
+     
+      logger.log(TreeLogger.INFO, "Done");
+      
+    } catch (Throwable e) {
+      logger.log(TreeLogger.ERROR, "Could not open dependency file.", e);
+    }
+
+    return storiesFile;
+  }
+
+  /**
+   * Associates a SourceInfo with a Range.
+   */
+  private static class RangeInfo {
+    public final SourceInfo info;
+    public final Range range;
+
+    public RangeInfo(Range range, SourceInfo info) {
+      this.range = range;
+      this.info = info;
+    }
+  }
+
+  /**
+   * Used by {@link #popAndRecord(Stack)} to determine start and end ranges.
+   */
+  private int lastEnd = 0;
+
+  /**
+   * This is a class field for convenience, but it should be deleted at the end
+   * of the constructor.
+   */
+  private transient Map<SourceInfo, StoryImpl> storyCache = new IdentityHashMap<SourceInfo, StoryImpl>();
+
+  /**
+   * This is a class field for convenience, but it should be deleted at the end
+   * of the constructor.
+   */
+  private transient Map<Correlation, Member> membersByCorrelation = new IdentityHashMap<Correlation, Member>();
+
+  private void analyzeFragment(MemberFactory memberFactory,
+      TreeSet<ClassMember> classesMutable,
+      TreeSet<FunctionMember> functionsMutable,
+      Map<Range, SourceInfo> sourceInfoMap, Set<SourceInfo> sourceInfoSeen,
+      int fragment) {
+    /*
+     * We want to iterate over the Ranges so that enclosing Ranges come before
+     * their enclosed Ranges...
+     */
+    Range[] dependencyOrder = sourceInfoMap.keySet().toArray(
+        new Range[sourceInfoMap.size()]);
+    Arrays.sort(dependencyOrder, Range.DEPENDENCY_ORDER_COMPARATOR);
+
+    Stack<RangeInfo> dependencyScope = new Stack<RangeInfo>();
+    for (Range range : dependencyOrder) {
+      SourceInfo info = sourceInfoMap.get(range);
+      assert info != null;
+
+      // Infer dependency information
+      if (!dependencyScope.isEmpty()) {
+
+        /*
+         * Pop frames until we get back to a container, using this as a chance
+         * to build up our list of non-overlapping Ranges to report back to the
+         * user.
+         */
+        while (!dependencyScope.peek().range.contains(range)) {
+          popAndRecord(dependencyScope, fragment);
+        }
+      }
+
+      // Possibly create and record Members
+      if (!sourceInfoSeen.contains(info)) {
+        sourceInfoSeen.add(info);
+        for (Correlation c : info.getPrimaryCorrelations()) {
+          if (membersByCorrelation.containsKey(c)) {
+            continue;
+          }
+
+          switch (c.getAxis()) {
+            case CLASS: {
+              JReferenceType type = c.getType();
+              StandardClassMember member = memberFactory.get(type);
+              membersByCorrelation.put(c, member);
+              classesMutable.add(member);
+              break;
+            }
+            case FIELD: {
+              JField field = c.getField();
+              JReferenceType type = c.getType();
+              StandardFieldMember member = memberFactory.get(field);
+              memberFactory.get(type).addField(member);
+              membersByCorrelation.put(c, member);
+              break;
+            }
+            case FUNCTION: {
+              JsFunction function = c.getFunction();
+              StandardFunctionMember member = memberFactory.get(function);
+              membersByCorrelation.put(c, member);
+              functionsMutable.add(member);
+              break;
+            }
+            case METHOD: {
+              JMethod method = c.getMethod();
+              JReferenceType type = c.getType();
+              StandardMethodMember member = memberFactory.get(method);
+              memberFactory.get(type).addMethod(member);
+              membersByCorrelation.put(c, member);
+              break;
+            }
+          }
+        }
+      }
+
+      /*
+       * Record dependencies as observed in the structure of the JS output. This
+       * an an ad-hoc approach that just looks at which SourceInfos are used
+       * within the Range of another SourceInfo.
+       */
+      Set<Correlation> correlationsInScope = new HashSet<Correlation>();
+      for (RangeInfo outer : dependencyScope) {
+        SourceInfo outerInfo = outer.info;
+        correlationsInScope.addAll(outerInfo.getPrimaryCorrelations());
+      }
+
+      dependencyScope.push(new RangeInfo(range, info));
+    }
+
+    // Unwind the rest of the stack to finish out the ranges
+    while (!dependencyScope.isEmpty()) {
+      popAndRecord(dependencyScope, fragment);
+    }
+
+    /*
+     * Because the first Range corresponds to the SourceInfo of the whole
+     * program, we'll know that we got all of the data if the ends match up. If
+     * this assert passes, we know that we've correctly generated a sequence of
+     * non-overlapping Ranges that encompass the whole program.
+     */
+    assert dependencyOrder[0].getEnd() == lastEnd;
+  }
+
+  /**
+   * Remove an element from the RangeInfo stack and stare a new StoryImpl with
+   * the right length, possibly sub-dividing the super-enclosing Range in the
+   * process.
+   */
+  private void popAndRecord(Stack<RangeInfo> dependencyScope, int fragment) {
+    RangeInfo rangeInfo = dependencyScope.pop();
+    Range toStore = rangeInfo.range;
+
+    /*
+     * Make a new Range for the gap between the popped Range and whatever we
+     * last stored.
+     */
+    if (lastEnd < toStore.getStart()) {
+      Range newRange = new Range(lastEnd, toStore.getStart());
+      assert !dependencyScope.isEmpty();
+
+      SourceInfo gapInfo = dependencyScope.peek().info;
+      recordStory(gapInfo, fragment, newRange.length(), newRange);
+      
+      lastEnd += newRange.length();
+    }
+
+    /*
+     * Store as much of the current Range as we haven't previously stored. The
+     * Max.max() is there to take care of the tail end of Ranges that have had a
+     * sub-range previously stored.
+     */
+    if (lastEnd < toStore.getEnd()) {
+      Range newRange = new Range(Math.max(lastEnd, toStore.getStart()),
+          toStore.getEnd());
+      recordStory(rangeInfo.info, fragment, newRange.length(), newRange);
+      lastEnd += newRange.length();
+    }
+  }
+
+  private void recordStory(SourceInfo info, int fragment, int length,
+      Range range) {
+    assert storyCache != null;
+
+    if (fragment > curHighestFragment) {
+      curHighestFragment = fragment;
+    }
+
+    StoryImpl theStory;
+    if (!storyCache.containsKey(info)) {
+
+      SortedSet<Member> members = new TreeSet<Member>(
+          Member.TYPE_AND_SOURCE_NAME_COMPARATOR);
+
+      if (info != null) {
+        for (Correlation c : info.getAllCorrelations()) {
+          Member m = membersByCorrelation.get(c);
+          if (m != null) {
+            members.add(m);
+          }
+        }
+      }
+
+      SortedSet<Origin> origins = new TreeSet<Origin>();
+      for (Correlation c : info.getAllCorrelations(Axis.ORIGIN)) {
+        origins.add(new OriginImpl(c.getOrigin()));
+      }
+
+      String literalType = null;
+      Correlation literalCorrelation = info.getPrimaryCorrelation(Axis.LITERAL);
+      if (literalCorrelation != null) {
+        literalType = literalCorrelation.getLiteral().getDescription();
+      }
+
+      theStory = new StoryImpl(storyCache.size(), members, origins,
+          literalType, fragment, length);
+      storyCache.put(info, theStory);
+    } else {
+      // Use a copy-constructed instance
+      theStory = new StoryImpl(storyCache.get(info), length);
+    }
+
+    emitStory(theStory, range);
+  }
+
+  private void emitStory(StoryImpl story, Range range) {
+    
+    int storyNum;
+    if (storyIds.containsKey(story)) {
+      storyNum = storyIds.get(story);
+    } else {
+      storyNum = storyIds.size();
+      storyIds.put(story, storyNum);
+    }
+
+    String curLine = "<story id=\"story" + Integer.toString(storyNum) + "\"";
+    if (story.getLiteralTypeName() != null) {
+      curLine = curLine + " literal=\"" + story.getLiteralTypeName() + "\"";
+    }
+    curLine = curLine + ">";
+    htmlOut.printRaw(curLine);
+    htmlOut.newline();
+
+    Set<Origin> origins = story.getSourceOrigin();
+    if (origins.size() > 0) {
+      htmlOut.indentIn();
+      htmlOut.indentIn();
+
+      curLine = "<origins>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+
+      htmlOut.indentIn();
+      htmlOut.indentIn();
+    }
+    for (Origin origin : origins) {
+      curLine = "<origin lineNumber=\""
+          + Integer.toString(origin.getLineNumber()) + "\" location=\""
+          + origin.getLocation() + "\"/>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+    }
+    if (origins.size() > 0) {
+      htmlOut.indentOut();
+      htmlOut.indentOut();
+
+      curLine = "</origins>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+
+      htmlOut.indentOut();
+      htmlOut.indentOut();
+    }
+
+    Set<Member> correlations = story.getMembers();
+    if (correlations.size() > 0) {
+      htmlOut.indentIn();
+      htmlOut.indentIn();
+
+      curLine = "<correlations>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+
+      htmlOut.indentIn();
+      htmlOut.indentIn();
+    }
+    for (Member correlation : correlations) {
+      curLine = "<by idref=\"" + correlation.getSourceName() + "\"/>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+    }
+    if (correlations.size() > 0) {
+      htmlOut.indentOut();
+      htmlOut.indentOut();
+
+      curLine = "</correlations>";
+      htmlOut.printRaw(curLine);
+      htmlOut.newline();
+
+      htmlOut.indentOut();
+      htmlOut.indentOut();
+    }
+
+    htmlOut.indentIn();
+    htmlOut.indentIn();
+
+    curLine = "<js fragment=\"" + curHighestFragment + "\"/>";
+    htmlOut.printRaw(curLine);
+    htmlOut.newline();
+
+    String jsCode = js[curHighestFragment].substring(range.getStart(),
+        range.getEnd());
+    jsCode = escapeXml(jsCode);
+    if ((jsCode.length() == 0) || (jsCode.compareTo("\n") == 0)) {
+      curLine = "<storyref idref=\"story" + Integer.toString(storyNum) + "\"/>";
+    } else {
+      curLine = "<storyref idref=\"story" + Integer.toString(storyNum) + "\">"
+          + jsCode + "</storyref>";
+    }
+
+    htmlOut.printRaw(curLine);
+    htmlOut.newline();
+
+    htmlOut.indentOut();
+    htmlOut.indentOut();
+
+    curLine = "</story>";
+    htmlOut.printRaw(curLine);
+    htmlOut.newline();
+  }
+
+  private String escapeXml(String unescaped) {
+    String escaped = unescaped.replaceAll("\\&", "&");
+    escaped = escaped.replaceAll("\\<", "<");
+    escaped = escaped.replaceAll("\\>", ">");
+    escaped = escaped.replaceAll("\\\"", """);
+    // escaped = escaped.replaceAll("\\'", "'");
+    return escaped;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/core/linker/soyc/SoycReportLinker.java b/dev/core/src/com/google/gwt/core/linker/soyc/SoycReportLinker.java
deleted file mode 100644
index 8ab22ab..0000000
--- a/dev/core/src/com/google/gwt/core/linker/soyc/SoycReportLinker.java
+++ /dev/null
@@ -1,827 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.core.linker.soyc;
-
-import com.google.gwt.core.ext.LinkerContext;
-import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.linker.AbstractLinker;
-import com.google.gwt.core.ext.linker.ArtifactSet;
-import com.google.gwt.core.ext.linker.CompilationAnalysis;
-import com.google.gwt.core.ext.linker.CompilationResult;
-import com.google.gwt.core.ext.linker.LinkerOrder;
-import com.google.gwt.core.ext.linker.SelectionProperty;
-import com.google.gwt.core.ext.linker.SyntheticArtifact;
-import com.google.gwt.core.ext.linker.CompilationAnalysis.Snippet;
-import com.google.gwt.core.ext.linker.LinkerOrder.Order;
-import com.google.gwt.core.ext.soyc.ClassMember;
-import com.google.gwt.core.ext.soyc.FieldMember;
-import com.google.gwt.core.ext.soyc.FunctionMember;
-import com.google.gwt.core.ext.soyc.Member;
-import com.google.gwt.core.ext.soyc.MethodMember;
-import com.google.gwt.core.ext.soyc.Range;
-import com.google.gwt.core.ext.soyc.Story;
-import com.google.gwt.core.ext.soyc.Story.Origin;
-import com.google.gwt.dev.util.HtmlTextOutput;
-import com.google.gwt.util.tools.Utility;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.zip.GZIPOutputStream;
-
-/**
- * Generates the XML report containing the Story of Your Compile.
- */
-@LinkerOrder(Order.PRE)
-public class SoycReportLinker extends AbstractLinker {
-
-  public String escapeXml(String unescaped) {
-    String escaped = unescaped.replaceAll("\\&", "&");
-    escaped = escaped.replaceAll("\\<", "<");
-    escaped = escaped.replaceAll("\\>", ">");
-    escaped = escaped.replaceAll("\\\"", """);
-    // escaped = escaped.replaceAll("\\'", "'");
-    return escaped;
-  }
-
-  @Override
-  public String getDescription() {
-    return "Story of your compile report";
-  }
-
-  @Override
-  public ArtifactSet link(TreeLogger logger, LinkerContext context,
-      ArtifactSet artifacts) throws UnableToCompleteException {
-    SortedSet<CompilationAnalysis> reports = artifacts.find(CompilationAnalysis.class);
-
-    // Do nothing if there are no reports to be generated.
-    if (reports.isEmpty()) {
-      return artifacts;
-    }
-
-    logger = logger.branch(TreeLogger.DEBUG, "SOYC report linker");
-    initialize(logger);
-
-    if (reports.isEmpty()) {
-      logger.log(TreeLogger.DEBUG, "No SOYC report artifacts");
-      return artifacts;
-    }
-
-    artifacts = new ArtifactSet(artifacts);
-    int reportNum = 0;
-    SortedMap<CompilationResult, String> partialPathsByResult = new TreeMap<CompilationResult, String>();
-
-    // TODO: This goes much faster in parallel, but what's the policy?
-    ExecutorService executor = Executors.newSingleThreadExecutor();
-    List<Future<SyntheticArtifact>> futures = new ArrayList<Future<SyntheticArtifact>>(
-        reports.size());
-    for (final CompilationAnalysis report : reports) {
-      final TreeLogger loopLogger = logger.branch(TreeLogger.SPAM,
-          "Report for " + report.toString());
-      final String reportName = "report" + reportNum++ + ".xml.gz";
-      partialPathsByResult.put(report.getCompilationResult(), reportName);
-      Future<SyntheticArtifact> future = executor.submit(new Callable<SyntheticArtifact>() {
-        public SyntheticArtifact call() throws Exception {
-          loopLogger.log(TreeLogger.INFO, "Started");
-          SyntheticArtifact reportArtifact = emitReport(loopLogger, report,
-              reportName, true);
-          return reportArtifact;
-        }
-      });
-      futures.add(future);
-    }
-    executor.shutdown();
-
-    for (Future<SyntheticArtifact> future : futures) {
-      SyntheticArtifact artifact;
-      try {
-        artifact = future.get();
-      } catch (InterruptedException e) {
-        logger.log(TreeLogger.ERROR, "Unable to process report", e);
-        throw new UnableToCompleteException();
-      } catch (ExecutionException e) {
-        logger.log(TreeLogger.ERROR, "Unable to process report", e);
-        throw new UnableToCompleteException();
-      }
-      artifact.setPrivate(true);
-      artifacts.add(artifact);
-    }
-
-    // Emit manifest
-    try {
-      SyntheticArtifact sa = emitManifest(logger, artifacts,
-          partialPathsByResult, false);
-      sa.setPrivate(true);
-      artifacts.add(sa);
-    } catch (FileNotFoundException e) {
-      // TODO Auto-generated catch block
-      e.printStackTrace();
-    } catch (IOException e) {
-      // TODO Auto-generated catch block
-      e.printStackTrace();
-    }
-
-    return artifacts;
-  }
-
-  private void emitAliases(HtmlTextOutput htmlOut, Set<String> methodAliases) {
-    String curLine;
-    if (methodAliases.size() > 0) {
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-
-      curLine = "<aliases>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-    }
-
-    for (String methodAlias : methodAliases) {
-      curLine = "<alias jsName=\"" + methodAlias + "\"/>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-    }
-    if (methodAliases.size() > 0) {
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-
-      curLine = "</aliases>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-    }
-  }
-
-  private void emitClasses(HtmlTextOutput htmlOut,
-      SortedMap<String, Set<ClassMember>> packageToClasses, String packageName) {
-    String curLine;
-    /**
-     * sort the classes alphabetically
-     */
-    TreeMap<String, ClassMember> sortedClasses = new TreeMap<String, ClassMember>();
-    for (ClassMember classMember : packageToClasses.get(packageName)) {
-      String className = classMember.getSourceName();
-      sortedClasses.put(className, classMember);
-    }
-
-    for (String className : sortedClasses.keySet()) {
-      ClassMember classMember = sortedClasses.get(className);
-      curLine = "<class id=\"" + className + "\" ";
-      htmlOut.printRaw(curLine);
-
-      String jsName = classMember.getJsName();
-      String name = className.substring(className.lastIndexOf('.') + 1);
-      curLine = "jsName=\"" + jsName + "\" name=\"" + name + "\">";
-
-      if (jsName == null) {
-        curLine = "name=\"" + name + "\">";
-      }
-
-      emitOverrides(htmlOut, curLine, classMember);
-      emitDependencies(htmlOut, classMember);
-      emitMethods(htmlOut, classMember);
-      emitFields(htmlOut, classMember);
-
-      curLine = "</class>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-    }
-  }
-
-  private void emitDependencies(HtmlTextOutput htmlOut, ClassMember classMember) {
-    String curLine;
-    Set<Member> dependencies = classMember.getDependencies();
-    if (dependencies.size() > 0) {
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-
-      curLine = "<depends>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-    }
-    for (Member dependency : dependencies) {
-      curLine = "<on idref=\"" + dependency.getSourceName() + "\"/>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-    }
-    if (dependencies.size() > 0) {
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-
-      curLine = "</depends>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-    }
-  }
-
-  private void emitFields(HtmlTextOutput htmlOut, ClassMember classMember) {
-    String curLine;
-    Set<FieldMember> fields = classMember.getFields();
-    if (fields.size() > 0) {
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-    }
-    for (FieldMember field : fields) {
-      curLine = "<field id=\"" + field.getSourceName() + "\" jsName=\""
-          + field.getJsName() + "\"/>";
-      String curJsName = field.getJsName();
-      if (curJsName == null) {
-        curLine = "<field id=\"" + field.getSourceName() + "\"/>";
-      }
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-    }
-    if (fields.size() > 0) {
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-    }
-  }
-
-  private void emitFunctions(CompilationAnalysis report, HtmlTextOutput htmlOut) {
-    String curLine;
-
-    Set<FunctionMember> functions = report.getFunctions();
-    for (FunctionMember function : functions) {
-      curLine = "<function ";
-      htmlOut.printRaw(curLine);
-
-      String sourceName = function.getSourceName();
-      String jsName = function.getJsName();
-      Set<Member> dependencies = function.getDependencies();
-      if (dependencies.size() == 0) {
-        curLine = "id=\"" + sourceName + "\" jsName=\"" + jsName + "\"/>";
-        if (jsName == null) {
-          curLine = "id=\"" + sourceName + "\"/>";
-        }
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-      } else {
-        curLine = "id=\"" + sourceName + "\" jsName=\"" + jsName + "\">";
-        if (jsName == null) {
-          curLine = "id=\"" + sourceName + "\">";
-        }
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-        htmlOut.indentIn();
-        htmlOut.indentIn();
-
-        curLine = "<depends>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-        htmlOut.indentIn();
-        htmlOut.indentIn();
-      }
-      for (Member dependency : dependencies) {
-        curLine = "<on idref=\"" + dependency.getSourceName() + "\"/>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-      }
-      if (dependencies.size() > 0) {
-        htmlOut.indentOut();
-        htmlOut.indentOut();
-
-        curLine = "</depends>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-        htmlOut.indentOut();
-        htmlOut.indentOut();
-
-        curLine = "</function>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-      }
-    }
-  }
-
-  private void emitJs(CompilationAnalysis report, HtmlTextOutput htmlOut,
-      Map<Story, Integer> storyIds) {
-
-    String curLine;
-    int fragment = 0;
-    for (String contents : report.getCompilationResult().getJavaScript()) {
-      curLine = "<js fragment=\"" + fragment + "\">";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-
-      for (Snippet snippet : report.getSnippets(fragment)) {
-        Range range = snippet.getRange();
-        Story story = snippet.getStory();
-        assert storyIds.containsKey(story);
-        int storyId = storyIds.get(story);
-
-        String jsCode = contents.substring(range.getStart(), range.getEnd());
-        jsCode = escapeXml(jsCode);
-        if ((jsCode.length() == 0) || (jsCode.compareTo("\n") == 0)) {
-          curLine = "<storyref idref=\"story" + Integer.toString(storyId)
-              + "\"/>";
-        } else {
-          curLine = "<storyref idref=\"story" + Integer.toString(storyId)
-              + "\">" + jsCode + "</storyref>";
-        }
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-      }
-
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-
-      curLine = "</js>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      fragment++;
-    }
-  }
-
-  private SyntheticArtifact emitManifest(TreeLogger logger,
-      ArtifactSet artifacts,
-      SortedMap<CompilationResult, String> partialPathsByResult,
-      boolean compress) throws UnableToCompleteException, IOException {
-
-    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-    OutputStreamWriter out;
-    try {
-      out = new OutputStreamWriter(compress ? new GZIPOutputStream(bytes)
-          : bytes);
-    } catch (IOException e) {
-      logger.log(TreeLogger.ERROR, "Unable to set up gzip stream", e);
-      throw new UnableToCompleteException();
-    }
-    PrintWriter pw = new PrintWriter(out);
-    HtmlTextOutput htmlOut = new HtmlTextOutput(pw, false);
-
-    String curLine = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
-    htmlOut.printRaw(curLine);
-    htmlOut.newline();
-    curLine = "<soyc-manifest>";
-    htmlOut.printRaw(curLine);
-    htmlOut.newline();
-    htmlOut.indentIn();
-    htmlOut.indentIn();
-
-    for (Map.Entry<CompilationResult, String> entry : partialPathsByResult.entrySet()) {
-      curLine = "<report href=\"" + entry.getValue() + "\">";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-
-      for (Map<SelectionProperty, String> map : entry.getKey().getPropertyMap()) {
-
-        if (map.size() > 0) {
-          curLine = "<permutation>";
-          htmlOut.printRaw(curLine);
-          htmlOut.newline();
-          htmlOut.indentIn();
-          htmlOut.indentIn();
-
-        } else {
-          curLine = "<permutation/>";
-          htmlOut.printRaw(curLine);
-          htmlOut.newline();
-        }
-        for (Map.Entry<SelectionProperty, String> propertyEntry : map.entrySet()) {
-          curLine = "<property name=\"" + propertyEntry.getKey().getName()
-              + "\" value=\"" + propertyEntry.getValue() + "\"/>";
-          htmlOut.printRaw(curLine);
-          htmlOut.newline();
-        }
-        if (map.size() > 0) {
-          htmlOut.indentOut();
-          htmlOut.indentOut();
-
-          curLine = "</permutation>";
-          htmlOut.printRaw(curLine);
-          htmlOut.newline();
-        }
-      }
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-
-      curLine = "</report>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-    }
-
-    htmlOut.indentOut();
-    htmlOut.indentOut();
-
-    curLine = "</soyc-manifest>";
-    htmlOut.printRaw(curLine);
-    htmlOut.newline();
-
-    pw.close();
-    Utility.close(out);
-    SyntheticArtifact toReturn = emitBytes(logger, bytes.toByteArray(),
-        "manifest.xml");
-
-    return toReturn;
-  }
-
-  private void emitMembers(CompilationAnalysis report, HtmlTextOutput htmlOut) {
-
-    String curLine = "<members>";
-    htmlOut.printRaw(curLine);
-    htmlOut.newline();
-    htmlOut.indentIn();
-    htmlOut.indentIn();
-
-    SortedMap<String, Set<ClassMember>> packageToClasses = new TreeMap<String, Set<ClassMember>>();
-
-    emitPackages(report, htmlOut, packageToClasses);
-    emitFunctions(report, htmlOut);
-
-    htmlOut.indentOut();
-    htmlOut.indentOut();
-    curLine = "</members>";
-    htmlOut.printRaw(curLine);
-    htmlOut.newline();
-  }
-
-  private void emitMethodDependencies(HtmlTextOutput htmlOut,
-      Set<Member> methodDependencies) {
-    String curLine;
-    if (methodDependencies.size() > 0) {
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-
-      curLine = "<depends>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-
-      for (Member methodDependency : methodDependencies) {
-        curLine = "<on idref=\"" + methodDependency.getSourceName() + "\"/>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-      }
-
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-
-      curLine = "</depends>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-    }
-  }
-
-  private void emitMethodOverrides(HtmlTextOutput htmlOut,
-      Set<MethodMember> methodOverrides) {
-    String curLine;
-    if (methodOverrides.size() > 0) {
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-
-      curLine = "<override>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-    }
-    for (MethodMember overrideMethodMember : methodOverrides) {
-      curLine = "<of idref=\"" + overrideMethodMember.getSourceName() + "\"/>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-    }
-    if (methodOverrides.size() > 0) {
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-
-      curLine = "</override>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-    }
-  }
-
-  private void emitMethods(HtmlTextOutput htmlOut, ClassMember classMember) {
-    String curLine;
-    Set<MethodMember> methods = classMember.getMethods();
-    if (methods.size() > 0) {
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-    }
-    for (MethodMember method : methods) {
-      curLine = "<method ";
-      htmlOut.printRaw(curLine);
-
-      String jsAtt = " jsName=\"" + method.getJsName() + "\"";
-      String curJsName = method.getJsName();
-
-      if (curJsName == null) {
-        jsAtt = "";
-      }
-
-      Set<String> methodAliases = method.getJsAliases();
-      Set<MethodMember> methodOverrides = method.getOverrides();
-      Set<Member> methodDependencies = method.getDependencies();
-
-      if ((methodOverrides.size() > 0) || (methodDependencies.size() > 0)
-          || (methodAliases.size() > 0)) {
-        curLine = "id=\"" + method.getSourceName() + "\"" + jsAtt + ">";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-      } else {
-        curLine = "id=\"" + method.getSourceName() + "\"" + jsAtt + "/>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-      }
-
-      emitAliases(htmlOut, methodAliases);
-      emitMethodOverrides(htmlOut, methodOverrides);
-      emitMethodDependencies(htmlOut, methodDependencies);
-
-      if ((methodOverrides.size() > 0) || (methodDependencies.size() > 0)
-          || (methodAliases.size() > 0)) {
-        curLine = "</method>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-      }
-    }
-
-    if (methods.size() > 0) {
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-    }
-  }
-
-  private void emitOverrides(HtmlTextOutput htmlOut, String curLine,
-      ClassMember classMember) {
-    htmlOut.printRaw(curLine);
-    htmlOut.newline();
-    Set<ClassMember> overrides = classMember.getOverrides();
-    if (overrides.size() > 0) {
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-
-      curLine = "<override>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-    }
-    for (ClassMember overrideClassMember : overrides) {
-      curLine = "<of idref=\"" + overrideClassMember.getSourceName() + "\"/>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-    }
-    if (overrides.size() > 0) {
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-
-      curLine = "</override>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-    }
-  }
-
-  private void emitPackages(CompilationAnalysis report, HtmlTextOutput htmlOut,
-      SortedMap<String, Set<ClassMember>> packageToClasses) {
-
-    String curLine;
-    for (ClassMember classMember : report.getClasses()) {
-      String packageName = classMember.getPackage();
-      if (packageToClasses.containsKey(packageName)) {
-        packageToClasses.get(packageName).add(classMember);
-      } else {
-        Set<ClassMember> insertSet = new HashSet<ClassMember>();
-        insertSet.add(classMember);
-        packageToClasses.put(packageName, insertSet);
-      }
-    }
-
-    for (String packageName : packageToClasses.keySet()) {
-
-      curLine = "<package id=\"" + packageName + "\">";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-
-      if (packageToClasses.get(packageName).size() > 0) {
-        htmlOut.indentIn();
-        htmlOut.indentIn();
-      }
-      emitClasses(htmlOut, packageToClasses, packageName);
-      if (packageToClasses.get(packageName).size() > 0) {
-        htmlOut.indentOut();
-        htmlOut.indentOut();
-      }
-
-      curLine = "</package>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-    }
-  }
-
-  private SyntheticArtifact emitReport(TreeLogger logger,
-      CompilationAnalysis report, String partialPath, boolean compress)
-      throws UnableToCompleteException, IOException {
-
-    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-    OutputStreamWriter out;
-    try {
-      out = new OutputStreamWriter(compress ? new GZIPOutputStream(bytes)
-          : bytes);
-    } catch (IOException e) {
-      logger.log(TreeLogger.ERROR, "Unable to set up gzip stream", e);
-      throw new UnableToCompleteException();
-    }
-    PrintWriter pw = new PrintWriter(out);
-    HtmlTextOutput htmlOut = new HtmlTextOutput(pw, false);
-
-    String curLine = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
-    htmlOut.printRaw(curLine);
-    htmlOut.newline();
-    curLine = "<soyc>";
-    htmlOut.printRaw(curLine);
-    htmlOut.newline();
-    htmlOut.indentIn();
-    htmlOut.indentIn();
-
-    Map<Integer, String> splitPointMap = new TreeMap<Integer, String>(
-        report.getSplitPointMap());
-    if (splitPointMap.size() > 0) {
-      curLine = "<splitpoints>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-      for (Integer splitPointCount : splitPointMap.keySet()) {
-        curLine = "<splitpoint id=\"" + splitPointCount + "\" location=\""
-            + splitPointMap.get(splitPointCount) + "\"/>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-      }
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-      curLine = "</splitpoints>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-    }
-
-    emitMembers(report, htmlOut);
-    Map<Story, Integer> storyIds = emitStories(report, htmlOut);
-    emitJs(report, htmlOut, storyIds);
-
-    htmlOut.indentOut();
-    htmlOut.indentOut();
-    curLine = "</soyc>";
-    htmlOut.printRaw(curLine);
-    htmlOut.newline();
-
-    pw.close();
-    Utility.close(out);
-    SyntheticArtifact toReturn = emitBytes(logger, bytes.toByteArray(),
-        partialPath);
-
-    return toReturn;
-  }
-
-  private Map<Story, Integer> emitStories(CompilationAnalysis report,
-      HtmlTextOutput htmlOut) {
-
-    String curLine;
-    Map<Story, Integer> storyIds = new HashMap<Story, Integer>();
-    Set<Story> stories = report.getStories();
-    curLine = "<stories>";
-    htmlOut.printRaw(curLine);
-    htmlOut.newline();
-
-    if (stories.size() > 0) {
-      htmlOut.indentIn();
-      htmlOut.indentIn();
-    }
-    for (Story story : stories) {
-
-      int storyNum = storyIds.size();
-      storyIds.put(story, storyNum);
-
-      curLine = "<story id=\"story" + Integer.toString(storyNum) + "\"";
-      if (story.getLiteralTypeName() != null) {
-        curLine = curLine + " literal=\"" + story.getLiteralTypeName() + "\"";
-      }
-      curLine = curLine + ">";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-
-      Set<Origin> origins = story.getSourceOrigin();
-      if (origins.size() > 0) {
-        htmlOut.indentIn();
-        htmlOut.indentIn();
-
-        curLine = "<origins>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-        htmlOut.indentIn();
-        htmlOut.indentIn();
-      }
-      for (Origin origin : origins) {
-        curLine = "<origin lineNumber=\""
-            + Integer.toString(origin.getLineNumber()) + "\" location=\""
-            + origin.getLocation() + "\"/>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-      }
-      if (origins.size() > 0) {
-        htmlOut.indentOut();
-        htmlOut.indentOut();
-
-        curLine = "</origins>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-
-        htmlOut.indentOut();
-        htmlOut.indentOut();
-      }
-
-      Set<Member> correlations = story.getMembers();
-      if (correlations.size() > 0) {
-        htmlOut.indentIn();
-        htmlOut.indentIn();
-
-        curLine = "<correlations>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-
-        htmlOut.indentIn();
-        htmlOut.indentIn();
-      }
-      for (Member correlation : correlations) {
-        curLine = "<by idref=\"" + correlation.getSourceName() + "\"/>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-      }
-      if (correlations.size() > 0) {
-        htmlOut.indentOut();
-        htmlOut.indentOut();
-
-        curLine = "</correlations>";
-        htmlOut.printRaw(curLine);
-        htmlOut.newline();
-
-        htmlOut.indentOut();
-        htmlOut.indentOut();
-      }
-
-      curLine = "</story>";
-      htmlOut.printRaw(curLine);
-      htmlOut.newline();
-    }
-    if (stories.size() > 0) {
-      htmlOut.indentOut();
-      htmlOut.indentOut();
-    }
-    curLine = "</stories>";
-    htmlOut.printRaw(curLine);
-    htmlOut.newline();
-
-    return storyIds;
-  }
-
-  private void initialize(TreeLogger logger) throws UnableToCompleteException {
-    logger = logger.branch(TreeLogger.SPAM, "Initializing");
-  }
-
-}
diff --git a/dev/core/src/com/google/gwt/dev/CompilePerms.java b/dev/core/src/com/google/gwt/dev/CompilePerms.java
index 5efa683..2bfe862 100644
--- a/dev/core/src/com/google/gwt/dev/CompilePerms.java
+++ b/dev/core/src/com/google/gwt/dev/CompilePerms.java
@@ -18,6 +18,7 @@
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.dev.CompileTaskRunner.CompileTask;
+import com.google.gwt.dev.GWTCompiler.GWTCompilerOptionsImpl;
 import com.google.gwt.dev.jjs.JavaToJavaScriptCompiler;
 import com.google.gwt.dev.jjs.UnifiedAst;
 import com.google.gwt.dev.util.FileBackedObject;
@@ -182,7 +183,7 @@
       Permutation permutation, UnifiedAst unifiedAst)
       throws UnableToCompleteException {
     return JavaToJavaScriptCompiler.compilePermutation(logger, unifiedAst,
-        permutation.getRebindAnswers());
+        permutation.getRebindAnswers(), permutation.getId());
   }
 
   /**
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java b/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
index 050e236..cf8fea0 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
@@ -22,11 +22,12 @@
 import com.google.gwt.dev.util.arg.OptionRunAsyncEnabled;
 import com.google.gwt.dev.util.arg.OptionScriptStyle;
 import com.google.gwt.dev.util.arg.OptionSoycEnabled;
+import com.google.gwt.dev.util.arg.OptionWorkDir;
 
 /**
  * Controls options for the {@link JavaToJavaScriptCompiler}.
  */
 public interface JJSOptions extends OptionAggressivelyOptimize,
     OptionDisableClassMetadata, OptionDraftCompile, OptionEnableAssertions,
-    OptionRunAsyncEnabled, OptionScriptStyle, OptionSoycEnabled {
+    OptionRunAsyncEnabled, OptionScriptStyle, OptionSoycEnabled, OptionWorkDir {
 }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java b/dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java
index 5403614..cb1f9dd 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.dev.jjs;
 
+import java.io.File;
 import java.io.Serializable;
 
 /**
@@ -29,6 +30,7 @@
   private JsOutputOption output = JsOutputOption.OBFUSCATED;
   private boolean runAsyncEnabled = true;
   private boolean soycEnabled = false;
+  private File workDir;
 
   public JJSOptionsImpl() {
   }
@@ -45,12 +47,17 @@
     setOutput(other.getOutput());
     setRunAsyncEnabled(other.isRunAsyncEnabled());
     setSoycEnabled(other.isSoycEnabled());
+    setWorkDir(other.getWorkDir());
   }
 
   public JsOutputOption getOutput() {
     return output;
   }
 
+  public File getWorkDir() {
+    return workDir;
+  }
+
   public boolean isAggressivelyOptimize() {
     return aggressivelyOptimize;
   }
@@ -102,4 +109,8 @@
   public void setSoycEnabled(boolean enabled) {
     soycEnabled = enabled;
   }
+  
+  public void setWorkDir(File workDir){
+    this.workDir = workDir;
+  }
 }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index b5e1739..edadbb8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -20,6 +20,11 @@
 import com.google.gwt.core.ext.linker.ArtifactSet;
 import com.google.gwt.core.ext.linker.impl.StandardCompilationAnalysis;
 import com.google.gwt.core.ext.soyc.Range;
+import com.google.gwt.core.ext.soyc.SplitPointRecorder;
+import com.google.gwt.core.ext.soyc.StoryRecorder;
+import com.google.gwt.core.ext.soyc.impl.DependencyRecorderImpl;
+import com.google.gwt.core.ext.soyc.impl.SplitPointRecorderImpl;
+import com.google.gwt.core.ext.soyc.impl.StoryRecorderImpl;
 import com.google.gwt.dev.PermutationResult;
 import com.google.gwt.dev.jdt.RebindPermutationOracle;
 import com.google.gwt.dev.jdt.WebModeCompilerFrontEnd;
@@ -94,6 +99,7 @@
 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -148,8 +154,8 @@
    *           {@link OutOfMemoryError} occurs
    */
   public static PermutationResult compilePermutation(TreeLogger logger,
-      UnifiedAst unifiedAst, Map<String, String> rebindAnswers)
-      throws UnableToCompleteException {
+      UnifiedAst unifiedAst, Map<String, String> rebindAnswers,
+      int permutationId) throws UnableToCompleteException {
     try {
       if (JProgram.isTracingEnabled()) {
         System.out.println("------------------------------------------------------------");
@@ -276,11 +282,20 @@
 
       PermutationResult toReturn = new PermutationResultImpl(js, symbolMap);
       if (sourceInfoMaps != null) {
-        toReturn.getArtifacts().add(
-            new StandardCompilationAnalysis(logger, sourceInfoMaps,
-                jprogram.getSplitPointMap()));
-      }
 
+        // get method dependencies
+        DependencyRecorderImpl dr = new DependencyRecorderImpl();
+        File depFile = dr.recordDependencies(jprogram, options.getWorkDir(), permutationId, logger);
+        
+        StoryRecorder sr = new StoryRecorderImpl();
+        File storyFile = sr.recordStories(jprogram, options.getWorkDir(), permutationId, logger, sourceInfoMaps, js);
+        
+        SplitPointRecorder spr = new SplitPointRecorderImpl();
+        File splitPointsFile = spr.recordSplitPoints(jprogram, options.getWorkDir(), permutationId, logger);
+        
+        toReturn.getArtifacts().add(
+            new StandardCompilationAnalysis(logger, depFile, storyFile, splitPointsFile));
+      }    
       return toReturn;
     } catch (Throwable e) {
       throw logAndTranslateException(logger, e);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java b/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java
index 246a0a2..e9a47f4 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/SourceInfo.java
@@ -23,6 +23,7 @@
 import java.util.EnumMap;
 import java.util.EnumSet;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
@@ -32,32 +33,6 @@
 public class SourceInfo implements Serializable {
 
   /**
-   * Describes how the SourceInfo's node was mutated during the compile cycle.
-   */
-  public static final class Mutation implements Serializable {
-    private final String caller;
-    private final String description;
-    private final long ts = System.currentTimeMillis();
-
-    private Mutation(String description, String caller) {
-      this.caller = caller;
-      this.description = description;
-    }
-
-    public String getCaller() {
-      return caller;
-    }
-
-    public String getDescription() {
-      return description;
-    }
-
-    public long getTimestamp() {
-      return ts;
-    }
-  }
-
-  /**
    * A totally-immutable version of SourceInfo.
    */
   protected static class Immutable extends SourceInfo {
@@ -98,13 +73,6 @@
       "Unknown source", true);
 
   /**
-   * Collecting mutation data is expensive in terms of additional objects and
-   * string literals and only of interest to compiler hackers, so we'll just
-   * normally have it disabled.
-   */
-  private static final boolean COLLECT_MUTATIONS = Boolean.getBoolean("gwt.soyc.collectMutations");
-
-  /**
    * Micro-opt for {@link #makeChild(Class, String)}.
    */
   private static final SourceInfo[] EMPTY_SOURCEINFO_ARRAY = new SourceInfo[0];
@@ -117,13 +85,7 @@
   /**
    * Any Correlation associated with the SourceInfo.
    */
-  private final Set<Correlation> allCorrelations;
-
-  /**
-   * Holds Mutation objects if the compiler is configured to collect mutations.
-   */
-  private final List<Mutation> mutations = COLLECT_MUTATIONS
-      ? new ArrayList<Mutation>() : null;
+  private final List<Correlation> allCorrelations;
 
   /**
    * Holds the origin data for the SourceInfo.
@@ -144,41 +106,40 @@
 
     // Be very aggressive in not allocating collections that we don't need.
     if (accumulateData) {
-      allCorrelations = new HashSet<Correlation>();
+      allCorrelations = new ArrayList<Correlation>();
       primaryCorrelations = new EnumMap<Axis, Correlation>(Axis.class);
-      // Don't use addCorrelation because of the immutable subclasses
-      Correlation originCorrelation = Correlation.by(origin);
-      allCorrelations.add(originCorrelation);
-      primaryCorrelations.put(Axis.ORIGIN, originCorrelation);
     } else {
       allCorrelations = null;
       primaryCorrelations = null;
     }
   }
 
+  private boolean isAlreadyInAllCorrelations(Correlation c) {
+    //make sure this correlations is not yet in the allCorrelations list
+    boolean alreadyThere = false;
+    Iterator<Correlation> it = allCorrelations.iterator();
+    while((alreadyThere == false)&&(it.hasNext())){
+      if (it.next().equals(c)){
+        alreadyThere = true;
+      }
+    }
+    return alreadyThere;
+  }
+
   private SourceInfo(SourceInfo parent, String mutation, String caller,
       SourceInfo... additionalAncestors) {
     assert parent != null;
-    assert mutation != null;
     assert caller != null;
-
     this.accumulateData = parent.accumulateData;
     this.origin = parent.origin;
-
     if (accumulateData) {
-      this.allCorrelations = new HashSet<Correlation>(parent.allCorrelations);
+      this.allCorrelations = new ArrayList<Correlation>(parent.allCorrelations);
       this.primaryCorrelations = new EnumMap<Axis, Correlation>(
           parent.primaryCorrelations);
     } else {
       allCorrelations = null;
       primaryCorrelations = null;
     }
-
-    if (COLLECT_MUTATIONS) {
-      this.mutations.addAll(parent.mutations);
-      this.mutations.add(new Mutation(mutation, caller));
-    }
-
     merge(additionalAncestors);
   }
 
@@ -189,9 +150,9 @@
     if (!accumulateData) {
       return;
     }
-
-    allCorrelations.add(c);
-
+    if (! isAlreadyInAllCorrelations(c)){
+      allCorrelations.add(c);
+    }    
     if (!primaryCorrelations.containsKey(c.getAxis())) {
       primaryCorrelations.put(c.getAxis(), c);
     }
@@ -222,21 +183,24 @@
    * Returns all Correlations applied to this SourceInfo, its parent, additional
    * ancestor SourceInfo, and any supertype SourceInfos.
    */
-  public Set<Correlation> getAllCorrelations() {
-    return accumulateData ? allCorrelations
-        : Collections.<Correlation> emptySet();
+  public List<Correlation> getAllCorrelations() {
+    if (accumulateData){
+      return allCorrelations;
+    }
+    else{
+      return Collections.<Correlation> emptyList();
+    }
   }
 
   /**
    * Returns all Correlations along a given axis applied to this SourceInfo, its
    * parent, additional ancestor SourceInfo, and any supertype SourceInfos.
    */
-  public Set<Correlation> getAllCorrelations(Axis axis) {
+  public List<Correlation> getAllCorrelations(Axis axis) {
     if (!accumulateData) {
-      return Collections.emptySet();
+      return Collections.emptyList();
     }
-
-    Set<Correlation> toReturn = new HashSet<Correlation>();
+    List<Correlation> toReturn = new ArrayList<Correlation>();
     for (Correlation c : getAllCorrelations()) {
       if (c.getAxis() == axis) {
         toReturn.add(c);
@@ -253,20 +217,6 @@
     return getOrigin().getFileName();
   }
 
-  /**
-   * Returns a summary of the mutations applied to the SourceInfo. It it
-   * expensive to collect mutation data, so this method will only return useful
-   * values if the <code>gwt.jjs.collectMutations</code> system property is
-   * defined.
-   */
-  public List<Mutation> getMutations() {
-    if (COLLECT_MUTATIONS) {
-      return mutations;
-    } else {
-      return Collections.emptyList();
-    }
-  }
-
   public SourceOrigin getOrigin() {
     return origin;
   }
@@ -338,7 +288,11 @@
         continue;
       }
 
-      allCorrelations.addAll(info.getAllCorrelations());
+      for (Correlation c : info.getAllCorrelations()){
+        if (! isAlreadyInAllCorrelations(c)){
+          allCorrelations.add(c);
+        }
+      }
 
       if (primaryCorrelations.size() < Axis.values().length) {
         EnumMap<Axis, Correlation> copy = new EnumMap<Axis, Correlation>(
@@ -346,10 +300,6 @@
         copy.keySet().removeAll(primaryCorrelations.keySet());
         primaryCorrelations.putAll(copy);
       }
-
-      if (COLLECT_MUTATIONS) {
-        mutations.addAll(0, info.getMutations());
-      }
     }
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
index f2868c3..eb09959 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
@@ -68,6 +68,18 @@
  * execution at a specified location.
  */
 public class ControlFlowAnalyzer {
+  /**
+   * A callback for recording control-flow dependencies as they are discovered.
+   * See {@link ControlFlowAnalyzer#setDependencyRecorder(DependencyRecorder)}.
+   */
+  public interface DependencyRecorder {
+
+    /**
+     * Used to record the dependencies of a specific method
+     */
+    void methodIsLiveBecause(JMethod liveMethod,
+        ArrayList<JMethod> dependencyChain);
+  }
 
   /**
    * Marks as "referenced" any types, methods, and fields that are reachable.
@@ -77,6 +89,8 @@
    * TODO(later): make RescueVisitor use less stack?
    */
   private class RescueVisitor extends JVisitor {
+    private ArrayList<JMethod> curMethodStack = new ArrayList<JMethod>();
+
     @Override
     public boolean visit(JArrayType type, Context ctx) {
       assert (referencedTypes.contains(type));
@@ -477,9 +491,14 @@
         if (!liveFieldsAndMethods.contains(method)) {
           liveFieldsAndMethods.add(method);
           methodsLiveExceptForInstantiability.remove(method);
-
+          if (dependencyRecorder != null) {
+            curMethodStack.add(method);
+            dependencyRecorder.methodIsLiveBecause(method, curMethodStack);
+          }
           accept(method);
-
+          if (dependencyRecorder != null) {
+            curMethodStack.remove(curMethodStack.size() - 1);
+          }
           if (method.isNative()) {
             /*
              * SPECIAL: returning from this method passes a value from
@@ -487,9 +506,7 @@
              */
             maybeRescueJavaScriptObjectPassingIntoJava(method.getType());
           }
-
           rescueOverridingMethods(method);
-
           return true;
         }
       }
@@ -638,6 +655,8 @@
     }
   }
 
+  private DependencyRecorder dependencyRecorder;
+
   private Set<JField> fieldsWritten = new HashSet<JField>();
   private Set<JReferenceType> instantiatedTypes = new HashSet<JReferenceType>();
   private Set<JNode> liveFieldsAndMethods = new HashSet<JNode>();
@@ -714,6 +733,18 @@
   }
 
   /**
+   * Specify the {@link DependencyRecorder} to be used for future traversals.
+   * Specifying <code>null</code> means to stop recording dependencies.
+   */
+  public void setDependencyRecorder(DependencyRecorder dr) {
+    if (dependencyRecorder != null && dr != null) {
+      throw new IllegalArgumentException(
+          "Attempting to set multiple dependency recorders");
+    }
+    this.dependencyRecorder = dr;
+  }
+
+  /**
    * Traverse all code executed by <code>expr</code>.
    */
   public void traverseFrom(JExpression expr) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index 079e17f..b9c5310 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -163,7 +163,6 @@
       String mangleName = mangleName(x);
       if (x.isStatic()) {
         JsName jsName = topScope.declareName(mangleName, name);
-        x.getSourceInfo().addCorrelation(Correlation.by(jsName));
         names.put(x, jsName);
         recordSymbol(x, jsName);
       } else {
@@ -177,7 +176,6 @@
         } else {
           jsName = peek().declareName(mangleName, name);
         }
-        x.getSourceInfo().addCorrelation(Correlation.by(jsName));
         names.put(x, jsName);
         recordSymbol(x, jsName);
       }
@@ -245,7 +243,6 @@
 
       // My seed function name
       JsName jsName = topScope.declareName(getNameString(x), x.getShortName());
-      x.getSourceInfo().addCorrelation(Correlation.by(jsName));
       names.put(x, jsName);
       recordSymbol(x, jsName);
 
@@ -331,7 +328,6 @@
         jsFunction = new JsFunction(sourceInfo, topScope, globalName, true);
       }
       methodBodyMap.put(x.getBody(), jsFunction);
-      jsFunction.getSourceInfo().addCorrelation(Correlation.by(jsFunction));
       jsFunction.getSourceInfo().addCorrelation(Correlation.by(globalName));
       push(jsFunction.getScope());
       return true;
@@ -1399,7 +1395,6 @@
       gwtOnLoadName.setObfuscatable(false);
       JsFunction gwtOnLoad = new JsFunction(sourceInfo, topScope,
           gwtOnLoadName, true);
-      sourceInfo.addCorrelation(Correlation.by(gwtOnLoad));
       globalStmts.add(gwtOnLoad.makeStmt());
       JsBlock body = new JsBlock(sourceInfo);
       gwtOnLoad.setBody(body);
@@ -1461,7 +1456,6 @@
           GenerateJavaScriptAST.class, "Null function");
       JsFunction nullFunc = new JsFunction(sourceInfo, topScope,
           nullMethodName, true);
-      sourceInfo.addCorrelation(Correlation.by(nullFunc));
       nullFunc.setBody(new JsBlock(sourceInfo));
       globalStatements.add(nullFunc.makeStmt());
     }
@@ -1478,7 +1472,6 @@
         JsFunction seedFunc = new JsFunction(sourceInfo, topScope,
             seedFuncName, true);
         seedFuncName.setStaticRef(seedFunc);
-        sourceInfo.addCorrelation(Correlation.by(seedFunc));
         JsBlock body = new JsBlock(sourceInfo);
         seedFunc.setBody(body);
         JsExprStmt seedFuncStmt = seedFunc.makeStmt();
diff --git a/tools/soyc-vis/src/com/google/gwt/soyc/CodeCollection.java b/tools/soyc-vis/src/com/google/gwt/soyc/CodeCollection.java
index 655b516..27ae797 100644
--- a/tools/soyc-vis/src/com/google/gwt/soyc/CodeCollection.java
+++ b/tools/soyc-vis/src/com/google/gwt/soyc/CodeCollection.java
@@ -19,41 +19,40 @@
 import java.util.TreeSet;
 
 public class CodeCollection {
-  
+
   public String codeType = "";
   public TreeSet<String> classes = new TreeSet<String>();
   public TreeSet<String> stories = new TreeSet<String>();
   public float cumPartialSize = 0f;
   public int cumSize = 0;
-  
-  
-  public CodeCollection(String type){
+
+  public CodeCollection(String type) {
     codeType = type;
   }
-  
-  public int getCumSize(){
+
+  public int getCumSize() {
     cumSize = 0;
-    for (String className : classes){
-      if (! GlobalInformation.classToSize.containsKey(className)){
-        System.err.println("*** NO SIZE FOUND FOR CLASS " + className + " *****");
-      }
-      else{
+    for (String className : classes) {
+      if (!GlobalInformation.classToSize.containsKey(className)) {
+        System.err.println("*** NO SIZE FOUND FOR CLASS " + className
+            + " *****");
+      } else {
         cumSize += GlobalInformation.classToSize.get(className);
       }
     }
     return cumSize;
- }
-  
-  public float getCumPartialSize(){
+  }
+
+  public float getCumPartialSize() {
     cumPartialSize = 0f;
-    for (String className : classes){
-      if (!GlobalInformation.classToPartialSize.containsKey(className)){
-        System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className + " *****");
-      }
-      else{
+    for (String className : classes) {
+      if (!GlobalInformation.classToPartialSize.containsKey(className)) {
+        System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className
+            + " *****");
+      } else {
         cumPartialSize += GlobalInformation.classToPartialSize.get(className);
       }
     }
     return cumPartialSize;
- }
+  }
 }
diff --git a/tools/soyc-vis/src/com/google/gwt/soyc/GlobalInformation.java b/tools/soyc-vis/src/com/google/gwt/soyc/GlobalInformation.java
index bdba9be..bc2c418 100644
--- a/tools/soyc-vis/src/com/google/gwt/soyc/GlobalInformation.java
+++ b/tools/soyc-vis/src/com/google/gwt/soyc/GlobalInformation.java
@@ -14,7 +14,6 @@
  * the License.
  */
 
-
 package com.google.gwt.soyc;
 
 import java.util.HashMap;
@@ -23,25 +22,25 @@
 import java.util.TreeSet;
 
 public class GlobalInformation {
-  
+
   public static Boolean displayDependencies = false;
-  
+  public static Boolean displaySplitPoints = false;
+
   public static int allOtherFragmentsPartialSize = 0;
   public static HashMap<String, String> classToPackage = new HashMap<String, String>();
   public static HashMap<String, Float> classToPartialSize = new HashMap<String, Float>();
   public static HashMap<String, Integer> classToSize = new HashMap<String, Integer>();
-  //TODO(kprobst): not currently used, but will be for dependencies
   public static HashMap<String, HashSet<String>> classToWhatItDependsOn = new HashMap<String, HashSet<String>>();
   public static float cumPartialSizeFromPackages = 0f;
-  public static int cumSizeAllCode  = 0;
+  public static int cumSizeAllCode = 0;
   public static int cumSizeFromPackages = 0;
   public static int cumSizeInitialFragment = 0;
-  public static HashMap<Integer, Float> fragmentToPartialSize = new HashMap<Integer, Float>(); //collect only size for exclusive fragments
+  // collect only size for exclusive fragments 
+  public static HashMap<Integer, Float> fragmentToPartialSize = new HashMap<Integer, Float>(); 
   public static HashMap<Integer, HashSet<String>> fragmentToStories = new HashMap<Integer, HashSet<String>>();
   public static TreeMap<String, LiteralsCollection> nameToLitColl = new TreeMap<String, LiteralsCollection>();
   public static HashMap<String, CodeCollection> nameToCodeColl = new HashMap<String, CodeCollection>();
 
-
   public static int nonAttributedBytes = 0;
   public static HashSet<String> nonAttributedStories = new HashSet<String>();
   public static int numBytesDoubleCounted = 0;
@@ -53,19 +52,19 @@
   public static HashMap<Integer, String> splitPointToLocation = new HashMap<Integer, String>();
   public static HashMap<String, HashSet<String>> storiesToCorrClasses = new HashMap<String, HashSet<String>>();
   public static HashMap<String, HashSet<String>> storiesToCorrClassesAndMethods = new HashMap<String, HashSet<String>>();
-  
+
   public static HashMap<String, String> storiesToLitType = new HashMap<String, String>();
-  
-  public static void computePackageSizes(){
+
+  public static void computePackageSizes() {
     cumSizeFromPackages = 0;
     packageToSize.clear();
-    for (String packageName : packageToClasses.keySet()){
+    for (String packageName : packageToClasses.keySet()) {
       packageToSize.put(packageName, 0);
-      for (String className : packageToClasses.get(packageName)){
-        if (! classToSize.containsKey(className)){
-          System.err.println("*** NO  SIZE FOUND FOR CLASS " + className + " *****");
-        }
-        else{
+      for (String className : packageToClasses.get(packageName)) {
+        if (!classToSize.containsKey(className)) {
+          System.err.println("*** NO  SIZE FOUND FOR CLASS " + className
+              + " *****");
+        } else {
           int curSize = classToSize.get(className);
           cumSizeFromPackages += curSize;
           int newSize = curSize + packageToSize.get(packageName);
@@ -74,16 +73,17 @@
       }
     }
   }
-  public static void computePartialPackageSizes(){
+
+  public static void computePartialPackageSizes() {
     cumPartialSizeFromPackages = 0;
     packageToPartialSize.clear();
-    for (String packageName : packageToClasses.keySet()){
+    for (String packageName : packageToClasses.keySet()) {
       packageToPartialSize.put(packageName, 0f);
-      for (String className : packageToClasses.get(packageName)){
-        if (! classToPartialSize.containsKey(className)){
-          System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className + " *****");
-        }
-        else{
+      for (String className : packageToClasses.get(packageName)) {
+        if (!classToPartialSize.containsKey(className)) {
+          System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className
+              + " *****");
+        } else {
           float curSize = classToPartialSize.get(className);
           cumPartialSizeFromPackages += curSize;
           float newSize = curSize + packageToPartialSize.get(packageName);
diff --git a/tools/soyc-vis/src/com/google/gwt/soyc/MakeTopLevelHtmlForPerm.java b/tools/soyc-vis/src/com/google/gwt/soyc/MakeTopLevelHtmlForPerm.java
index 7712e0b..8a3669f 100644
--- a/tools/soyc-vis/src/com/google/gwt/soyc/MakeTopLevelHtmlForPerm.java
+++ b/tools/soyc-vis/src/com/google/gwt/soyc/MakeTopLevelHtmlForPerm.java
@@ -26,7 +26,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.TreeSet;
@@ -35,23 +34,24 @@
 import java.util.jar.JarInputStream;
 
 public class MakeTopLevelHtmlForPerm {
-  
-  private static void makePackageHtml(String outFileName) throws IOException{
-    
-    
-    TreeMap<Float, String> sortedPackages = new TreeMap<Float, String>(Collections.reverseOrder());
+
+  private static void makePackageHtml(String outFileName) throws IOException {
+
+    TreeMap<Float, String> sortedPackages = new TreeMap<Float, String>(
+        Collections.reverseOrder());
     float maxSize = 0f;
     float sumSize = 0f;
-    for (String packageName : GlobalInformation.packageToPartialSize.keySet()){
-      sortedPackages.put(GlobalInformation.packageToPartialSize.get(packageName), packageName);
+    for (String packageName : GlobalInformation.packageToPartialSize.keySet()) {
+      sortedPackages.put(
+          GlobalInformation.packageToPartialSize.get(packageName), packageName);
       sumSize += GlobalInformation.packageToPartialSize.get(packageName);
-      if (GlobalInformation.packageToPartialSize.get(packageName) > maxSize){
+      if (GlobalInformation.packageToPartialSize.get(packageName) > maxSize) {
         maxSize = GlobalInformation.packageToPartialSize.get(packageName);
       }
     }
-    
+
     final PrintWriter outFile = new PrintWriter(outFileName);
-    
+
     outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
     outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
     outFile.println("<html>");
@@ -63,20 +63,21 @@
     outFile.println("<body>");
 
     int yOffset = 0;
-    for (Float size : sortedPackages.keySet()){
-      
+    for (Float size : sortedPackages.keySet()) {
+
       String packageName = sortedPackages.get(size);
       String drillDownFileName = packageName + "Classes.html";
-      
+
       float ratio = (size / maxSize) * 79;
-      
-      if (ratio < 3){
+
+      if (ratio < 3) {
         ratio = 3;
       }
 
       float perc = (size / sumSize) * 100;
-      
-      outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 110px;\">");
+
+      outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: "
+          + yOffset + "px; left: 110px;\">");
       outFile.println("<div id=\"lb\">");
       outFile.println("<div id=\"rb\">");
       outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -86,66 +87,64 @@
       outFile.println("</div></div></div></div>");
       outFile.println("</div></div></div></div>");
       outFile.println("</div>");
-      
-      int yOffsetText = yOffset+8;
-      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
-      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:70px;\">%.1f", perc);
+
+      int yOffsetText = yOffset + 8;
+      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+          + "px; left:5px;\">%.1f</div>\n", size);
+      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+          + "px; left:70px;\">%.1f", perc);
       outFile.println("%</div>\n");
-      outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:110px;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">"+packageName+"</a></div>");
-      
+      outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+          + "px; left:110px;\"><a href=\"" + drillDownFileName
+          + "\" target=\"_top\">" + packageName + "</a></div>");
+
       yOffset = yOffset + 25;
 
     }
     outFile.println("</body>");
     outFile.println("</html>");
     outFile.close();
-    
+
   }
-  
-  private static void makeFragmentsHtml(String outFileName) throws IOException{
-    
-    // TreeMap<Float, Integer> sortedFragments = new TreeMap<Float, Integer>(Collections.reverseOrder());
-    TreeMap<Float, String> sortedSplitPoints = new TreeMap<Float, String>(Collections.reverseOrder());
+
+  private static void makeFragmentsHtml(String outFileName) throws IOException {
+
+    // TreeMap<Float, Integer> sortedFragments = new TreeMap<Float,
+    // Integer>(Collections.reverseOrder());
+    TreeMap<Float, String> sortedSplitPoints = new TreeMap<Float, String>(
+        Collections.reverseOrder());
     float maxSize = 0f;
     float sumSize = 0f;
-    
+
     // initial fragment
     float initialSize = GlobalInformation.fragmentToPartialSize.get(0);
     sumSize += initialSize;
     maxSize = initialSize;
     sortedSplitPoints.put(initialSize, "initialDownload");
-    
+
     // all fragments that are not in the initial load order
     float allOtherFragmentsSize = GlobalInformation.allOtherFragmentsPartialSize;
     sumSize += allOtherFragmentsSize;
-    if (allOtherFragmentsSize > maxSize){
+    if (allOtherFragmentsSize > maxSize) {
       maxSize = allOtherFragmentsSize;
     }
     sortedSplitPoints.put(allOtherFragmentsSize, "allOtherFragments");
-    
+
     // all exclusive fragments
     System.out.println("");
-    for (Integer splitPointId : GlobalInformation.splitPointToLocation.keySet()){
+    for (Integer splitPointId : GlobalInformation.splitPointToLocation.keySet()) {
       System.out.println("splitPointId is: " + splitPointId);
       Float sizeOfCurExclusiveFrag = GlobalInformation.fragmentToPartialSize.get(splitPointId);
-      sortedSplitPoints.put(sizeOfCurExclusiveFrag, GlobalInformation.splitPointToLocation.get(splitPointId));
+      sortedSplitPoints.put(sizeOfCurExclusiveFrag,
+          GlobalInformation.splitPointToLocation.get(splitPointId));
       sumSize += sizeOfCurExclusiveFrag;
-      if (sizeOfCurExclusiveFrag > maxSize){
+      if (sizeOfCurExclusiveFrag > maxSize) {
         maxSize = sizeOfCurExclusiveFrag;
       }
     }
-    
-    
-/*    for (Integer fragmentName : GlobalInformation.fragmentToPartialSize.keySet()){
-      sortedFragments.put(GlobalInformation.fragmentToPartialSize.get(fragmentName), fragmentName);
-      sumSize += GlobalInformation.fragmentToPartialSize.get(fragmentName);
-      if (GlobalInformation.fragmentToPartialSize.get(fragmentName) > maxSize){
-        maxSize = GlobalInformation.fragmentToPartialSize.get(fragmentName);
-      }
-    }*/
-    
+
     final PrintWriter outFile = new PrintWriter(outFileName);
-    
+
     outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
     outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
     outFile.println("<html>");
@@ -156,23 +155,18 @@
     outFile.println("<body>");
 
     int yOffset = 0;
-    //for (Float size : sortedFragments.keySet()){
-    for (Float size : sortedSplitPoints.keySet()){
-    
-      // Integer fragmentName = sortedFragments.get(size);
+    for (Float size : sortedSplitPoints.keySet()) {
       String splitPointName = sortedSplitPoints.get(size);
-      // String drillDownFileName = "fragment" + Integer.toString(fragmentName) + "Classes.html";
       String drillDownFileName = "splitPoint" + splitPointName + "Classes.html";
-      
+
       float ratio = (size / maxSize) * 79;
-      
-      if (ratio < 3){
+      if (ratio < 3) {
         ratio = 3;
       }
-
       float perc = (size / sumSize) * 100;
-      
-      outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 110px;\">");
+
+      outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: "
+          + yOffset + "px; left: 110px;\">");
       outFile.println("<div id=\"lb\">");
       outFile.println("<div id=\"rb\">");
       outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -182,45 +176,50 @@
       outFile.println("</div></div></div></div>");
       outFile.println("</div></div></div></div>");
       outFile.println("</div>");
-      
-      int yOffsetText = yOffset+8;
-      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
-      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:80px;\">%.1f", perc);
+
+      int yOffsetText = yOffset + 8;
+      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+          + "px; left:5px;\">%.1f</div>\n", size);
+      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+          + "px; left:80px;\">%.1f", perc);
       outFile.println("%</div>\n");
-      // outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:120px;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">fragment"+ Integer.toString(fragmentName) +"</a></div>");
-      outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:120px;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">"+ splitPointName +"</a></div>");
-       
+      outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+          + "px; left:120px;\"><a href=\"" + drillDownFileName
+          + "\" target=\"_top\">" + splitPointName + "</a></div>");
+
       yOffset = yOffset + 25;
 
     }
     outFile.println("</body>");
     outFile.println("</html>");
     outFile.close();
-    
+
   }
 
-  private static void makeCodeTypeHtml(String outFileName, HashMap<String, CodeCollection> nameToCodeColl) throws IOException{
-    
-    
+  private static void makeCodeTypeHtml(String outFileName,
+      HashMap<String, CodeCollection> nameToCodeColl) throws IOException {
+
     float maxSize = 0f;
     float sumSize = 0f;
-    TreeMap<Float, String> sortedCodeTypes = new TreeMap<Float, String>(Collections.reverseOrder());
-    
-    //TODO(kprobst): turn this into a multimap? com.google.common.collect.TreeMultimap
-    for (String codeType : nameToCodeColl.keySet()){
+    TreeMap<Float, String> sortedCodeTypes = new TreeMap<Float, String>(
+        Collections.reverseOrder());
+
+    // TODO(kprobst): turn this into a multimap?
+    // com.google.common.collect.TreeMultimap
+    for (String codeType : nameToCodeColl.keySet()) {
       float curSize = nameToCodeColl.get(codeType).getCumPartialSize();
       sumSize += curSize;
-      
-      if (curSize != 0f){
+
+      if (curSize != 0f) {
         sortedCodeTypes.put(curSize, codeType);
-        if (curSize > maxSize){
+        if (curSize > maxSize) {
           maxSize = curSize;
         }
       }
     }
-    
+
     final PrintWriter outFile = new PrintWriter(outFileName);
-    
+
     outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
     outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
     outFile.println("<html>");
@@ -231,19 +230,20 @@
     outFile.println("<body>");
 
     int yOffset = 0;
-    for (Float size : sortedCodeTypes.keySet()){
-      
+    for (Float size : sortedCodeTypes.keySet()) {
+
       String codeType = sortedCodeTypes.get(size);
       String drillDownFileName = codeType + "Classes.html";
-      
-      float ratio = (size / maxSize) * 79;    
+
+      float ratio = (size / maxSize) * 79;
       float perc = (size / sumSize) * 100;
-      
-      if (ratio < 3){
+
+      if (ratio < 3) {
         ratio = 3;
       }
 
-      outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 110px;\">");
+      outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: "
+          + yOffset + "px; left: 110px;\">");
       outFile.println("<div id=\"lb\">");
       outFile.println("<div id=\"rb\">");
       outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -253,46 +253,49 @@
       outFile.println("</div></div></div></div>");
       outFile.println("</div></div></div></div>");
       outFile.println("</div>");
-      
-      int yOffsetText = yOffset+8;
-      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
-      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:70px;\">%.1f", perc);
+
+      int yOffsetText = yOffset + 8;
+      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+          + "px; left:5px;\">%.1f</div>\n", size);
+      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+          + "px; left:70px;\">%.1f", perc);
       outFile.println("%</div>\n");
-      outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:110px;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">"+codeType+"</a></div>");
-      
+      outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+          + "px; left:110px;\"><a href=\"" + drillDownFileName
+          + "\" target=\"_top\">" + codeType + "</a></div>");
+
       yOffset = yOffset + 25;
 
     }
     outFile.println("</body>");
     outFile.println("</html>");
     outFile.close();
-    
-    
+
   }
-  
-  private static void makeLiteralsHtml(String outFileName, TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
-    
+
+  private static void makeLiteralsHtml(String outFileName,
+      TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
 
     float maxSize = 0f;
     float sumSize = 0f;
-    TreeMap<Float, String> sortedLitTypes = new TreeMap<Float, String>(Collections.reverseOrder());
- 
-    for (String literal : nameToLitColl.keySet()){
+    TreeMap<Float, String> sortedLitTypes = new TreeMap<Float, String>(
+        Collections.reverseOrder());
+
+    for (String literal : nameToLitColl.keySet()) {
       float curSize = nameToLitColl.get(literal).cumSize;
       sumSize += curSize;
-      
-      if (curSize != 0f){
+
+      if (curSize != 0f) {
         sortedLitTypes.put(curSize, literal);
-      
-        if (curSize > maxSize){
+
+        if (curSize > maxSize) {
           maxSize = curSize;
         }
       }
     }
 
-
     final PrintWriter outFile = new PrintWriter(outFileName);
-    
+
     outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
     outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
     outFile.println("<html>");
@@ -303,19 +306,20 @@
     outFile.println("<body>");
 
     int yOffset = 0;
-    for (Float size : sortedLitTypes.keySet()){
-      
+    for (Float size : sortedLitTypes.keySet()) {
+
       String literal = sortedLitTypes.get(size);
       String drillDownFileName = literal + "Lits.html";
-      
-      float ratio = (size / maxSize) * 79;   
+
+      float ratio = (size / maxSize) * 79;
       float perc = (size / sumSize) * 100;
-      
-      if (ratio < 3){
+
+      if (ratio < 3) {
         ratio = 3;
       }
-      
-      outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 110px;\">");
+
+      outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: "
+          + yOffset + "px; left: 110px;\">");
       outFile.println("<div id=\"lb\">");
       outFile.println("<div id=\"rb\">");
       outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -325,26 +329,31 @@
       outFile.println("</div></div></div></div>");
       outFile.println("</div></div></div></div>");
       outFile.println("</div>");
-      
-      int yOffsetText = yOffset+8;
-      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
-      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:70px;\">%.1f", perc);
+
+      int yOffsetText = yOffset + 8;
+      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+          + "px; left:5px;\">%.1f</div>\n", size);
+      outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+          + "px; left:70px;\">%.1f", perc);
       outFile.println("%</div>\n");
-      outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:110px;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">"+literal+"</a></div>");
-      
+      outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+          + "px; left:110px;\"><a href=\"" + drillDownFileName
+          + "\" target=\"_top\">" + literal + "</a></div>");
+
       yOffset = yOffset + 25;
 
     }
     outFile.println("</body>");
     outFile.println("</html>");
     outFile.close();
-    
+
   }
-  
-  private static void makeStringLiteralsHtml(String outFileName, TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
+
+  private static void makeStringLiteralsHtml(String outFileName,
+      TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
 
     final PrintWriter outFile = new PrintWriter(outFileName);
-    
+
     outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
     outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
     outFile.println("<html>");
@@ -353,42 +362,42 @@
     outFile.println("<link rel=\"stylesheet\" href=\"roundedCorners.css\" media=\"screen\">");
     outFile.println("</head>");
     outFile.println("<body>");
-    
-    
-    if (nameToLitColl.get("string").stringTypeToSize.size() > 0){
-      
+
+    if (nameToLitColl.get("string").stringTypeToSize.size() > 0) {
+
       float maxSize = 0f;
       float sumSize = 0f;
-      TreeMap<Float, String> sortedStLitTypes = new TreeMap<Float, String>(Collections.reverseOrder());
-      
-      for (String stringLiteral : nameToLitColl.get("string").stringTypeToSize.keySet()){
+      TreeMap<Float, String> sortedStLitTypes = new TreeMap<Float, String>(
+          Collections.reverseOrder());
+
+      for (String stringLiteral : nameToLitColl.get("string").stringTypeToSize.keySet()) {
         float curSize = nameToLitColl.get("string").stringTypeToSize.get(stringLiteral);
         sumSize += curSize;
-        
-        if (curSize != 0f){
+
+        if (curSize != 0f) {
           sortedStLitTypes.put(curSize, stringLiteral);
-          
-          if (curSize > maxSize){
+
+          if (curSize > maxSize) {
             maxSize = curSize;
           }
         }
       }
 
-  
       int yOffset = 0;
-      for (Float size : sortedStLitTypes.keySet()){
-        
+      for (Float size : sortedStLitTypes.keySet()) {
+
         String stringLiteral = sortedStLitTypes.get(size);
         String drillDownFileName = stringLiteral + "Strings.html";
-        
+
         float ratio = (size / maxSize) * 79;
         float perc = (size / sumSize) * 100;
-        
-        if (ratio < 3){
+
+        if (ratio < 3) {
           ratio = 3;
         }
-  
-        outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 110px;\">");
+
+        outFile.println("<div id=\"box\" style=\"width:" + ratio + "%; top: "
+            + yOffset + "px; left: 110px;\">");
         outFile.println("<div id=\"lb\">");
         outFile.println("<div id=\"rb\">");
         outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -398,82 +407,92 @@
         outFile.println("</div></div></div></div>");
         outFile.println("</div></div></div></div>");
         outFile.println("</div>");
-        
-        int yOffsetText = yOffset+8;
-        outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
-        outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:70px;\">%.1f", perc);
+
+        int yOffsetText = yOffset + 8;
+        outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+            + "px; left:5px;\">%.1f</div>\n", size);
+        outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+            + "px; left:70px;\">%.1f", perc);
         outFile.println("%</div>\n");
-        outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:110px;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">"+stringLiteral+"</a></div>");
-        
+        outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+            + "px; left:110px;\"><a href=\"" + drillDownFileName
+            + "\" target=\"_top\">" + stringLiteral + "</a></div>");
+
         yOffset = yOffset + 25;
-  
+
       }
-    
+
     }
-    
-    else{
+
+    else {
       outFile.println("No string literals found for this application.");
-      
+
     }
 
     outFile.println("</body>");
     outFile.println("</html>");
     outFile.close();
   }
-  
 
-  public static void copyFileOrDirectoryFromJar(String jarFileName, String inputFileName, File dstPath, boolean isDirectory) throws IOException{
+  public static void copyFileOrDirectoryFromJar(String jarFileName,
+      String inputFileName, File dstPath, boolean isDirectory)
+      throws IOException {
 
     JarFile jarFile = new JarFile(jarFileName);
-    if (isDirectory){
+    if (isDirectory) {
       dstPath.mkdir();
-      
-      JarInputStream jarFileIS = new JarInputStream(new FileInputStream(jarFileName));
+
+      JarInputStream jarFileIS = new JarInputStream(new FileInputStream(
+          jarFileName));
       JarEntry jarEntry = jarFileIS.getNextJarEntry();
-      while(jarEntry != null){
-        if (! inputFileName.endsWith("/")){
+      while (jarEntry != null) {
+        if (!inputFileName.endsWith("/")) {
           inputFileName += "/";
         }
-        if ((jarEntry.getName().compareTo(inputFileName) != 0)&&(jarEntry.getName().startsWith(inputFileName))){
-          File newDstPath = new File(jarEntry.getName());          
-          copyFileOrDirectoryFromJar(jarFileName, jarEntry.getName(), newDstPath, false);
-        } 
+        if ((jarEntry.getName().compareTo(inputFileName) != 0)
+            && (jarEntry.getName().startsWith(inputFileName))) {
+          File newDstPath = new File(jarEntry.getName());
+          copyFileOrDirectoryFromJar(jarFileName, jarEntry.getName(),
+              newDstPath, false);
+        }
         jarEntry = jarFileIS.getNextJarEntry();
       }
       jarFileIS.close();
     }
 
-    else{
+    else {
       InputStream in = jarFile.getInputStream(jarFile.getEntry(inputFileName));
-      OutputStream out = new FileOutputStream(dstPath); 
-      
+      OutputStream out = new FileOutputStream(dstPath);
+
       int c;
-      while ((c = in.read()) != -1){
-        out.write(c);          
+      while ((c = in.read()) != -1) {
+        out.write(c);
       }
       in.close();
       out.close();
       jarFile.close();
     }
   }
-  
-  public static void copyFileOrDirectory(File srcPath, File dstPath, String classPath, String inputFileName, boolean isDirectory) throws IOException{
-    if (srcPath.isDirectory()){
-      if (!dstPath.exists()){
+
+  public static void copyFileOrDirectory(File srcPath, File dstPath,
+      String classPath, String inputFileName, boolean isDirectory)
+      throws IOException {
+    if (srcPath.isDirectory()) {
+      if (!dstPath.exists()) {
         dstPath.mkdir();
-     }
-     String files[] = srcPath.list();
-     for(int i = 0; i < files.length; i++){
-        copyFileOrDirectory(new File(srcPath, files[i]), new File(dstPath, files[i]), classPath, inputFileName, isDirectory);
       }
-    }
-   else{
-      if(!srcPath.exists()){
-        copyFileOrDirectoryFromJar(classPath, inputFileName, dstPath, isDirectory);
-      }    
-      else{
+      String files[] = srcPath.list();
+      for (int i = 0; i < files.length; i++) {
+        copyFileOrDirectory(new File(srcPath, files[i]), new File(dstPath,
+            files[i]), classPath, inputFileName, isDirectory);
+      }
+    } else {
+      if (!srcPath.exists()) {
+        copyFileOrDirectoryFromJar(classPath, inputFileName, dstPath,
+            isDirectory);
+      } else {
         InputStream in = new FileInputStream(srcPath);
-        OutputStream out = new FileOutputStream(dstPath); 
+        OutputStream out = new FileOutputStream(dstPath);
         // Transfer bytes from in to out
         byte[] buf = new byte[1024];
         int len;
@@ -482,8 +501,8 @@
         }
         in.close();
         out.close();
-        }
-     }
+      }
+    }
   }
 
   public static String escapeXml(String unescaped) {
@@ -495,77 +514,76 @@
     return escaped;
   }
 
-  public static void makeCodeTypeClassesHtmls(HashMap<String, CodeCollection> nameToCodeColl) throws IOException{
-    
-    for (String codeType : nameToCodeColl.keySet()){
-      
-      //construct file name
+  public static void makeCodeTypeClassesHtmls(
+      HashMap<String, CodeCollection> nameToCodeColl) throws IOException {
+
+    for (String codeType : nameToCodeColl.keySet()) {
+
+      // construct file name
       String outFileName = codeType + "Classes.html";
-      
-  
+
       float maxSize = 0f;
-      TreeMap<Float, String> sortedClasses = new TreeMap<Float, String>(Collections.reverseOrder());
-      for (String className : nameToCodeColl.get(codeType).classes){
-        if (GlobalInformation.classToPartialSize.containsKey(className)){
-  
+      TreeMap<Float, String> sortedClasses = new TreeMap<Float, String>(
+          Collections.reverseOrder());
+      for (String className : nameToCodeColl.get(codeType).classes) {
+        if (GlobalInformation.classToPartialSize.containsKey(className)) {
+
           float curSize = 0f;
-          if (! GlobalInformation.classToPartialSize.containsKey(className)){
-            System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className + " *****");
-          }
-          else{
+          if (!GlobalInformation.classToPartialSize.containsKey(className)) {
+            System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS "
+                + className + " *****");
+          } else {
             curSize = GlobalInformation.classToPartialSize.get(className);
           }
-          
-          if (curSize != 0f){
+
+          if (curSize != 0f) {
             sortedClasses.put(curSize, className);
-            if (curSize > maxSize){
+            if (curSize > maxSize) {
               maxSize = curSize;
             }
           }
         }
       }
-  
+
       final PrintWriter outFile = new PrintWriter(outFileName);
-      
+
       outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
       outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
       outFile.println("<html>");
       outFile.println("<head>");
-  
+
       outFile.println("<style type=\"text/css\">");
       outFile.println("body {background-color: #728FCE}");
       outFile.println("h2 {background-color: transparent}");
       outFile.println("p {background-color: fuchsia}");
       outFile.println("</style>");
-      
+
       outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
       outFile.println("<link rel=\"stylesheet\" href=\"classLevel.css\" media=\"screen\">");
       outFile.println("<title>Classes of type \"" + codeType + "\"</title>");
       outFile.println("</head>");
       outFile.println("<body>");
-      
-  
-  
+
       outFile.println("<center>");
       outFile.println("<h2>Classes of type \"" + codeType + "\"</h2>");
       outFile.println("</center>");
       outFile.println("<hr>");
-  
+
       outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 90px; left:70px; position:absolute; background-color:white\"");
-  
-  
+
       int yOffset = 0;
-      for (Float size : sortedClasses.keySet()){
-        
+      for (Float size : sortedClasses.keySet()) {
+
         String className = sortedClasses.get(size);
-        
+
         float ratio = (size / maxSize) * 85;
-        
-        if (ratio < 3){
+
+        if (ratio < 3) {
           ratio = 3;
         }
-  
-        outFile.println("<div class=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 60px;\">");
+
+        outFile.println("<div class=\"box\" style=\"width:" + ratio
+            + "%; top: " + yOffset + "px; left: 60px;\">");
         outFile.println("<div id=\"lb\">");
         outFile.println("<div id=\"rb\">");
         outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -575,63 +593,17 @@
         outFile.println("</div></div></div></div>");
         outFile.println("</div></div></div></div>");
         outFile.println("</div>");
-        
-        int yOffsetText = yOffset+8;
-         outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
-         outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:70px;\">"+className+"</div>");
-        
-        yOffset = yOffset + 25;
-  
-      }
-      
-      outFile.println("</div>");
-      outFile.println("</body>");
-      outFile.println("</html>");
-      outFile.close();
-    }    
-  }
 
-  public static void makeDependenciesTableHtmls() throws IOException{
-  
-    for (String className : GlobalInformation.classToWhatItDependsOn.keySet()){
-          
-      String outFileName = className + "Deps.html";
-      final PrintWriter outFile = new PrintWriter(outFileName);
-      
-      outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
-      outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
-      outFile.println("<html>");
-      outFile.println("<head>");
-      outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
-      outFile.println("<title>Classes that \"" + className + "\" depends on</title>");
-      outFile.println("</head>");
-  
-      outFile.println("<style type=\"text/css\">");
-      outFile.println("body {background-color: #728FCE}");
-      outFile.println("h2 {background-color: transparent}");
-      outFile.println("p {background-color: fuchsia}");
-      outFile.println("</style>");
-      
-      outFile.println("<body>");
-      outFile.println("<center>");
-      outFile.println("<h2>Classes that \"" + className + "\" depends on</h2>");
-      outFile.println("</center>");
-      outFile.println("<hr>");
-      
-      outFile.println("<center>");
-      outFile.println("<table border=\"1\" width=\"80%\" style=\"font-size: 11pt;\" bgcolor=\"white\">");
-      
-      for (String depClassName : GlobalInformation.classToWhatItDependsOn.get(className)){
-        
-          outFile.println("<tr>");
-          outFile.println("<td width=\"80%\">" + depClassName + "</td>");
-          outFile.println("</tr>");
-          
+        int yOffsetText = yOffset + 8;
+        outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+            + "px; left:5px;\">%.1f</div>\n", size);
+        outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+            + "px; left:70px;\">" + className + "</div>");
+
+        yOffset = yOffset + 25;
+
       }
-  
-      outFile.println("</table>");
-      outFile.println("<center>");
-      
+
       outFile.println("</div>");
       outFile.println("</body>");
       outFile.println("</html>");
@@ -639,137 +611,68 @@
     }
   }
 
-  /**
-   * Makes html file for fragment classes. 
-   * TODO(kprobst): update this once we have SOYC updated to supply enough information
-   * @throws IOException
-   */
-  public static void makeFragmentClassesHtmls() throws IOException{
-    
-    
-    for (Integer fragmentName : GlobalInformation.fragmentToStories.keySet()){
-      HashSet<String> alreadyPrintedClasses = new HashSet<String>();
-      
-      String outFileName = "fragment" + Integer.toString(fragmentName) + "Classes.html";
-      
-      final PrintWriter outFile = new PrintWriter(outFileName);
-      
-      outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
-      outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
-      outFile.println("<html>");
-      outFile.println("<head>");
-      outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
-      outFile.println("<title>Classes correlated with fragment " + Integer.toString(fragmentName) + " </title>");
-      outFile.println("</head>");
-  
-      outFile.println("<style type=\"text/css\">");
-      outFile.println("body {background-color: #728FCE}");
-      outFile.println("h2 {background-color: transparent}");
-      outFile.println("p {background-color: fuchsia}");
-      outFile.println(".tablediv {");
-      outFile.println("display:  table;");
-      outFile.println("width:100%;");
-      outFile.println("background-color:#eee;");
-      outFile.println("border:1px solid  #666666;");
-      outFile.println("border-spacing:5px;");
-      outFile.println("border-collapse:separate;");
-      outFile.println("}");
-      outFile.println(".celldiv {");
-      outFile.println("float:left;");
-      outFile.println("display:  table-cell;");
-      outFile.println("width:49.5%;");
-      outFile.println("font-size: 14px;");
-      outFile.println("background-color:white;");
-      outFile.println("}");
-      outFile.println(".rowdiv  {");
-      outFile.println("display:  table-row;");
-      outFile.println("width:100%;");
-      outFile.println("}");
-      outFile.println("</style>");
-      
-      outFile.println("<body>");
-      outFile.println("<center>");
-      outFile.println("<h2>Classes correlated with fragment " + Integer.toString(fragmentName) + "</h2>");
-      outFile.println("</center>");
-      outFile.println("<hr>");
-      
-      outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");  
-      outFile.println("<div  class=\"tablediv\">");      
-      
-      for (String storyName : GlobalInformation.fragmentToStories.get(fragmentName)){
-        if (GlobalInformation.storiesToCorrClasses.containsKey(storyName)){
-          for (String className : GlobalInformation.storiesToCorrClasses.get(storyName)){
-  
-            if (! alreadyPrintedClasses.contains(className)){
-              //outFile.println("<div class=\"rowdiv\">");   
-              outFile.println("<div  class=\"rowdiv\">" + className + "</div>");
-              //outFile.println("</div>");
-              alreadyPrintedClasses.add(className);
-            }
-          }
-        }
-      }
-      outFile.println("</div>");
-      outFile.println("</body>");
-      outFile.println("</html>");
-      outFile.close();
-     }
-  }
+  public static void makeHTMLShell(
+      HashMap<String, CodeCollection> nameToCodeColl,
+      TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
+    // this will contain the place holder iframes where the actual information
+    // is going to go.
 
-  public static void makeHTMLShell(HashMap<String, CodeCollection> nameToCodeColl, TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
-    //this will contain the place holder iframes where the actual information is going to go.
-    
     System.out.println("making html shell");
     // copy from the bin directory to the current directory
     String classPath = System.getProperty("java.class.path");
-    if (!classPath.endsWith("/")){
+    if (!classPath.endsWith("/")) {
       classPath += "/";
     }
     String inputFileName = "roundedCorners.css";
     File inputFile = new File(classPath + inputFileName);
     File outputFile = new File("roundedCorners.css");
+    System.err.println("now trying to copy inputFile |" + inputFile
+        + "| to outputFile |" + outputFile + "|, classPath is " + classPath
+        + ", inputFileName is: |" + inputFileName);
     copyFileOrDirectory(inputFile, outputFile, classPath, inputFileName, false);
 
     inputFileName = "classLevel.css";
     File inputFile2 = new File(classPath + inputFileName);
     File outputFile2 = new File("classLevel.css");
-    copyFileOrDirectory(inputFile2, outputFile2, classPath, inputFileName, false);
-  
+    copyFileOrDirectory(inputFile2, outputFile2, classPath, inputFileName,
+        false);
+
     inputFileName = "images";
     File inputDir = new File(classPath + "images");
     File outputDir = new File("images");
     copyFileOrDirectory(inputDir, outputDir, classPath, inputFileName, true);
-    
-    
+
     String fileName = "SoycDashboard-index.html";
-    
+
     final PrintWriter outFile = new PrintWriter(fileName);
     outFile.println("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">");
     outFile.println("<html>");
     outFile.println("<head>");
     outFile.println("<title>Story of Your Compile - Top Level Dashboard for Permutation</title>");
-    
+
     outFile.println("<style type=\"text/css\">");
     outFile.println("body {background-color: #728FCE}");
     outFile.println("h2 {background-color: transparent}");
     outFile.println("p {background-color: fuchsia}");
     outFile.println("</style>");
     outFile.println("</head>");
-    
-    
+
     outFile.println("<body>");
     outFile.println("<center>");
     outFile.println("<h3>Story of Your Compile Dashboard</h3>");
     outFile.println("<hr>");
-    if (GlobalInformation.fragmentToStories.size() > 1){
-      outFile.println("<b>Full code size: <span style=\"color:maroon\">" + GlobalInformation.cumSizeAllCode + "</span>, Size of Initial Download:  <span style=\"color:maroon\">" + GlobalInformation.fragmentToPartialSize.get(0) + "</span></b>");
+    if (GlobalInformation.fragmentToStories.size() > 1) {
+      outFile.println("<b>Full code size: <span style=\"color:maroon\">"
+          + GlobalInformation.cumSizeAllCode
+          + "</span>, Size of Initial Download:  <span style=\"color:maroon\">"
+          + GlobalInformation.fragmentToPartialSize.get(0) + "</span></b>");
+    } else {
+      outFile.println("<b>Full code size: <span style=\"color:maroon\">"
+          + GlobalInformation.cumSizeAllCode + "</span></b>");
     }
-    else{
-      outFile.println("<b>Full code size: <span style=\"color:maroon\">" + GlobalInformation.cumSizeAllCode + "</span></b>");
-    }
-    
+
     outFile.println("<hr>");
-    
+
     outFile.println("</center>");
     outFile.println("  <div style=\"width:50%;  float:left; padding-top: 10px;\">");
     outFile.println("<b>Package breakdown</b>");
@@ -777,91 +680,84 @@
     outFile.println("  <div style=\"width:48%;  float:right; padding-top: 10px; \">");
     outFile.println("<b>Code type breakdown</b>");
     outFile.println("    </div>");
-    
-  
+
     outFile.println("  <div style=\"width:50%;  float:left; padding-top: 10px;\">");
     outFile.println("<div style=\"width: 110px; float: left; font-size:16px;\">Size</div>");
     outFile.println("<div style=\"width: 200px; float: left; text-align:left; font-size:16px; \">Package Name</div>");
     outFile.println("    </div>");
-    
-    
+
     outFile.println("  <div style=\"width:48%;  float:right; padding-top: 10px;\">");
     outFile.println("<div style=\"width: 110px; float: left; font-size:16px;\">Size</div>");
     outFile.println("<div style=\"width: 200px; float: left; text-align:left; font-size:16px; \">Code Type</div>");
     outFile.println("    </div>");
-    
-    
-    
+
     outFile.println("<div style=\"height:35%; width:48%; margin:0 auto; background-color:white; float:left;\">");
     outFile.println("<iframe src=\"packageBreakdown.html\" width=100% height=100% scrolling=auto></iframe>");
     outFile.println("  </div>");
     makePackageHtml("packageBreakdown.html");
-    
+
     outFile.println("<div style=\"height:35%; width:48%; margin:0 auto; background-color:white; float:right;\">");
     outFile.println("<iframe src=\"codeTypeBreakdown.html\" width=100% height=100% scrolling=auto></iframe>");
     outFile.println("  </div>");
     makeCodeTypeHtml("codeTypeBreakdown.html", nameToCodeColl);
-    
+
     outFile.println("  <div style=\"width:50%;  float:left; padding-top: 10px;\">");
     outFile.println("<b>Literals breakdown</b>");
     outFile.println("    </div>");
     outFile.println("  <div style=\"width:48%;  float:right; padding-top: 10px;  \">");
     outFile.println("<b>String literals breakdown</b>");
     outFile.println("    </div>");
-    
-  
+
     outFile.println("  <div style=\"width:50%;  float:left; padding-top: 10px;\">");
     outFile.println("<div style=\"width: 110px; float: left; font-size:16px;\">Size</div>");
     outFile.println("<div style=\"width: 200px; float: left; text-align:left; font-size:16px; \">Literal Type</div>");
     outFile.println("    </div>");
-    
-    
+
     outFile.println("  <div style=\"width:48%;  float:right; padding-top: 10px; \">");
     outFile.println("<div style=\"width: 110px; float: left; font-size:16px;\">Size</div>");
     outFile.println("<div style=\"width: 200px; float: left; text-align:left; font-size:16px; \">String Literal Type</div>");
     outFile.println("    </div>");
-    
-    
+
     outFile.println("<div style=\"height:35%; width:48%; margin:0 auto; background-color:white; float:left;\">");
     outFile.println("<iframe src=\"literalsBreakdown.html\" width=100% height=100% scrolling=auto></iframe>");
     outFile.println("</div>");
     makeLiteralsHtml("literalsBreakdown.html", nameToLitColl);
-  
+
     outFile.println("<div style=\"height:35%; width:48%; margin:0 auto; background-color:white; float:right;\">");
     outFile.println("<iframe src=\"stringLiteralsBreakdown.html\" width=100% height=100% scrolling=auto></iframe>");
     outFile.println("  </div>");
     makeStringLiteralsHtml("stringLiteralsBreakdown.html", nameToLitColl);
-  
-  
-    if (GlobalInformation.fragmentToStories.size() > 1){
+
+    if (GlobalInformation.fragmentToStories.size() > 1) {
       outFile.println("  <div style=\"width:50%;  float:left; padding-top: 10px;\">");
       outFile.println("<b>Breakdown by runAsync split points</b>");
       outFile.println("    </div>");
-  
+
       outFile.println("  <div style=\"width:100%;  float:left; padding-top: 10px;\">");
       outFile.println("<div style=\"width: 110px; float: left; font-size:16px;\">Size</div>");
       outFile.println("<div style=\"width: 200px; float: left; text-align:left; font-size:16px; \">Fragment Name</div>");
       outFile.println("    </div>");
-      
+
       outFile.println("<div style=\"height:35%; width:100%; margin:0 auto; background-color:white; float:left;\">");
       outFile.println("<iframe src=\"fragmentsBreakdown.html\" width=100% height=100% scrolling=auto></iframe>");
       outFile.println("</div>");
       makeFragmentsHtml("fragmentsBreakdown.html");
     }
-  
+
     outFile.println("  </body>");
     outFile.println("</html>");
     outFile.close();
-    
+
   }
 
-  public static void makeLiteralsClassesTableHtmls(TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
+  public static void makeLiteralsClassesTableHtmls(
+      TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
 
-    for (String literalType : nameToLitColl.keySet()){
-      
+    for (String literalType : nameToLitColl.keySet()) {
+
       String outFileName = literalType + "Lits.html";
       final PrintWriter outFile = new PrintWriter(outFileName);
-      
+
       outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
       outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
       outFile.println("<html>");
@@ -875,101 +771,99 @@
       outFile.println("h2 {background-color: transparent}");
       outFile.println("p {background-color: fuchsia}");
       outFile.println("</style>");
-      
+
       outFile.println("<body>");
       outFile.println("<center>");
       outFile.println("<h2>Literals of type \"" + literalType + "\"</h2>");
       outFile.println("</center>");
       outFile.println("<hr>");
-      
+
       outFile.println("<center>");
       outFile.println("<table border=\"1\" width=\"80%\" style=\"font-size: 11pt;\" bgcolor=\"white\">");
-   
-      for (String literal : nameToLitColl.get(literalType).literalToLocations.keySet()){
-  
-        if (literal.trim().compareTo("") == 0){
+
+      for (String literal : nameToLitColl.get(literalType).literalToLocations.keySet()) {
+
+        if (literal.trim().compareTo("") == 0) {
           literal = "[whitespace only string]";
         }
-        
 
         String newLiteral = "";
-        if(literal.length() > 80){
+        if (literal.length() > 80) {
           int i;
-          for (i = 80; i < literal.length(); i=i+80){
-            String part1 = literal.substring(i-80, i);
-            newLiteral = newLiteral + part1 + " "; 
+          for (i = 80; i < literal.length(); i = i + 80) {
+            String part1 = literal.substring(i - 80, i);
+            newLiteral = newLiteral + part1 + " ";
           }
-          if (i-80 > 0){
-            newLiteral = newLiteral + literal.substring(i-80);
+          if (i - 80 > 0) {
+            newLiteral = newLiteral + literal.substring(i - 80);
           }
-        }
-        else{
+        } else {
           newLiteral = literal;
         }
-        
+
         String escliteral = escapeXml(newLiteral);
 
         outFile.println("<tr>");
         outFile.println("<td width=\"40%\">" + escliteral + "</td>");
-        
 
         int ct = 0;
-        for (String location : nameToLitColl.get(literalType).literalToLocations.get(literal)){
-          
-          if (ct > 0){
-            outFile.println("<tr>");  
-            outFile.println("<td width=\"40%\"> </td>");          
-          }
-          
-          String newLocation = "";
-          if(location.length() > 80){
-            int i;
-            for (i = 80; i < location.length(); i=i+80){
-              String part1 = location.substring(i-80, i);
-              newLocation = newLocation + part1 + " "; 
-            }
-            if (i-80 > 0){
-              newLocation = newLocation + location.substring(i-80);
-            }
-          }
-          else{
-            newLocation = location;
-          }
-          
-          
-          outFile.println("<td width=\"40%\">" + newLocation + "</td>");
+        if ((nameToLitColl.containsKey(literalType))
+            && (nameToLitColl.get(literalType).literalToLocations.containsKey(literal))) {
+          for (String location : nameToLitColl.get(literalType).literalToLocations.get(literal)) {
 
-          if (ct > 0){
-            outFile.println("</tr>");
+            if (ct > 0) {
+              outFile.println("<tr>");
+              outFile.println("<td width=\"40%\"> </td>");
+            }
+
+            String newLocation = "";
+            if (location.length() > 80) {
+              int i;
+              for (i = 80; i < location.length(); i = i + 80) {
+                String part1 = location.substring(i - 80, i);
+                newLocation = newLocation + part1 + " ";
+              }
+              if (i - 80 > 0) {
+                newLocation = newLocation + location.substring(i - 80);
+              }
+            } else {
+              newLocation = location;
+            }
+
+            outFile.println("<td width=\"40%\">" + newLocation + "</td>");
+
+            if (ct > 0) {
+              outFile.println("</tr>");
+            }
+            ct++;
           }
-          ct++;
-          
+        } else {
+          System.err.println("either literalType " + literalType
+              + " not known, or no location for literal " + literal);
         }
 
-        
         outFile.println("</tr>");
-        
+
       }
 
       outFile.println("</table>");
       outFile.println("<center>");
 
-      
       outFile.println("</div>");
       outFile.println("</body>");
       outFile.println("</html>");
       outFile.close();
-     }
+    }
   }
 
-  public static void makeLiteralsClassesHtmls(TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
-    
-    
-    for (String literalType : nameToLitColl.keySet()){
-      
+  public static void makeLiteralsClassesHtmls(
+      TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
+
+    for (String literalType : nameToLitColl.keySet()) {
+
       String outFileName = literalType + "Lits.html";
       final PrintWriter outFile = new PrintWriter(outFileName);
-      
+
       outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
       outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
       outFile.println("<html>");
@@ -999,61 +893,57 @@
       outFile.println("}");
       outFile.println(".rowdiv  {");
       outFile.println("display:  table-row;");
-      //outFile.println("width:90%;");
       outFile.println("}");
       outFile.println("</style>");
-      
+
       outFile.println("<body>");
       outFile.println("<center>");
       outFile.println("<h2>Literals of type \"" + literalType + "\"</h2>");
       outFile.println("</center>");
       outFile.println("<hr>");
-      
-      outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");  
-      outFile.println("<div class=\"tablediv\">");      
-      for (String literal : nameToLitColl.get(literalType).literalToLocations.keySet()){
-  
-        if (literal.trim().compareTo("") == 0){
+
+      outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
+      outFile.println("<div class=\"tablediv\">");
+      for (String literal : nameToLitColl.get(literalType).literalToLocations.keySet()) {
+
+        if (literal.trim().compareTo("") == 0) {
           literal = "[whitespace only string]";
         }
-        
 
         String newLiteral = "";
-        if(literal.length() > 100){
+        if (literal.length() > 100) {
           int i;
-          for (i = 100; i < literal.length(); i=i+100){
-            String part1 = literal.substring(i-100, i);
-            newLiteral = newLiteral + part1 + " "; 
+          for (i = 100; i < literal.length(); i = i + 100) {
+            String part1 = literal.substring(i - 100, i);
+            newLiteral = newLiteral + part1 + " ";
           }
-          if (i-100 > 0){
-            newLiteral = newLiteral + literal.substring(i-100);
+          if (i - 100 > 0) {
+            newLiteral = newLiteral + literal.substring(i - 100);
           }
-        }
-        else{
+        } else {
           newLiteral = literal;
         }
-        
+
         String escliteral = escapeXml(newLiteral);
-        outFile.println("<div class=\"rowdiv\">");   
+        outFile.println("<div class=\"rowdiv\">");
         outFile.println("<div class=\"celldiv\">" + escliteral + "</div>");
 
-        for (String location : nameToLitColl.get(literalType).literalToLocations.get(literal)){
-          
+        for (String location : nameToLitColl.get(literalType).literalToLocations.get(literal)) {
+
           String newLocation = "";
-          if(location.length() > 100){
+          if (location.length() > 100) {
             int i;
-            for (i = 100; i < location.length(); i=i+100){
-              String part1 = location.substring(i-100, i);
-              newLocation = newLocation + part1 + " "; 
+            for (i = 100; i < location.length(); i = i + 100) {
+              String part1 = location.substring(i - 100, i);
+              newLocation = newLocation + part1 + " ";
             }
-            if (i-100 > 0){
-              newLocation = newLocation + location.substring(i-100);
+            if (i - 100 > 0) {
+              newLocation = newLocation + location.substring(i - 100);
             }
-          }
-          else{
+          } else {
             newLocation = location;
           }
-          
+
           outFile.println("<div class=\"celldiv\">" + newLocation + "</div>");
         }
         outFile.println("</div>");
@@ -1062,96 +952,94 @@
       outFile.println("</body>");
       outFile.println("</html>");
       outFile.close();
-     }
+    }
   }
 
-  public static void makePackageClassesHtmls() throws IOException{
-        
-    for (String packageName : GlobalInformation.packageToClasses.keySet()){
-      
+  public static void makePackageClassesHtmls() throws IOException {
+
+    for (String packageName : GlobalInformation.packageToClasses.keySet()) {
+
       String outFileName = packageName + "Classes.html";
-      TreeMap<Float, String> sortedClasses = new TreeMap<Float, String>(Collections.reverseOrder());
+      TreeMap<Float, String> sortedClasses = new TreeMap<Float, String>(
+          Collections.reverseOrder());
       float maxSize = 0f;
-      
-      //TODO(kprobst): not currently used, but will be for dependencies
+
       int maxDepCount = 1;
-  
-      for (String className : GlobalInformation.packageToClasses.get(packageName)){
-        
+
+      for (String className : GlobalInformation.packageToClasses.get(packageName)) {
+
         float curSize = 0f;
-        if (! GlobalInformation.classToPartialSize.containsKey(className)){
-          System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className + " *****");
-        }
-        else{
+        if (!GlobalInformation.classToPartialSize.containsKey(className)) {
+          System.err.println("*** NO PARTIAL SIZE FOUND FOR CLASS " + className
+              + " *****");
+        } else {
           curSize = GlobalInformation.classToPartialSize.get(className);
         }
-          
-        //TODO(kprobst): not currently used, but will be for dependencies
+
         int depCount = 0;
-        if (GlobalInformation.classToWhatItDependsOn.containsKey(className)){
+        if (GlobalInformation.classToWhatItDependsOn.containsKey(className)) {
           depCount = GlobalInformation.classToWhatItDependsOn.get(className).size();
         }
-        
-        if (curSize != 0f){
-          
+
+        if (curSize != 0f) {
+
           sortedClasses.put(curSize, className);
-          if (curSize > maxSize){
+          if (curSize > maxSize) {
             maxSize = curSize;
           }
-          //TODO(kprobst): not currently used, but will be for dependencies
-          if (depCount > maxDepCount){
+          if (depCount > maxDepCount) {
             maxDepCount = depCount;
           }
         }
       }
-      
-        
+
       final PrintWriter outFile = new PrintWriter(outFileName);
-      
+
       outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
       outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
       outFile.println("<html>");
       outFile.println("<head>");
       outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
       outFile.println("<link rel=\"stylesheet\" href=\"classLevel.css\" media=\"screen\">");
-      outFile.println("<title>Classes in package \"" + packageName + "\"</title>");
+      outFile.println("<title>Classes in package \"" + packageName
+          + "\"</title>");
       outFile.println("</head>");
       outFile.println("<body>");
-      
-  
+
       outFile.println("<center>");
       outFile.println("<h2>Classes in package \"" + packageName + "\"</h2>");
       outFile.println("</center>");
       outFile.println("<hr>");
-  
+
       outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 90px; left:70px; position:absolute; background-color:white\"");
-  
-  
+
       int yOffset = 0;
-      for (Float size : sortedClasses.keySet()){
-        
+      for (Float size : sortedClasses.keySet()) {
+
         String className = sortedClasses.get(size);
-        
-        //TODO(kprobst): switch out the commented/uncommented lines below when showing dependencies
+
+        // TODO(kprobst): switch out the commented/uncommented lines below when
+        // showing dependencies
         // float ratio = (size / maxSize) * 45;
         float ratio = (size / maxSize) * 85;
-         
-        if (ratio < 3){
+
+        if (ratio < 3) {
           ratio = 3;
         }
-        
-        //TODO(kprobst): not currently used, but will be for dependencies
-       // get the dependency count
+
+        // TODO(kprobst): not currently used, but will be for dependencies
+        // get the dependency count
         int depCount = 0;
-        if (GlobalInformation.classToWhatItDependsOn.containsKey(className)){
+        if (GlobalInformation.classToWhatItDependsOn.containsKey(className)) {
           depCount = GlobalInformation.classToWhatItDependsOn.get(className).size();
         }
-        float depRatio = ((float)depCount / (float)maxDepCount) * 45f;
-        if (depRatio < 3.0){
+        float depRatio = ((float) depCount / (float) maxDepCount) * 45f;
+        if (depRatio < 3.0) {
           depRatio = 3;
         }
-  
-        outFile.println("<div class=\"box\" style=\"width:" + ratio + "%; top: " + yOffset + "px; left: 60px;\">");
+
+        outFile.println("<div class=\"box\" style=\"width:" + ratio
+            + "%; top: " + yOffset + "px; left: 60px;\">");
         outFile.println("<div id=\"lb\">");
         outFile.println("<div id=\"rb\">");
         outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
@@ -1161,32 +1049,42 @@
         outFile.println("</div></div></div></div>");
         outFile.println("</div></div></div></div>");
         outFile.println("</div>");
-        
-        
-        //TODO(kprobst): not currently used, but will be for dependencies
-/*        outFile.println("<div class=\"box-right\" style=\"width:" + depRatio + "%; top: " + yOffset + "px; left: 50%\">");
-        outFile.println("<div id=\"lb\">");
-        outFile.println("<div id=\"rb\">");
-        outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
-        outFile.println("<div id=\"tb\"><div id=\"tlc\"><div id=\"trc\">");
-        outFile.println("<div id=\"content\">");
-        outFile.println("</div>");
-        outFile.println("</div></div></div></div>");
-        outFile.println("</div></div></div></div>");
-        outFile.println("</div>");*/
-              
-        int yOffsetText = yOffset+8;
-        outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:5px;\">%.1f</div>\n", size);
-        outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:70px;\">"+className+"</div>");
-        
-/*        //TODO(kprobst) make this a link
-        String drillDownFileName = className + "Deps.html";
-        outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText + "px; left:50%;\"><a href=\"" + drillDownFileName + "\" target=\"_top\">Dependencies: " + depCount + "</a></div>");
-*/        
+
+        // TODO(kprobst): not currently used, but will be for dependencies
+        /*
+         * outFile.println("<div class=\"box-right\" style=\"width:" + depRatio
+         * + "%; top: " + yOffset + "px; left: 50%\">");
+         * outFile.println("<div id=\"lb\">");
+         * outFile.println("<div id=\"rb\">");
+         * outFile.println("<div id=\"bb\"><div id=\"blc\"><div id=\"brc\">");
+         * outFile.println("<div id=\"tb\"><div id=\"tlc\"><div id=\"trc\">");
+         * outFile.println("<div id=\"content\">"); outFile.println("</div>");
+         * outFile.println("</div></div></div></div>");
+         * outFile.println("</div></div></div></div>");
+         * outFile.println("</div>");
+         */
+
+        int yOffsetText = yOffset + 8;
+        outFile.printf("<div class=\"barlabel\" style=\"top:" + yOffsetText
+            + "px; left:5px;\">%.1f</div>\n", size);
+        if (GlobalInformation.displayDependencies == true) {
+          outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+              + "px; left:70px;\"><a href=\"methodDependencies-" + packageName
+              + ".html#" + className + "\">" + className + "</a></div>");
+        } else {
+          outFile.println("<div class=\"barlabel\" style=\"top:" + yOffsetText
+              + "px; left:70px;\">" + className + "</div>");
+        }
+        /*
+         * //TODO(kprobst) make this a link String drillDownFileName = className
+         * + "Deps.html"; outFile.println("<div class=\"barlabel\" style=\"top:"
+         * + yOffsetText + "px; left:50%;\"><a href=\"" + drillDownFileName +
+         * "\" target=\"_top\">Dependencies: " + depCount + "</a></div>");
+         */
         yOffset = yOffset + 25;
-  
+
       }
-      
+
       outFile.println("</div>");
       outFile.println("</body>");
       outFile.println("</html>");
@@ -1195,53 +1093,58 @@
   }
 
   /**
-   * Makes html file for fragment classes. 
-   * TODO(kprobst): update this once we have SOYC updated to supply enough information
+   * Makes html file for fragment classes. TODO(kprobst): update this once we
+   * have SOYC updated to supply enough information
+   * 
    * @throws IOException
    */
-  public static void makeSplitPointClassesHtmls() throws IOException{
-    
-    //for the initial fragment and the fragments in the load order, we can print this immediately
-    // For those fragments *not* in the initial load order, we just collect and then print at the end
+  public static void makeSplitPointClassesHtmls() throws IOException {
+
+    // for the initial fragment and the fragments in the load order, we can
+    // print this immediately
+    // For those fragments *not* in the initial load order, we just collect and
+    // then print at the end
     TreeSet<String> sortedClassesAndMethodsAllOtherFragments = new TreeSet<String>();
-        
-    for (Integer fragmentName : GlobalInformation.fragmentToStories.keySet()){
-         
-      if ((fragmentName != 0)&&(!GlobalInformation.splitPointToLocation.containsKey(fragmentName))){
-        
+
+    for (Integer fragmentName : GlobalInformation.fragmentToStories.keySet()) {
+
+      if ((fragmentName != 0)
+          && (!GlobalInformation.splitPointToLocation.containsKey(fragmentName))) {
+
         // get the stories from ALL the fragments
-        for (String storyName : GlobalInformation.fragmentToStories.get(fragmentName)){
-          if ((!GlobalInformation.nameToLitColl.get("string").storyToLocations.containsKey(storyName))&&(GlobalInformation.storiesToCorrClassesAndMethods.containsKey(storyName))){
-            for (String className : GlobalInformation.storiesToCorrClassesAndMethods.get(storyName)){
-                sortedClassesAndMethodsAllOtherFragments.add(className);
+        for (String storyName : GlobalInformation.fragmentToStories.get(fragmentName)) {
+          if ((!GlobalInformation.nameToLitColl.get("string").storyToLocations.containsKey(storyName))
+              && (GlobalInformation.storiesToCorrClassesAndMethods.containsKey(storyName))) {
+            for (String className : GlobalInformation.storiesToCorrClassesAndMethods.get(storyName)) {
+              sortedClassesAndMethodsAllOtherFragments.add(className);
             }
           }
         }
       }
-      
-//      else if ((fragmentName == 0)||(GlobalInformation.splitPointToLocation.containsKey(fragmentName))){
-      else{
+
+      else {
         String curSplitPointLocation;
-        
-        if (fragmentName == 0){
+
+        if (fragmentName == 0) {
           curSplitPointLocation = "initialDownload";
-        }
-        else{
+        } else {
           curSplitPointLocation = GlobalInformation.splitPointToLocation.get(fragmentName);
         }
-        
-        String outFileName = "splitPoint" + curSplitPointLocation + "Classes.html";
-        
+
+        String outFileName = "splitPoint" + curSplitPointLocation
+            + "Classes.html";
+
         final PrintWriter outFile = new PrintWriter(outFileName);
-        
+
         outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
         outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
         outFile.println("<html>");
         outFile.println("<head>");
         outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
-        outFile.println("<title>Classes and methods in exclusives fragment for runAsync split point \"" + curSplitPointLocation + "\" </title>");
+        outFile.println("<title>Classes and methods in exclusives fragment for runAsync split point \""
+            + curSplitPointLocation + "\" </title>");
         outFile.println("</head>");
-  
+
         outFile.println("<style type=\"text/css\">");
         outFile.println("body {background-color: #728FCE}");
         outFile.println("h2 {background-color: transparent}");
@@ -1266,57 +1169,62 @@
         outFile.println("width:100%;");
         outFile.println("}");
         outFile.println("</style>");
-        
+
         outFile.println("<body>");
         outFile.println("<center>");
-        outFile.println("<h2>Classes and methods in exclusives fragment for runAsync split point \"" + curSplitPointLocation + "\"</h2>");
+        outFile.println("<h2>Classes and methods in exclusives fragment for runAsync split point \""
+            + curSplitPointLocation + "\"</h2>");
         outFile.println("</center>");
         outFile.println("<hr>");
-        
-        outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");  
-        outFile.println("<div  class=\"tablediv\">");  
-        
+
+        outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
+        outFile.println("<div  class=\"tablediv\">");
+
         TreeSet<String> sortedClassesAndMethods = new TreeSet<String>();
-        for (String storyName : GlobalInformation.fragmentToStories.get(fragmentName)){
-          if ((!GlobalInformation.nameToLitColl.get("string").storyToLocations.containsKey(storyName))&&(GlobalInformation.storiesToCorrClassesAndMethods.containsKey(storyName))){
-            for (String className : GlobalInformation.storiesToCorrClassesAndMethods.get(storyName)){
-                sortedClassesAndMethods.add(className);
+        for (String storyName : GlobalInformation.fragmentToStories.get(fragmentName)) {
+          if ((!GlobalInformation.nameToLitColl.get("string").storyToLocations.containsKey(storyName))
+              && (GlobalInformation.storiesToCorrClassesAndMethods.containsKey(storyName))) {
+            for (String className : GlobalInformation.storiesToCorrClassesAndMethods.get(storyName)) {
+              sortedClassesAndMethods.add(className);
             }
           }
         }
-        for (String classOrMethod : sortedClassesAndMethods){
+        for (String classOrMethod : sortedClassesAndMethods) {
 
-          
-          //if it's a method
-          if ((GlobalInformation.displayDependencies == true)&&(classOrMethod.contains("("))&&(classOrMethod.contains(")"))){
-            //get the package
+          // if it's a method
+          if ((GlobalInformation.displayDependencies == true)
+              && (classOrMethod.contains("(")) && (classOrMethod.contains(")"))) {
+            // get the package
             String packageName = classOrMethod;
             packageName = packageName.replaceAll("\\.\\p{Upper}.*", "");
-            
+
             String noParamMethod = classOrMethod;
             noParamMethod = noParamMethod.replaceAll("\\(.*", "");
-            
-            outFile.println("<div  class=\"rowdiv\"><a href=\"methodDependencies-" + packageName + ".html#"+ noParamMethod + "\">" + classOrMethod + "</a></div>");
-          }
-          else{
-            outFile.println("<div  class=\"rowdiv\">" + classOrMethod + "</div>");            
+
+            outFile.println("<div  class=\"rowdiv\"><a href=\"methodDependencies-"
+                + packageName
+                + ".html#"
+                + noParamMethod
+                + "\">"
+                + classOrMethod + "</a></div>");
+          } else {
+            outFile.println("<div  class=\"rowdiv\">" + classOrMethod
+                + "</div>");
           }
         }
-        
+
         outFile.println("</div>");
         outFile.println("</body>");
         outFile.println("</html>");
         outFile.close();
-       }
+      }
     }
-    
-    
-    //finally, make the file for all the other fragments
+
+    // finally, make the file for all the other fragments
     String outFileName = "splitPointAllOtherFragmentsClasses.html";
-    
+
     final PrintWriter outFile = new PrintWriter(outFileName);
 
-    
     outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
     outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
     outFile.println("<html>");
@@ -1349,53 +1257,52 @@
     outFile.println("width:100%;");
     outFile.println("}");
     outFile.println("</style>");
-    
+
     outFile.println("<body>");
     outFile.println("<center>");
     outFile.println("<h2>Classes and methods in exclusives fragment for runAsync split point \"allOtherFragments\"</h2>");
     outFile.println("</center>");
     outFile.println("<hr>");
-    
-    outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");  
-    outFile.println("<div  class=\"tablediv\">");  
-    
-    for (String classOrMethod : sortedClassesAndMethodsAllOtherFragments){
 
-      //if it's a method
-      if ((GlobalInformation.displayDependencies == true)&&(classOrMethod.contains("("))&&(classOrMethod.contains(")"))){
-        //get the package
+    outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
+    outFile.println("<div  class=\"tablediv\">");
+
+    for (String classOrMethod : sortedClassesAndMethodsAllOtherFragments) {
+
+      // if it's a method
+      if ((GlobalInformation.displayDependencies == true)
+          && (classOrMethod.contains("(")) && (classOrMethod.contains(")"))) {
+        // get the package
         String packageName = classOrMethod;
         packageName = packageName.replaceAll("\\.\\p{Upper}.*", "");
-        
+
         String noParamMethod = classOrMethod;
         noParamMethod = noParamMethod.replaceAll("\\(.*", "");
-        
-        outFile.println("<div  class=\"rowdiv\"><a href=\"methodDependencies-" + packageName + ".html#"+ noParamMethod + "\">" + classOrMethod + "</a></div>");
-      }
-      else{
+
+        outFile.println("<div  class=\"rowdiv\"><a href=\"methodDependencies-"
+            + packageName + ".html#" + noParamMethod + "\">" + classOrMethod
+            + "</a></div>");
+      } else {
         outFile.println("<div  class=\"rowdiv\">" + classOrMethod + "</div>");
       }
     }
-    
+
     outFile.println("</div>");
     outFile.println("</body>");
     outFile.println("</html>");
     outFile.close();
 
-    
-    
   }
 
-  public static void makeStringLiteralsClassesHtmls(TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
-    
-    
-    for (String literalType : nameToLitColl.get("string").stringTypeToSize.keySet()){
-      
+  public static void makeStringLiteralsClassesHtmls(
+      TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
+
+    for (String literalType : nameToLitColl.get("string").stringTypeToSize.keySet()) {
+
       String outFileName = literalType + "Strings.html";
-      
+
       final PrintWriter outFile = new PrintWriter(outFileName);
-      
-      
+
       outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
       outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
       outFile.println("<html>");
@@ -1428,62 +1335,59 @@
       outFile.println("width:100%;");
       outFile.println("}");
       outFile.println("</style>");
-      
+
       outFile.println("<body>");
       outFile.println("<center>");
       outFile.println("<h2>Literals of type \"" + literalType + "\"</h2>");
       outFile.println("</center>");
       outFile.println("<hr>");
-      
-      outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");  
-      outFile.println("<div  class=\"tablediv\">");      
 
-      
-      for (String literal : nameToLitColl.get("string").stringLiteralToType.keySet()){
-        
-        if (nameToLitColl.get("string").stringLiteralToType.get(literal).compareTo(literalType) == 0){
-       
+      outFile.println("<div style=\"width:90%; height:80%; overflow-y:auto; overflow-x:auto; top: 30px; left:60px; position:relative; background-color:white\"");
+      outFile.println("<div  class=\"tablediv\">");
 
-          if (literal.trim().compareTo("") == 0){
+      for (String literal : nameToLitColl.get("string").stringLiteralToType.keySet()) {
+
+        if (nameToLitColl.get("string").stringLiteralToType.get(literal).compareTo(
+            literalType) == 0) {
+
+          if (literal.trim().compareTo("") == 0) {
             literal = "[whitespace only string]";
           }
-          
+
           String newLiteral = "";
-          if(literal.length() > 100){
+          if (literal.length() > 100) {
             int i;
-            for (i = 100; i < literal.length(); i=i+100){
-              String part1 = literal.substring(i-100, i);
-              newLiteral = newLiteral + part1 + " "; 
+            for (i = 100; i < literal.length(); i = i + 100) {
+              String part1 = literal.substring(i - 100, i);
+              newLiteral = newLiteral + part1 + " ";
             }
-            if (i-100 > 0){
-              newLiteral = newLiteral + literal.substring(i-100);
+            if (i - 100 > 0) {
+              newLiteral = newLiteral + literal.substring(i - 100);
             }
-          }
-          else{
+          } else {
             newLiteral = literal;
           }
-          
+
           String escliteral = escapeXml(newLiteral);
-          outFile.println("<div class=\"rowdiv\">");   
+          outFile.println("<div class=\"rowdiv\">");
           outFile.println("<div  class=\"celldiv\">" + escliteral + "</div>");
 
-          for (String location : nameToLitColl.get("string").literalToLocations.get(literal)){
-            
+          for (String location : nameToLitColl.get("string").literalToLocations.get(literal)) {
+
             String newLocation = "";
-            if(location.length() > 100){
+            if (location.length() > 100) {
               int i;
-              for (i = 100; i < location.length(); i=i+100){
-                String part1 = location.substring(i-100, i);
-                newLocation = newLocation + part1 + " "; 
+              for (i = 100; i < location.length(); i = i + 100) {
+                String part1 = location.substring(i - 100, i);
+                newLocation = newLocation + part1 + " ";
               }
-              if (i-100 > 0){
-                newLocation = newLocation + location.substring(i-100);
+              if (i - 100 > 0) {
+                newLocation = newLocation + location.substring(i - 100);
               }
-            }
-            else{
+            } else {
               newLocation = location;
             }
-            
+
             outFile.println("<div  class=\"celldiv\">" + newLocation + "</div>");
           }
           outFile.println("</div>");
@@ -1493,21 +1397,18 @@
       outFile.println("</body>");
       outFile.println("</html>");
       outFile.close();
-     }
-         
-          
+    }
 
   }
-  
-  public static void makeStringLiteralsClassesTableHtmls(TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException{
 
-    
-    for (String literalType : nameToLitColl.get("string").stringTypeToSize.keySet()){
- 
-      
+  public static void makeStringLiteralsClassesTableHtmls(
+      TreeMap<String, LiteralsCollection> nameToLitColl) throws IOException {
+
+    for (String literalType : nameToLitColl.get("string").stringTypeToSize.keySet()) {
+
       String outFileName = literalType + "Strings.html";
       final PrintWriter outFile = new PrintWriter(outFileName);
-      
+
       outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
       outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
       outFile.println("<html>");
@@ -1521,86 +1422,87 @@
       outFile.println("h2 {background-color: transparent}");
       outFile.println("p {background-color: fuchsia}");
       outFile.println("</style>");
-      
+
       outFile.println("<body>");
       outFile.println("<center>");
       outFile.println("<h2>Literals of type \"" + literalType + "\"</h2>");
       outFile.println("</center>");
       outFile.println("<hr>");
-      
-      outFile.println("<center>");      
+
+      outFile.println("<center>");
       outFile.println("<table border=\"1\" width=\"80%\" style=\"font-size: 11pt;\" bgcolor=\"white\">");
-      
-   
-      
-      for (String literal : nameToLitColl.get("string").stringLiteralToType.keySet()){
-        
-        if (nameToLitColl.get("string").stringLiteralToType.get(literal).compareTo(literalType) == 0){
- 
-          if (literal.trim().compareTo("") == 0){
+
+      for (String literal : nameToLitColl.get("string").stringLiteralToType.keySet()) {
+
+        if (nameToLitColl.get("string").stringLiteralToType.get(literal).compareTo(
+            literalType) == 0) {
+
+          if (literal.trim().compareTo("") == 0) {
             literal = "[whitespace only string]";
           }
-  
+
           String newLiteral = "";
-          if(literal.length() > 80){
+          if (literal.length() > 80) {
             int i;
-            for (i = 80; i < literal.length(); i=i+80){
-              String part1 = literal.substring(i-80, i);
-              newLiteral = newLiteral + part1 + " "; 
+            for (i = 80; i < literal.length(); i = i + 80) {
+              String part1 = literal.substring(i - 80, i);
+              newLiteral = newLiteral + part1 + " ";
             }
-            if (i-80 > 0){
-              newLiteral = newLiteral + literal.substring(i-80);
+            if (i - 80 > 0) {
+              newLiteral = newLiteral + literal.substring(i - 80);
             }
-          }
-          else{
+          } else {
             newLiteral = literal;
           }
-          
+
           String escliteral = escapeXml(newLiteral);
-  
+
           outFile.println("<tr>");
           outFile.println("<td width=\"40%\">" + escliteral + "</td>");
-          
-  
+
           int ct = 0;
 
-          for (String location : nameToLitColl.get("string").literalToLocations.get(literal)){
-            
-            if (ct > 0){
-              outFile.println("<tr>");  
-              outFile.println("<td width=\"40%\"> </td>");          
-            }
-            
-            String newLocation = "";
-            if(location.length() > 80){
-              int i;
-              for (i = 80; i < location.length(); i=i+80){
-                String part1 = location.substring(i-80, i);
-                newLocation = newLocation + part1 + " "; 
+          if (nameToLitColl.get("string").literalToLocations.containsKey(literal)) {
+
+            for (String location : nameToLitColl.get("string").literalToLocations.get(literal)) {
+
+              if (ct > 0) {
+                outFile.println("<tr>");
+                outFile.println("<td width=\"40%\"> </td>");
               }
-              if (i-80 > 0){
-                newLocation = newLocation + location.substring(i-80);
+
+              String newLocation = "";
+              if (location.length() > 80) {
+                int i;
+                for (i = 80; i < location.length(); i = i + 80) {
+                  String part1 = location.substring(i - 80, i);
+                  newLocation = newLocation + part1 + " ";
+                }
+                if (i - 80 > 0) {
+                  newLocation = newLocation + location.substring(i - 80);
+                }
+              } else {
+                newLocation = location;
               }
+
+              outFile.println("<td width=\"40%\">" + newLocation + "</td>");
+
+              if (ct > 0) {
+                outFile.println("</tr>");
+              }
+              ct++;
             }
-            else{
-              newLocation = location;
-            }
-            
-            
-            outFile.println("<td width=\"40%\">" + newLocation + "</td>");
-  
-            if (ct > 0){
-              outFile.println("</tr>");
-            }
-            ct++;
+          } else {
+            System.err.println("no location given for string literal: "
+                + literal);
           }
           outFile.println("</tr>");
-        }  
+        }
       }
 
       outFile.println("</table>");
       outFile.println("<center>");
-      
+
       outFile.println("</div>");
       outFile.println("</body>");
       outFile.println("</html>");
@@ -1608,75 +1510,92 @@
     }
   }
 
-
-  
-  public static void makeDependenciesHtml(Map<String, ArrayList<String>> dependencies) throws IOException{
+  public static void makeDependenciesHtml(
+      Map<String, ArrayList<String>> dependencies) throws IOException {
 
     String origOutFileName = "methodDependencies-";
     PrintWriter outFile = null;
     String curPackageName = "";
-    
-    for (String method : dependencies.keySet()){
+    String curClassName = "";
+
+    for (String method : dependencies.keySet()) {
       // this key set is already in alphabetical order
       // get the package of this method, i.e., everything up to .[A-Z]
-      
+
       String packageName = method;
       packageName = packageName.replaceAll("\\.\\p{Upper}.*", "");
-      
 
-        if ((curPackageName.compareTo("") == 0) || (curPackageName.compareTo(packageName) != 0)){
+      String className = method;
+      className = className.replaceAll("::.*", "");
 
-          curPackageName = packageName;
-          if (outFile != null){
-            //finish up the current file
-            outFile.println("</table>");
-            outFile.println("<center>");
-            
-            outFile.println("</div>");
-            outFile.println("</body>");
-            outFile.println("</html>");
-            outFile.close();
-          }
-          
-          String outFileName = origOutFileName + curPackageName + ".html";
-          outFile = new PrintWriter(outFileName); 
-          
-          outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
-          outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
-          outFile.println("<html>");
-          outFile.println("<head>");
-          outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
-          outFile.println("<title>Method Dependencies</title>");
-          outFile.println("</head>");
-      
-          outFile.println("<style type=\"text/css\">");
-          outFile.println("body {background-color: #728FCE}");
-          outFile.println("h2 {background-color: transparent}");
-          outFile.println("p {background-color: fuchsia}");
-          outFile.println("</style>");
-          
-          outFile.println("<body>");
+      if ((curPackageName.compareTo("") == 0)
+          || (curPackageName.compareTo(packageName) != 0)) {
+
+        curPackageName = packageName;
+        if (outFile != null) {
+          // finish up the current file
+          outFile.println("</table>");
           outFile.println("<center>");
-          outFile.println("<h2>Method Dependencies</h2>");
-          outFile.println("</center>");
-          outFile.println("<hr>");
-          
-          outFile.println("<center>");      
-          outFile.println("<table border=\"1\" width=\"80%\" style=\"font-size: 11pt;\" bgcolor=\"white\">");
-          
+
+          outFile.println("</div>");
+          outFile.println("</body>");
+          outFile.println("</html>");
+          outFile.close();
         }
+
+        String outFileName = origOutFileName + curPackageName + ".html";
+        outFile = new PrintWriter(outFileName);
+
+        outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
+        outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
+        outFile.println("<html>");
+        outFile.println("<head>");
+        outFile.println("<meta http-equiv=\"content-type\" content=\"text/html;charset=ISO-8859-1\">");
+        outFile.println("<title>Method Dependencies</title>");
+        outFile.println("</head>");
+
+        outFile.println("<style type=\"text/css\">");
+        outFile.println("body {background-color: #728FCE}");
+        outFile.println("h2 {background-color: transparent}");
+        outFile.println("p {background-color: fuchsia}");
+        outFile.println("</style>");
+
+        outFile.println("<body>");
+        outFile.println("<center>");
+        outFile.println("<h2>Method Dependencies for package " + curPackageName
+            + "</h2>");
+        outFile.println("</center>");
+        outFile.println("<hr>");
+
+        outFile.println("<center>");
+        outFile.println("<table border=\"1\" width=\"80%\" style=\"font-size: 11pt;\" bgcolor=\"white\">");
+
+      }
+      outFile.println("<tr>");
+      if (curClassName.compareTo(className) != 0) {
+        outFile.println("<td width=\"80%\"><a name=\"" + className + "\">"
+            + "<a name=\"" + method + "\">" + method
+            + "</a></a><font color=\"green\"> called by</font></td>");
+        curClassName = className;
+      } else {
+        outFile.println("<td width=\"80%\"><a name=\"" + method + "\">"
+            + method + "</a><font color=\"green\"> called by</font></td>");
+      }
+      outFile.println("</tr>");
+
+      for (int i = 0; i < dependencies.get(method).size(); i++) {
+        String depMethod = dependencies.get(method).get(i);
+
         outFile.println("<tr>");
-        outFile.println("<td width=\"80%\"><a name=\"" + method + "\">" + method + "</a></td>");
-        outFile.println("</tr>");
-        
-        for (int i = 0; i < dependencies.get(method).size(); i++){
-          String depMethod = dependencies.get(method).get(i);
-          
-          outFile.println("<tr>");
-          outFile.println("<td width=\"20%\"></td>");
+        outFile.println("<td width=\"20%\"></td>");
+        if (i != dependencies.get(method).size() - 1) {
+          outFile.println("<td width=\"60%\">" + depMethod
+              + "<font color=\"green\"> called by</font></td>");
+        } else {
           outFile.println("<td width=\"60%\">" + depMethod + "</td>");
-          outFile.println("</tr>");
         }
+        outFile.println("</tr>");
+      }
     }
   }
 }
diff --git a/tools/soyc-vis/src/com/google/gwt/soyc/SoycDashboard.java b/tools/soyc-vis/src/com/google/gwt/soyc/SoycDashboard.java
index 4afe351..2d060fd 100644
--- a/tools/soyc-vis/src/com/google/gwt/soyc/SoycDashboard.java
+++ b/tools/soyc-vis/src/com/google/gwt/soyc/SoycDashboard.java
@@ -31,53 +31,59 @@
 import javax.xml.parsers.*;
 
 public class SoycDashboard {
-  
+
   /**
    * @param args Input: XML file containing soyc compile output
-   * @throws IOException 
-   * @throws SAXException 
+   * @throws IOException
+   * @throws SAXException
    */
   public static void main(String[] args) {
-    
-    String inFileName = "";
-    String depInFileName = "";
-    if ((args.length != 1) && (args.length != 2)){
 
-      if (args.length == 1){
+    String storiesFileName = "";
+    String depFileName = "";
+    String splitPointsFileName = "";
+    if ((args.length == 1) || (args.length == 2) || (args.length == 3)) {
+
+      if (args.length == 1) {
         GlobalInformation.displayDependencies = false;
-      }
-      else{
+        GlobalInformation.displaySplitPoints = true;
+      } else if (args.length == 2) {
         GlobalInformation.displayDependencies = true;
-        depInFileName = args[1];
+        GlobalInformation.displaySplitPoints = false;
+        depFileName = args[1];
+      } else if (args.length == 3) {
+        GlobalInformation.displayDependencies = true;
+        GlobalInformation.displaySplitPoints = true;        
+        depFileName = args[1];
+        splitPointsFileName = args[2];
       }
       
-      System.err.println("Usage: java com/google/gwt/soyc/SoycDashboard soyc-report0.xml[.gz] soyc-dependencies0.xml[.gz] OR java com/google/gwt/soyc/SoycDashboard soyc-report0.xml[.gz]");
+    } else {
+      System.err.println("Usage: java com/google/gwt/soyc/SoycDashboard soyc-report0.xml[.gz] [soyc-dependencies0.xml[.gz]] [soyc-splitpoints0.xml[.gz]]");
       System.exit(1);
     }
-    
-    inFileName = args[0];
-    
-    
-    
-    if (GlobalInformation.displayDependencies == true){
+
+    storiesFileName = args[0];
+
+    if (GlobalInformation.displayDependencies == true) {
       /**
        * handle dependencies
        */
-  
+
       Map<String, ArrayList<String>> dependencies = new TreeMap<String, ArrayList<String>>();
       DefaultHandler depHandler = parseXMLDocumentDependencies(dependencies);
-      
+
       // start parsing
       SAXParserFactory depFactoryMain = SAXParserFactory.newInstance();
       depFactoryMain.setNamespaceAware(true);
       try {
         SAXParser saxParser = depFactoryMain.newSAXParser();
-        InputStream in = new FileInputStream(depInFileName);
-        if (depInFileName.endsWith(".gz")) {
+        InputStream in = new FileInputStream(depFileName);
+        if (depFileName.endsWith(".gz")) {
           in = new GZIPInputStream(in);
         }
         in = new BufferedInputStream(in);
-        saxParser.parse(in,depHandler);
+        saxParser.parse(in, depHandler);
       } catch (ParserConfigurationException e) {
         throw new RuntimeException("Could not parse document. ", e);
       } catch (SAXException e) {
@@ -87,56 +93,93 @@
       } catch (IOException e) {
         throw new RuntimeException("Could not open file. ", e);
       }
-      
-      try{
+
+      try {
         MakeTopLevelHtmlForPerm.makeDependenciesHtml(dependencies);
       } catch (IOException e) {
         throw new RuntimeException("Cannot open file. ", e);
       }
     }
+
+    if (GlobalInformation.displaySplitPoints == true) {
+      /** handle runAsync split points
+       */
+
+      DefaultHandler splitPointHandler = parseXMLDocumentSplitPoints();
+
+      // start parsing
+      SAXParserFactory splitPointsFactoryMain = SAXParserFactory.newInstance();
+      splitPointsFactoryMain.setNamespaceAware(true);
+      try {
+        SAXParser saxParser = splitPointsFactoryMain.newSAXParser();
+        InputStream in = new FileInputStream(splitPointsFileName);
+        if (depFileName.endsWith(".gz")) {
+          in = new GZIPInputStream(in);
+        }
+        in = new BufferedInputStream(in);
+        saxParser.parse(in, splitPointHandler);
+      } catch (ParserConfigurationException e) {
+        throw new RuntimeException("Could not parse document. ", e);
+      } catch (SAXException e) {
+        throw new RuntimeException("Could not create SAX parser. ", e);
+      } catch (FileNotFoundException e) {
+        throw new RuntimeException("Could not open file. ", e);
+      } catch (IOException e) {
+        throw new RuntimeException("Could not open file. ", e);
+      }
+    }
+    
     
     /**
      * handle everything else
      */
 
     // to store literals data
-    GlobalInformation.nameToLitColl.put("long",new LiteralsCollection("long"));
-    GlobalInformation.nameToLitColl.put("null",new LiteralsCollection("null"));
-    GlobalInformation.nameToLitColl.put("class",new LiteralsCollection("class"));
-    GlobalInformation.nameToLitColl.put("int",new LiteralsCollection("int"));
-    GlobalInformation.nameToLitColl.put("string",new LiteralsCollection("string"));
-    GlobalInformation.nameToLitColl.put("number",new LiteralsCollection("number"));
-    GlobalInformation.nameToLitColl.put("boolean",new LiteralsCollection("boolean"));
-    GlobalInformation.nameToLitColl.put("double",new LiteralsCollection("double"));
-    GlobalInformation.nameToLitColl.put("char",new LiteralsCollection("char"));
-    GlobalInformation.nameToLitColl.put("undefined",new LiteralsCollection("undefined"));
-    GlobalInformation.nameToLitColl.put("float",new LiteralsCollection("float"));
-    
+    GlobalInformation.nameToLitColl.put("long", new LiteralsCollection("long"));
+    GlobalInformation.nameToLitColl.put("null", new LiteralsCollection("null"));
+    GlobalInformation.nameToLitColl.put("class",
+        new LiteralsCollection("class"));
+    GlobalInformation.nameToLitColl.put("int", new LiteralsCollection("int"));
+    GlobalInformation.nameToLitColl.put("string", new LiteralsCollection(
+        "string"));
+    GlobalInformation.nameToLitColl.put("number", new LiteralsCollection(
+        "number"));
+    GlobalInformation.nameToLitColl.put("boolean", new LiteralsCollection(
+        "boolean"));
+    GlobalInformation.nameToLitColl.put("double", new LiteralsCollection(
+        "double"));
+    GlobalInformation.nameToLitColl.put("char", new LiteralsCollection("char"));
+    GlobalInformation.nameToLitColl.put("undefined", new LiteralsCollection(
+        "undefined"));
+    GlobalInformation.nameToLitColl.put("float",
+        new LiteralsCollection("float"));
+
     // to store code data
-    GlobalInformation.nameToCodeColl.put("allOther", new CodeCollection("allOther"));
+    GlobalInformation.nameToCodeColl.put("allOther", new CodeCollection(
+        "allOther"));
     GlobalInformation.nameToCodeColl.put("widget", new CodeCollection("widget"));
-    GlobalInformation.nameToCodeColl.put("rpcUser", new CodeCollection("rpcUser"));
+    GlobalInformation.nameToCodeColl.put("rpcUser", new CodeCollection(
+        "rpcUser"));
     GlobalInformation.nameToCodeColl.put("rpcGen", new CodeCollection("rpcGen"));
     GlobalInformation.nameToCodeColl.put("rpcGwt", new CodeCollection("rpcGwt"));
     GlobalInformation.nameToCodeColl.put("gwtLang", new CodeCollection("long"));
     GlobalInformation.nameToCodeColl.put("jre", new CodeCollection("jre"));
-    
-    
-    // make the parser handler
-    DefaultHandler handler = parseXMLDocument(GlobalInformation.nameToLitColl, GlobalInformation.nameToCodeColl);
 
-    
+    // make the parser handler
+    DefaultHandler handler = parseXMLDocument(GlobalInformation.nameToLitColl,
+        GlobalInformation.nameToCodeColl);
+
     // start parsing
     SAXParserFactory factoryMain = SAXParserFactory.newInstance();
     factoryMain.setNamespaceAware(true);
     try {
       SAXParser saxParser = factoryMain.newSAXParser();
-      InputStream in = new FileInputStream(inFileName);
-      if (inFileName.endsWith(".gz")) {
+      InputStream in = new FileInputStream(storiesFileName);
+      if (storiesFileName.endsWith(".gz")) {
         in = new GZIPInputStream(in);
       }
       in = new BufferedInputStream(in);
-      saxParser.parse(in,handler);
+      saxParser.parse(in, handler);
     } catch (ParserConfigurationException e) {
       throw new RuntimeException("Could not parse document. ", e);
     } catch (SAXException e) {
@@ -149,25 +192,25 @@
 
     // add to "All Other Code" if none of the special categories apply
     updateAllOtherCodeType(GlobalInformation.nameToCodeColl);
-    
+
     // now we need to aggregate numbers
     GlobalInformation.computePackageSizes();
     GlobalInformation.computePartialPackageSizes();
-    
+
     // clean up the RPC categories
     foldInRPCHeuristic(GlobalInformation.nameToCodeColl);
-    
+
     // generate all the html files
-    makeHTMLFiles(GlobalInformation.nameToLitColl, GlobalInformation.nameToCodeColl); 
-    
+    makeHTMLFiles(GlobalInformation.nameToLitColl,
+        GlobalInformation.nameToCodeColl);
+
     System.out.println("Finished creating reports. To see the dashboard, open SoycDashboard-index.html in your browser.");
   }
 
-
   private static DefaultHandler parseXMLDocument(
       final TreeMap<String, LiteralsCollection> nameToLitColl,
       final HashMap<String, CodeCollection> nameToCodeColl) {
-    
+
     DefaultHandler handler = new DefaultHandler() {
 
       String curStoryId;
@@ -178,302 +221,297 @@
       HashSet<String> curRelevantLitTypes = new HashSet<String>();
       HashSet<String> curRelevantCodeTypes = new HashSet<String>();
       String curClassId;
-      String curPackage;
       Integer curFragment;
-      String curFunctionId = "";
       boolean specialCodeType = false;
       StringBuilder valueBuilder = new StringBuilder();
       int ct = 0;
       boolean fragmentInLoadOrder = false;
-      
+
       /**
-       * This method deals with the beginning of the XML element.
-       * It analyzes the XML node and adds its information to the relevant literal or code collection for later analysis.
-       * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+       * This method deals with the beginning of the XML element. It analyzes
+       * the XML node and adds its information to the relevant literal or code
+       * collection for later analysis.
+       * 
+       * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
+       *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
        */
       @Override
-      public void startElement(String nsUri, String strippedName, String tagName, Attributes attributes) {
-        
-        if ((ct % 10000) == 0){
+      public void startElement(String nsUri, String strippedName,
+          String tagName, Attributes attributes) {
+
+        if ((ct % 10000) == 0) {
           System.out.println(ct);
         }
         ct++;
-        
-        valueBuilder.delete(0,valueBuilder.length());
-        
-        if (strippedName.compareTo("splitpoint") == 0){
-          System.out.println("about to process splitpoint");
-         parseSplitPoint(attributes); 
-        }
-        else if ((strippedName.compareTo("package") == 0)&&(attributes.getValue("id") != null)){
-          curPackage = attributes.getValue("id");
-          
-          if (curPackage.compareTo("") == 0){
-            curPackage = "emptyPackageName";
-          }
-          
-          if (! GlobalInformation.packageToClasses.containsKey(curPackage)){
-            TreeSet<String> insertSet = new TreeSet<String>();
-            GlobalInformation.packageToClasses.put(curPackage, insertSet);
-          }
-        }
-        
-        else if (strippedName.compareTo("class") == 0){
-          
-          parseClass(nameToCodeColl, attributes);
-        }
 
-        else if (strippedName.compareTo("function") == 0){
-          if (attributes.getValue("id") != null){
-            curFunctionId = attributes.getValue("id");
-          }
-        }
-        
-        //TODO(kprobst): not currently used, but will be for dependencies
-        else if (strippedName.compareTo("on") == 0){
-          parseDependsOn(nameToCodeColl, attributes);
-        }
-        
-        else if (strippedName.compareTo("of") == 0){
-          parseOverrides(nameToCodeColl, attributes);
-        }
+        valueBuilder.delete(0, valueBuilder.length());
 
-        else if (strippedName.compareTo("by") == 0){
-          parseCorrelations(nameToCodeColl, attributes);
-        }
-
-        else if (strippedName.compareTo("story") == 0){
+        if (strippedName.compareTo("story") == 0) {
           parseStory(attributes);
         }
         
-        else if (strippedName.compareTo("origin") == 0){
+        else if (strippedName.compareTo("of") == 0) {
+          parseOverrides(nameToCodeColl, attributes);
+        }
+
+        else if (strippedName.compareTo("by") == 0) {
+          parseCorrelations(nameToCodeColl, attributes);
+        }
+
+        else if (strippedName.compareTo("origin") == 0) {
           parseOrigins(nameToLitColl, attributes);
         }
-        
-        else if (strippedName.compareTo("js") == 0){
-          if (attributes.getValue("fragment") != null){
+
+        else if (strippedName.compareTo("js") == 0) {
+          if (attributes.getValue("fragment") != null) {
             // ignore all code that is not in the first load order
-            
+
             curFragment = Integer.parseInt(attributes.getValue("fragment"));
-            if((curFragment == 0)||
-                (curFragment == (GlobalInformation.numSplitPoints+1))||
-                (curFragment == (GlobalInformation.numSplitPoints+2))||
-                ((curFragment >= 2) && (curFragment <= GlobalInformation.numSplitPoints))){
+            if ((curFragment == 0)
+                || (curFragment == (GlobalInformation.numSplitPoints + 1))
+                || (curFragment == (GlobalInformation.numSplitPoints + 2))
+                || ((curFragment >= 2) && (curFragment <= GlobalInformation.numSplitPoints))) {
               fragmentInLoadOrder = true;
-            }
-            else{
+            } else {
               fragmentInLoadOrder = false;
             }
-          }
-          else{
-           
+          } else {
+
             curFragment = -2;
           }
         }
 
-        else if (strippedName.compareTo("storyref") == 0){
+        else if (strippedName.compareTo("storyref") == 0) {
           parseJs(nameToLitColl, nameToCodeColl, attributes, curFragment);
         }
       }
 
-      
       /**
-       * This method collects a block of the value of the current XML node that the SAX parser parses.
-       * It simply adds to the the previous blocks, so that we can collect the entire value block.
+       * This method collects a block of the value of the current XML node that
+       * the SAX parser parses. It simply adds to the the previous blocks, so
+       * that we can collect the entire value block.
        */
-       @Override
-      public void characters (char ch[], int start, int length){
-         valueBuilder.append(ch, start, length);
-       }
-      
-
-     /**
-      * This method marks the end of an XML element that the SAX parser parses.
-      * It has access to the full value of the node and uses it add information to the relevant literal or code collections.
-      * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
-      */
       @Override
-      public void endElement (String  nsUri, String strippedName, String qName){
-        String value = valueBuilder.toString();
+      public void characters(char ch[], int start, int length) {
+        valueBuilder.append(ch, start, length);
+      }
+
+      /**
+       * This method marks the end of an XML element that the SAX parser parses.
+       * It has access to the full value of the node and uses it to add information
+       * to the relevant literal or code collections.
+       * 
+       * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
+       *      java.lang.String, java.lang.String)
+       */
+      @Override
+      public void endElement(String nsUri, String strippedName, String qName) {
         
-        int numBytes = value.getBytes().length;
-          
-        if (curStoryRef != null){
-          
-          //add this size to the current fragment
-          if (GlobalInformation.storiesToCorrClasses.containsKey(curStoryRef)){
-            
-            if ((GlobalInformation.storiesToLitType.containsKey(curStoryRef))&&(GlobalInformation.storiesToCorrClasses.get(curStoryRef).size() > 0)){
-             GlobalInformation.numBytesDoubleCounted += numBytes;
-            }
-            
-            float partialSize = (float)numBytes / (float)GlobalInformation.storiesToCorrClasses.get(curStoryRef).size();                               
-            if (!GlobalInformation.fragmentToPartialSize.containsKey(curFragment)){
-              GlobalInformation.fragmentToPartialSize.put(curFragment, partialSize);
-            }
-            else{
-              float newSize = GlobalInformation.fragmentToPartialSize.get(curFragment) + partialSize;
+        if (strippedName.compareTo("storyref") == 0){
+          String value = valueBuilder.toString();
+  
+          int numBytes = value.getBytes().length;
+          if (curStoryRef != null) {  
+            if (!GlobalInformation.fragmentToPartialSize.containsKey(curFragment)) {
+              GlobalInformation.fragmentToPartialSize.put(curFragment,
+                  (float)numBytes);
+            } else {
+              float newSize = GlobalInformation.fragmentToPartialSize.get(curFragment)
+                  + (float)numBytes;
               GlobalInformation.fragmentToPartialSize.put(curFragment, newSize);
             }
-                    
-            // now do different things depending on whether this fragment is in the load order or not
-            if (fragmentInLoadOrder == false){
+  
+            // now do different things depending on whether this fragment is in
+            // the load order or not
+            if (fragmentInLoadOrder == false) {
               GlobalInformation.allOtherFragmentsPartialSize += numBytes;
-            }
-            else{
+            } else {
               GlobalInformation.cumSizeAllCode += numBytes;
-              
-              if ((!GlobalInformation.storiesToLitType.containsKey(curStoryRef))&&
-                  (!GlobalInformation.storiesToCorrClasses.containsKey(curStoryRef))){
-                 GlobalInformation.nonAttributedStories.add(curStoryRef);
-                 GlobalInformation.nonAttributedBytes += numBytes;
+            }
+            
+            
+            // add this size to the classes associated with it
+            if (GlobalInformation.storiesToCorrClasses.containsKey(curStoryRef)) {
+  
+              if ((GlobalInformation.storiesToLitType.containsKey(curStoryRef))
+                  && (GlobalInformation.storiesToCorrClasses.get(curStoryRef).size() > 0)) {
+                GlobalInformation.numBytesDoubleCounted += numBytes;
               }
-            
-            
-              // go through all the classes for this story
-              for (String className : GlobalInformation.storiesToCorrClasses.get(curStoryRef)){
-                // get the corresponding package
-                if (GlobalInformation.classToPackage.containsKey(className)){
-                  String packageName = GlobalInformation.classToPackage.get(className);
+  
+              float partialSize = (float) numBytes
+                  / (float) GlobalInformation.storiesToCorrClasses.get(
+                      curStoryRef).size();
+  
+              // now do different things depending on whether this fragment is in
+              // the load order or not
+              if (fragmentInLoadOrder == true) {
+                if ((!GlobalInformation.storiesToLitType.containsKey(curStoryRef))
+                    && (!GlobalInformation.storiesToCorrClasses.containsKey(curStoryRef))) {
+                  GlobalInformation.nonAttributedStories.add(curStoryRef);
+                  GlobalInformation.nonAttributedBytes += numBytes;
+                }
+  
+                // go through all the classes for this story
+                for (String className : GlobalInformation.storiesToCorrClasses.get(curStoryRef)) {
+                  // get the corresponding package
                   
-                  if (!GlobalInformation.packageToClasses.containsKey(packageName)){
+                  String packageName = "";
+                  
+                  
+                  if (!GlobalInformation.classToPackage.containsKey(className)) {
+                    //derive the package name from the class
+                    packageName = className;
+                    packageName = packageName.replaceAll("\\.[A-Z].*","");
+                    GlobalInformation.classToPackage.put(className, packageName); 
+                  }
+                  else{
+                    packageName = GlobalInformation.classToPackage.get(className);
+                  }
+                  parseClass(nameToCodeColl, className, packageName);
+
+                  if (!GlobalInformation.packageToClasses.containsKey(packageName)) {
                     TreeSet<String> insertSet = new TreeSet<String>();
                     insertSet.add(className);
-                    GlobalInformation.packageToClasses.put(packageName, insertSet);
+                    GlobalInformation.packageToClasses.put(packageName,
+                        insertSet);
+                  } else {
+                    GlobalInformation.packageToClasses.get(packageName).add(
+                        className);
                   }
-                  else{
-                    GlobalInformation.packageToClasses.get(packageName).add(className);
-                  }
-                  
-                  if (GlobalInformation.classToSize.containsKey(className)){
-                    int newSize = GlobalInformation.classToSize.get(className) + numBytes;
+
+                  if (GlobalInformation.classToSize.containsKey(className)) {
+                    int newSize = GlobalInformation.classToSize.get(className)
+                        + numBytes;
                     GlobalInformation.classToSize.put(className, newSize);
+                  } else {
+                    GlobalInformation.classToSize.put(className, numBytes);
                   }
-                  else{
-                    GlobalInformation.classToSize.put(className, numBytes);  
-                  }
-                  
-                  if (GlobalInformation.classToPartialSize.containsKey(className)){
-                    float newSize = GlobalInformation.classToPartialSize.get(className) + partialSize;
+
+                  if (GlobalInformation.classToPartialSize.containsKey(className)) {
+                    float newSize = GlobalInformation.classToPartialSize.get(className)
+                        + partialSize;
                     GlobalInformation.classToPartialSize.put(className, newSize);
-                  }
-                  else{
-                    GlobalInformation.classToPartialSize.put(className, partialSize);  
+                  } else {
+                    GlobalInformation.classToPartialSize.put(className,
+                        partialSize);
                   }
                 }
               }
             }
+            updateLitTypes(nameToLitColl, value, numBytes);
           }
-          updateLitTypes(nameToLitColl, value, numBytes);    
         }
       }
 
-      
       /*
        * This method assigns strings to the appropriate category
        */
       private void updateLitTypes(
           final TreeMap<String, LiteralsCollection> nameToLitColl,
           String value, int numBytes) {
-        
+
         int iNumCounted = 0;
-        
-        for (String relLitType : curRelevantLitTypes){
+
+        for (String relLitType : curRelevantLitTypes) {
           iNumCounted++;
-          
-          //then give string literals special treatment
-          if (relLitType.compareTo("string") == 0){
-            
-            // note that this will double-count (i.e., it will count a string twice if it's in the output twice), as it should.
+
+          // then give string literals special treatment
+          if (relLitType.compareTo("string") == 0) {
+
+            // note that this will double-count (i.e., it will count a string
+            // twice if it's in the output twice), as it should.
             nameToLitColl.get("string").cumStringSize += numBytes;
             nameToLitColl.get(relLitType).cumSize += numBytes;
-                       
-            //get the origins
+
+            // get the origins
             HashSet<String> originSet = nameToLitColl.get("string").storyToLocations.get(curStoryRef);
-            
+
             // find the most appropriate string literal category
             String mostAppropriateCategory = "";
             String mostAppropriateLocation = "";
             String backupLocation = "";
-            for (String origin : originSet){
-              
-              if ((origin.contains("ClassLiteralHolder")) && (mostAppropriateCategory.compareTo("") == 0)){
+            for (String origin : originSet) {
+
+              if ((origin.contains("ClassLiteralHolder"))
+                  && (mostAppropriateCategory.compareTo("") == 0)) {
                 mostAppropriateCategory = "compiler";
                 mostAppropriateLocation = origin;
-              }
-              else if ((origin.startsWith("transient source for"))&&(origin.contains("_TypeSerializer")) && (mostAppropriateCategory.compareTo("") == 0)){
+              } else if ((origin.startsWith("transient source for"))
+                  && (origin.contains("_TypeSerializer"))
+                  && (mostAppropriateCategory.compareTo("") == 0)) {
                 mostAppropriateCategory = "transient";
                 mostAppropriateLocation = origin;
-              }
-              else if ((origin.contains("InlineResourceBundleGenerator")) && (mostAppropriateCategory.compareTo("") == 0)){
+              } else if ((origin.contains("InlineResourceBundleGenerator"))
+                  && (mostAppropriateCategory.compareTo("") == 0)) {
                 mostAppropriateCategory = "inlinedTextRes";
                 mostAppropriateLocation = origin;
               }
-              if (origin.compareTo("com.google.gwt.dev.js.ast.JsProgram: Line 0") != 0){
+              if (origin.compareTo("com.google.gwt.dev.js.ast.JsProgram: Line 0") != 0) {
                 backupLocation = origin;
               }
             }
 
-            if (backupLocation.compareTo("") == 0){
+            if (backupLocation.compareTo("") == 0) {
               backupLocation = "com.google.gwt.dev.js.ast.JsProgram: Line 0";
             }
-            if ((((value.startsWith("'")) && (value.endsWith("'"))) ||
-                ((value.startsWith("\""))&&(value.endsWith("\"")))) &&
-                (mostAppropriateCategory.compareTo("") == 0)){
+            if ((((value.startsWith("'")) && (value.endsWith("'"))) || ((value.startsWith("\"")) && (value.endsWith("\""))))
+                && (mostAppropriateCategory.compareTo("") == 0)) {
               mostAppropriateCategory = "user";
               mostAppropriateLocation = backupLocation;
-            }
-            else if (mostAppropriateCategory.compareTo("") == 0){
+            } else if (mostAppropriateCategory.compareTo("") == 0) {
               mostAppropriateCategory = "otherStrings";
               mostAppropriateLocation = backupLocation;
             }
-                        
-            if (!nameToLitColl.get("string").stringLiteralToType.containsKey(value)){
-              nameToLitColl.get("string").stringLiteralToType.put(value, mostAppropriateCategory);
-              if (!nameToLitColl.get("string").stringTypeToCount.containsKey(mostAppropriateCategory)){
-                   nameToLitColl.get("string").stringTypeToCount.put(mostAppropriateCategory, 1); 
-              }
-              else{
-                int iNewCount = nameToLitColl.get("string").stringTypeToCount.get(mostAppropriateCategory) + 1; 
-                nameToLitColl.get("string").stringTypeToCount.put(mostAppropriateCategory, iNewCount); 
+
+            if (!nameToLitColl.get("string").stringLiteralToType.containsKey(value)) {
+              nameToLitColl.get("string").stringLiteralToType.put(value,
+                  mostAppropriateCategory);
+              if (!nameToLitColl.get("string").stringTypeToCount.containsKey(mostAppropriateCategory)) {
+                nameToLitColl.get("string").stringTypeToCount.put(
+                    mostAppropriateCategory, 1);
+              } else {
+                int iNewCount = nameToLitColl.get("string").stringTypeToCount.get(mostAppropriateCategory) + 1;
+                nameToLitColl.get("string").stringTypeToCount.put(
+                    mostAppropriateCategory, iNewCount);
               }
 
-              
               int iNewSize = numBytes;
-              if (nameToLitColl.get("string").stringTypeToSize.containsKey(mostAppropriateCategory)){
+              if (nameToLitColl.get("string").stringTypeToSize.containsKey(mostAppropriateCategory)) {
                 iNewSize += nameToLitColl.get("string").stringTypeToSize.get(mostAppropriateCategory);
               }
-              nameToLitColl.get("string").stringTypeToSize.put(mostAppropriateCategory, iNewSize);
+              nameToLitColl.get("string").stringTypeToSize.put(
+                  mostAppropriateCategory, iNewSize);
 
-
-              if (nameToLitColl.get("string").storyToLocations.containsKey(curStoryRef)){
+              if (nameToLitColl.get("string").storyToLocations.containsKey(curStoryRef)) {
                 HashSet<String> insertSet = new HashSet<String>();
                 insertSet.add(mostAppropriateLocation);
-                nameToLitColl.get(relLitType).literalToLocations.put(value,insertSet);
+                nameToLitColl.get(relLitType).literalToLocations.put(value,
+                    insertSet);
               }
-            } 
+            }
           }
 
-          else{
-            // note that this will double-count (i.e., it will count a literal twice if it's in the output twice), as it should.
+          else {
+            // note that this will double-count (i.e., it will count a literal
+            // twice if it's in the output twice), as it should.
             nameToLitColl.get(relLitType).cumSize += numBytes;
-            
-            if (nameToLitColl.get(relLitType).storyToLocations.containsKey(curStoryRef)){
-              if (nameToLitColl.get(relLitType).literalToLocations.containsKey(value)){
-                nameToLitColl.get(relLitType).literalToLocations.get(value).addAll(nameToLitColl.get(relLitType).
-                      storyToLocations.get(curStoryRef));
-              }
-              else{
+
+            if (nameToLitColl.get(relLitType).storyToLocations.containsKey(curStoryRef)) {
+              if (nameToLitColl.get(relLitType).literalToLocations.containsKey(value)) {
+                nameToLitColl.get(relLitType).literalToLocations.get(value).addAll(
+                    nameToLitColl.get(relLitType).storyToLocations.get(curStoryRef));
+              } else {
                 HashSet<String> insertSet = nameToLitColl.get(relLitType).storyToLocations.get(curStoryRef);
-                nameToLitColl.get(relLitType).literalToLocations.put(value,insertSet);
+                nameToLitColl.get(relLitType).literalToLocations.put(value,
+                    insertSet);
               }
-              
+
             }
-          }          
+          }
         }
       }
-      
-      /* 
+
+      /*
        * parses the "JS" portion of the XML file
        */
       private void parseJs(
@@ -482,39 +520,39 @@
           Attributes attributes, Integer curFragment) {
         curRelevantLitTypes.clear();
         curRelevantCodeTypes.clear();
-        
-        if (attributes.getValue("idref") != null){
-          
+
+        if (attributes.getValue("idref") != null) {
+
           curStoryRef = attributes.getValue("idref");
-          
-          if (curFragment != -1){
-            //add this to the stories for this fragment
-            if (!GlobalInformation.fragmentToStories.containsKey(curFragment)){
+
+          if (curFragment != -1) {
+            // add this to the stories for this fragment
+            if (!GlobalInformation.fragmentToStories.containsKey(curFragment)) {
               HashSet<String> insertSet = new HashSet<String>();
               insertSet.add(curStoryRef);
               GlobalInformation.fragmentToStories.put(curFragment, insertSet);
-            }
-            else{
-              GlobalInformation.fragmentToStories.get(curFragment).add(curStoryRef);
+            } else {
+              GlobalInformation.fragmentToStories.get(curFragment).add(
+                  curStoryRef);
             }
           }
-          
-          for (String litType : nameToLitColl.keySet()){
-            if (nameToLitColl.get(litType).storyToLocations.containsKey(curStoryRef)){
+
+          for (String litType : nameToLitColl.keySet()) {
+            if (nameToLitColl.get(litType).storyToLocations.containsKey(curStoryRef)) {
               curRelevantLitTypes.add(litType);
             }
           }
-          
+
           specialCodeType = false;
-          for (String codeType : nameToCodeColl.keySet()){
-            if (nameToCodeColl.get(codeType).stories.contains(curStoryRef)){
+          for (String codeType : nameToCodeColl.keySet()) {
+            if (nameToCodeColl.get(codeType).stories.contains(curStoryRef)) {
               curRelevantCodeTypes.add(codeType);
               specialCodeType = true;
             }
           }
-          if (specialCodeType == false){
-                      
-              nameToCodeColl.get("allOther").stories.add(curStoryRef);
+          if (specialCodeType == false) {
+
+            nameToCodeColl.get("allOther").stories.add(curStoryRef);
             curRelevantCodeTypes.add("allOther");
           }
         }
@@ -526,66 +564,43 @@
       private void parseOrigins(
           final TreeMap<String, LiteralsCollection> nameToLitColl,
           Attributes attributes) {
-        if ((curStoryLiteralType.compareTo("") != 0)&&
-            (attributes.getValue("lineNumber") != null)&&
-            (attributes.getValue("location") != null)){
+        if ((curStoryLiteralType.compareTo("") != 0)
+            && (attributes.getValue("lineNumber") != null)
+            && (attributes.getValue("location") != null)) {
           curLineNumber = attributes.getValue("lineNumber");
           curLocation = attributes.getValue("location");
           String curOrigin = curLocation + ": Line " + curLineNumber;
-          
-          if (!nameToLitColl.get(curStoryLiteralType).storyToLocations.containsKey(curStoryId)){
+
+          if (!nameToLitColl.get(curStoryLiteralType).storyToLocations.containsKey(curStoryId)) {
             HashSet<String> insertSet = new HashSet<String>();
             insertSet.add(curOrigin);
-            nameToLitColl.get(curStoryLiteralType).storyToLocations.put(curStoryId, insertSet);
-          }
-          else{
-            nameToLitColl.get(curStoryLiteralType).storyToLocations.get(curStoryId).add(curOrigin);
+            nameToLitColl.get(curStoryLiteralType).storyToLocations.put(
+                curStoryId, insertSet);
+          } else {
+            nameToLitColl.get(curStoryLiteralType).storyToLocations.get(
+                curStoryId).add(curOrigin);
           }
         }
       }
 
       /*
-       * parses the split points
-       */
-      private void parseSplitPoint(Attributes attributes){
-        System.out.println("processing split point");
-        if (attributes.getValue("id") != null){
-          String curSplitPoint = attributes.getValue("id");
-          System.out.println("\tcurSplitPoint is: " + curSplitPoint);
-          if (attributes.getValue("location") != null){
-            String curSplitPointLocation = attributes.getValue("location");
-            
-            curSplitPointLocation = curSplitPointLocation.replaceAll("\\(L.*","");
-            
-            System.out.println("\tcurSplitPointLocation is: " + curSplitPointLocation);
-            GlobalInformation.splitPointToLocation.put(Integer.parseInt(curSplitPoint), curSplitPointLocation);
-            GlobalInformation.numSplitPoints++;
-            
-            System.out.println("adding split point and location: " + curSplitPoint + "-->" + curSplitPointLocation);
-            System.out.println("\t(Number of split points is now: " + GlobalInformation.numSplitPoints + ")");
-            
-          }
-        }
-      }
-      
-      /*
        * parses the "story" portion of the XML file
        */
       private void parseStory(Attributes attributes) {
-        if (attributes.getValue("id") != null){
+        if (attributes.getValue("id") != null) {
           curStoryId = attributes.getValue("id");
-          if (attributes.getValue("literal") != null){
+          if (attributes.getValue("literal") != null) {
             curStoryLiteralType = attributes.getValue("literal");
-            GlobalInformation.storiesToLitType.put(curStoryId, curStoryLiteralType);
-            
+            GlobalInformation.storiesToLitType.put(curStoryId,
+                curStoryLiteralType);
 
-            if (!nameToLitColl.get(curStoryLiteralType).storyToLocations.containsKey(curStoryId)){
+            if (!nameToLitColl.get(curStoryLiteralType).storyToLocations.containsKey(curStoryId)) {
               HashSet<String> insertSet = new HashSet<String>();
-              nameToLitColl.get(curStoryLiteralType).storyToLocations.put(curStoryId, insertSet);
+              nameToLitColl.get(curStoryLiteralType).storyToLocations.put(
+                  curStoryId, insertSet);
             }
-            
-          }
-          else{
+
+          } else {
             curStoryLiteralType = "";
           }
         }
@@ -598,41 +613,37 @@
           final HashMap<String, CodeCollection> nameToCodeColl,
           Attributes attributes) {
         
-        if (attributes.getValue("idref") != null){
-          
+        if (attributes.getValue("idref") != null) {
+
           String corrClassOrMethod = attributes.getValue("idref");
-          
           String corrClass = attributes.getValue("idref");
- 
-          if (corrClass.contains(":")){
+
+          if (corrClass.contains(":")) {
             corrClass = corrClass.replaceAll(":.*", "");
           }
-          
-          if (GlobalInformation.classToPackage.containsKey(corrClass)){ //if we know about this class
-            
-            if (! GlobalInformation.storiesToCorrClassesAndMethods.containsKey(curStoryId)){
-              HashSet<String> insertSet = new HashSet<String>();
-              insertSet.add(corrClassOrMethod);
-              GlobalInformation.storiesToCorrClassesAndMethods.put(curStoryId, insertSet);
-            }
-            else{
-              GlobalInformation.storiesToCorrClassesAndMethods.get(curStoryId).add(corrClassOrMethod);
-            }
-            
-  
-            if (! GlobalInformation.storiesToCorrClasses.containsKey(curStoryId)){
-              HashSet<String> insertSet = new HashSet<String>();
-              insertSet.add(corrClass);
-              GlobalInformation.storiesToCorrClasses.put(curStoryId, insertSet);
-            }
-            else{
-              GlobalInformation.storiesToCorrClasses.get(curStoryId).add(corrClass);
-            }
-            
-            for (String codeType : nameToCodeColl.keySet()){
-              if (nameToCodeColl.get(codeType).classes.contains(corrClass)){
-                nameToCodeColl.get(codeType).stories.add(curStoryId);
-              }
+
+          if (!GlobalInformation.storiesToCorrClassesAndMethods.containsKey(curStoryId)) {
+            HashSet<String> insertSet = new HashSet<String>();
+            insertSet.add(corrClassOrMethod);
+            GlobalInformation.storiesToCorrClassesAndMethods.put(curStoryId,
+                insertSet);
+          } else {
+            GlobalInformation.storiesToCorrClassesAndMethods.get(curStoryId).add(
+                corrClassOrMethod);
+          }
+
+          if (!GlobalInformation.storiesToCorrClasses.containsKey(curStoryId)) {
+            HashSet<String> insertSet = new HashSet<String>();
+            insertSet.add(corrClass);
+            GlobalInformation.storiesToCorrClasses.put(curStoryId, insertSet);
+          } else {
+            GlobalInformation.storiesToCorrClasses.get(curStoryId).add(
+                corrClass);
+          }
+
+          for (String codeType : nameToCodeColl.keySet()) {
+            if (nameToCodeColl.get(codeType).classes.contains(corrClass)) {
+              nameToCodeColl.get(codeType).stories.add(curStoryId);
             }
           }
         }
@@ -644,23 +655,21 @@
       private void parseOverrides(
           final HashMap<String, CodeCollection> nameToCodeColl,
           Attributes attributes) {
-        if (attributes.getValue("idref") != null){
+        if (attributes.getValue("idref") != null) {
           String overriddenClass = attributes.getValue("idref");
-          
 
-          //TODO(kprobst): fix this -- we either generalize to classes, or the numbers are messed up...
-          if (overriddenClass.contains(":")){
+          // we either generalize to classes, or the
+          // numbers are messed up...
+          if (overriddenClass.contains(":")) {
             overriddenClass = overriddenClass.replaceAll(":.*", "");
           }
-          
-          if (overriddenClass.compareTo("com.google.gwt.user.client.ui.UIObject") == 0){
+
+          if (overriddenClass.compareTo("com.google.gwt.user.client.ui.UIObject") == 0) {
             nameToCodeColl.get("widget").classes.add(curClassId);
-          }
-          else if (overriddenClass.contains("java.io.Serializable") || 
-                   overriddenClass.contains("IsSerializable")){
+          } else if (overriddenClass.contains("java.io.Serializable")
+              || overriddenClass.contains("IsSerializable")) {
             nameToCodeColl.get("rpcUser").classes.add(curClassId);
-          }
-          else if (overriddenClass.contains("com.google.gwt.user.client.rpc.core.java")){
+          } else if (overriddenClass.contains("com.google.gwt.user.client.rpc.core.java")) {
             nameToCodeColl.get("rpcGwt").classes.add(curClassId);
           }
         }
@@ -669,97 +678,96 @@
       /*
        * parses the "class" portion of the XML file
        */
-      private void parseClass(
-          final HashMap<String, CodeCollection> nameToCodeColl,
-          Attributes attributes) {
-        if (attributes.getValue("id") != null){
-          curClassId = attributes.getValue("id");
+      private void parseClass(final HashMap<String, CodeCollection> nameToCodeColl,
+          String curClassId, String curPackage) {
+        //if (attributes.getValue("id") != null) {
+        //  curClassId = attributes.getValue("id");
 
-          GlobalInformation.classToPackage.put(curClassId, curPackage);
+        //  GlobalInformation.classToPackage.put(curClassId, curPackage);
 
-          if (curPackage.startsWith("java")){
+          if (curPackage.startsWith("java")) {
             nameToCodeColl.get("jre").classes.add(curClassId);
-          }
-          else if (curPackage.startsWith("com.google.gwt.lang")){
+          } else if (curPackage.startsWith("com.google.gwt.lang")) {
             nameToCodeColl.get("gwtLang").classes.add(curClassId);
           }
-          if (curClassId.contains("_CustomFieldSerializer")){
+          if (curClassId.contains("_CustomFieldSerializer")) {
             nameToCodeColl.get("rpcUser").classes.add(curClassId);
-          }
-          else if (curClassId.endsWith("_FieldSerializer") || 
-                    curClassId.endsWith("_Proxy") ||
-                    curClassId.endsWith("_TypeSerializer")){
+          } else if (curClassId.endsWith("_FieldSerializer")
+              || curClassId.endsWith("_Proxy")
+              || curClassId.endsWith("_TypeSerializer")) {
             nameToCodeColl.get("rpcGen").classes.add(curClassId);
           }
-        }
+        //}
       }
-      
+
       /*
        * parses the "depends on" portion of the XML file
        */
-      private void parseDependsOn(final HashMap<String, CodeCollection> nameToCodeColl, Attributes attributes) {
-        if (curFunctionId.compareTo("") == 0){
-          if (attributes.getValue("idref") != null){
+/*      private void parseDependsOn(
+          final HashMap<String, CodeCollection> nameToCodeColl,
+          Attributes attributes) {
+        if (curFunctionId.compareTo("") == 0) {
+          if (attributes.getValue("idref") != null) {
             String curDepClassId = attributes.getValue("idref");
-  
-            if (curDepClassId.contains(":")){
-              // strip everything after the :: (to get to class, even if it's a method)
+
+            if (curDepClassId.contains(":")) {
+              // strip everything after the :: (to get to class, even if it's a
+              // method)
               curDepClassId = curDepClassId.replaceAll(":.*", "");
             }
- 
-            if (curDepClassId.contains(".")){
-              if (! GlobalInformation.classToWhatItDependsOn.containsKey(curClassId)){
+
+            if (curDepClassId.contains(".")) {
+              if (!GlobalInformation.classToWhatItDependsOn.containsKey(curClassId)) {
                 HashSet<String> insertSet = new HashSet<String>();
                 insertSet.add(curDepClassId);
-                GlobalInformation.classToWhatItDependsOn.put(curClassId, insertSet);
-              }
-              else{
-                GlobalInformation.classToWhatItDependsOn.get(curClassId).add(curDepClassId);
+                GlobalInformation.classToWhatItDependsOn.put(curClassId,
+                    insertSet);
+              } else {
+                GlobalInformation.classToWhatItDependsOn.get(curClassId).add(
+                    curDepClassId);
               }
             }
           }
         }
-      }
+      }*/
     };
     return handler;
   }
-  
 
-  
-  
-  
+  private static DefaultHandler parseXMLDocumentDependencies(
+      final Map<String, ArrayList<String>> dependencies) {
 
-
-  private static DefaultHandler parseXMLDocumentDependencies(final Map<String, ArrayList<String>> dependencies) { 
-    
     DefaultHandler handler = new DefaultHandler() {
 
       StringBuilder valueBuilder = new StringBuilder();
       // may want to create a class for this later
       String curMethod;
-        
+
       /**
-       * This method deals with the beginning of the XML element.
-       * It analyzes the XML node and adds its information to the relevant literal or code collection for later analysis.
-       * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+       * This method deals with the beginning of the XML element. It analyzes
+       * the XML node and adds its information to the relevant literal or code
+       * collection for later analysis.
+       * 
+       * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
+       *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
        */
       @Override
-      public void startElement(String nsUri, String strippedName, String tagName, Attributes attributes) {
-      
-        valueBuilder.delete(0,valueBuilder.length());
-        
-        
-        if ((strippedName.compareTo("method") == 0)&&(attributes.getValue("name") != null)){
+      public void startElement(String nsUri, String strippedName,
+          String tagName, Attributes attributes) {
+
+        valueBuilder.delete(0, valueBuilder.length());
+
+        if ((strippedName.compareTo("method") == 0)
+            && (attributes.getValue("name") != null)) {
           curMethod = attributes.getValue("name");
-        }
-        else if ((strippedName.compareTo("called") == 0)&&(attributes.getValue("by") != null)){
+        } else if ((strippedName.compareTo("called") == 0)
+            && (attributes.getValue("by") != null)) {
           String curDepMethod = attributes.getValue("by");
-          if (!dependencies.containsKey(curMethod)){
+          if (!dependencies.containsKey(curMethod)) {
             ArrayList<String> insertArray = new ArrayList<String>();
             insertArray.add(curDepMethod);
             dependencies.put(curMethod, insertArray);
-          }
-          else{
+          } else {
             dependencies.get(curMethod).add(curDepMethod);
           }
         }
@@ -768,10 +776,56 @@
     };
     return handler;
   }
-  
 
-  
-  
+  private static DefaultHandler parseXMLDocumentSplitPoints() {
+
+    DefaultHandler handler = new DefaultHandler() {
+
+      /**
+       * This method deals with the beginning of the XML element. It analyzes
+       * the XML node and adds its information to the relevant literal or code
+       * collection for later analysis.
+       * 
+       * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
+       *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
+       */
+      @Override
+      public void startElement(String nsUri, String strippedName,
+          String tagName, Attributes attributes) {
+        if (strippedName.compareTo("splitpoint") == 0) {
+          parseSplitPoint(attributes);
+        }
+      }
+      
+      /*
+       * parses the split points
+       */
+      private void parseSplitPoint(Attributes attributes) {
+        if (attributes.getValue("id") != null) {
+          String curSplitPoint = attributes.getValue("id");
+          if (attributes.getValue("location") != null) {
+            String curSplitPointLocation = attributes.getValue("location");
+
+            curSplitPointLocation = curSplitPointLocation.replaceAll("\\(L.*",
+                "");
+
+            GlobalInformation.splitPointToLocation.put(
+                Integer.parseInt(curSplitPoint), curSplitPointLocation);
+            GlobalInformation.numSplitPoints++;
+
+            System.out.println("adding split point and location: "
+                + curSplitPoint + "-->" + curSplitPointLocation);
+          }
+        }
+      }
+
+
+      
+    };
+    return handler;
+  }
+
+
   
   /*
    * cleans up the RPC code categories
@@ -779,37 +833,35 @@
   private static void foldInRPCHeuristic(
       final HashMap<String, CodeCollection> nameToCodeColl) {
     /**
-     * Heuristic: this moves all classes that override serializable from RPC to "Other Code" *if* there is no RPC generated code, i.e., if the 
+     * Heuristic: this moves all classes that override serializable from RPC to
+     * "Other Code" *if* there is no RPC generated code, i.e., if the
      * application really is not using RPC
      */
-    
-  
-    if (nameToCodeColl.get("rpcGen").classes.size() == 0){
-      
-      for (String className : nameToCodeColl.get("rpcUser").classes){
-        
-        if ((! nameToCodeColl.get("widget").classes.contains(className))&&
-            (! nameToCodeColl.get("jre").classes.contains(className))&&
-            (! nameToCodeColl.get("gwtLang").classes.contains(className))){
-          nameToCodeColl.get("allOther").classes.add(className);          
-        } 
+
+    if (nameToCodeColl.get("rpcGen").classes.size() == 0) {
+
+      for (String className : nameToCodeColl.get("rpcUser").classes) {
+
+        if ((!nameToCodeColl.get("widget").classes.contains(className))
+            && (!nameToCodeColl.get("jre").classes.contains(className))
+            && (!nameToCodeColl.get("gwtLang").classes.contains(className))) {
+          nameToCodeColl.get("allOther").classes.add(className);
+        }
       }
       nameToCodeColl.get("rpcUser").classes.clear();
-      
-      for (String className : nameToCodeColl.get("rpcGwt").classes){        
-        if ((! nameToCodeColl.get("widget").classes.contains(className))&&
-          (! nameToCodeColl.get("jre").classes.contains(className))&&
-          (! nameToCodeColl.get("gwtLang").classes.contains(className))){
-          nameToCodeColl.get("allOther").classes.add(className);          
-        } 
-  
+
+      for (String className : nameToCodeColl.get("rpcGwt").classes) {
+        if ((!nameToCodeColl.get("widget").classes.contains(className))
+            && (!nameToCodeColl.get("jre").classes.contains(className))
+            && (!nameToCodeColl.get("gwtLang").classes.contains(className))) {
+          nameToCodeColl.get("allOther").classes.add(className);
+        }
+
       }
       nameToCodeColl.get("rpcGwt").classes.clear();
     }
-            
-  
-  }
 
+  }
 
   /*
    * generates all the HTML files
@@ -823,57 +875,46 @@
       MakeTopLevelHtmlForPerm.makeCodeTypeClassesHtmls(nameToCodeColl);
       MakeTopLevelHtmlForPerm.makeLiteralsClassesTableHtmls(nameToLitColl);
       MakeTopLevelHtmlForPerm.makeStringLiteralsClassesTableHtmls(nameToLitColl);
-      // MakeTopLevelHtmlForPerm.makeFragmentClassesHtmls();
       MakeTopLevelHtmlForPerm.makeSplitPointClassesHtmls();
-      MakeTopLevelHtmlForPerm.makeDependenciesTableHtmls();
 
-      //make the shell last so we can display aggregate information here
+      // make the shell last so we can display aggregate information here
       MakeTopLevelHtmlForPerm.makeHTMLShell(nameToCodeColl, nameToLitColl);
-      
+
     } catch (IOException e) {
       throw new RuntimeException("Cannot open file. ", e);
     }
   }
 
-  
   /*
    * assigns code to "all other code" if none of the special categories apply
    */
-  private static void updateAllOtherCodeType(final HashMap<String, CodeCollection> nameToCodeColl){
-    //all classes not in any of the other categories
-    for (String className : GlobalInformation.classToPackage.keySet()){
-      if ( (!nameToCodeColl.get("widget").classes.contains(className))&&
-          (!nameToCodeColl.get("rpcUser").classes.contains(className))&&
-          (!nameToCodeColl.get("rpcGwt").classes.contains(className))&&
-          (!nameToCodeColl.get("rpcGen").classes.contains(className))&&
-          (!nameToCodeColl.get("jre").classes.contains(className))&&
-          (!nameToCodeColl.get("gwtLang").classes.contains(className))){
+  private static void updateAllOtherCodeType(
+      final HashMap<String, CodeCollection> nameToCodeColl) {
+    // all classes not in any of the other categories
+    for (String className : GlobalInformation.classToPackage.keySet()) {
+      if ((!nameToCodeColl.get("widget").classes.contains(className))
+          && (!nameToCodeColl.get("rpcUser").classes.contains(className))
+          && (!nameToCodeColl.get("rpcGwt").classes.contains(className))
+          && (!nameToCodeColl.get("rpcGen").classes.contains(className))
+          && (!nameToCodeColl.get("jre").classes.contains(className))
+          && (!nameToCodeColl.get("gwtLang").classes.contains(className))) {
         nameToCodeColl.get("allOther").classes.add(className);
       }
     }
   }
 
-
   /*
-   * unescape the JS snippets - in the XML file they are XML encoded for correct display, but this 
-   * will mess up the byte counts
+   * unescape the JS snippets - in the XML file they are XML encoded for correct
+   * display, but this will mess up the byte counts
    */
   public static String unEscapeXml(String escaped) {
-    String unescaped = escaped.replaceAll("&","\\&");
-    unescaped = unescaped.replaceAll("<","\\<");
-    unescaped = unescaped.replaceAll(">","\\>");
-    unescaped = unescaped.replaceAll(""","\\\"");
-    //escaped = escaped.replaceAll("\\n", "");
-    unescaped = unescaped.replaceAll("'","\\'");
+    String unescaped = escaped.replaceAll("&", "\\&");
+    unescaped = unescaped.replaceAll("<", "\\<");
+    unescaped = unescaped.replaceAll(">", "\\>");
+    unescaped = unescaped.replaceAll(""", "\\\"");
+    // escaped = escaped.replaceAll("\\n", "");
+    unescaped = unescaped.replaceAll("'", "\\'");
     return unescaped;
   }
-  
 
-  
-  
 }
-
-
-
-
-
diff --git a/user/src/com/google/gwt/core/Core.gwt.xml b/user/src/com/google/gwt/core/Core.gwt.xml
index b207319..d88d528 100644
--- a/user/src/com/google/gwt/core/Core.gwt.xml
+++ b/user/src/com/google/gwt/core/Core.gwt.xml
@@ -21,14 +21,11 @@
   <inherits name="com.google.gwt.dev.jjs.intrinsic.Intrinsic" />
   <inherits name="com.google.gwt.emul.Emulation" />
 
-  <define-linker name="soycReport" class="com.google.gwt.core.linker.soyc.SoycReportLinker" />
   <define-linker name="sso" class="com.google.gwt.core.linker.SingleScriptLinker" />
   <define-linker name="std" class="com.google.gwt.core.linker.IFrameLinker" />
   <define-linker name="symbolMaps" class="com.google.gwt.core.linker.SymbolMapsLinker" />
   <define-linker name="xs" class="com.google.gwt.core.linker.XSLinker" />
 
   <add-linker name="std" />
-  <add-linker name="soycReport" />
   <add-linker name="symbolMaps" />
-
 </module>