new version with WorkingCopy Management
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / builder / State.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/State.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/State.java
new file mode 100644 (file)
index 0000000..754ecbe
--- /dev/null
@@ -0,0 +1,612 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpeclipse.builder;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+
+import net.sourceforge.phpdt.internal.core.Util;
+import net.sourceforge.phpdt.internal.core.util.SimpleLookupTable;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+public class State {
+// NOTE: this state cannot contain types that are not defined in this project
+
+String javaProjectName;
+ClasspathMultiDirectory[] sourceLocations;
+ClasspathLocation[] binaryLocations;
+// keyed by the project relative path of the type (ie. "src1/p1/p2/A.java"), value is a ReferenceCollection or an AdditionalTypeCollection
+SimpleLookupTable references;
+// keyed by qualified type name "p1/p2/A", value is the project relative path which defines this type "src1/p1/p2/A.java"
+SimpleLookupTable typeLocators;
+
+int buildNumber;
+long lastStructuralBuildTime;
+SimpleLookupTable structuralBuildTimes;
+
+private String[] knownPackageNames; // of the form "p1/p2"
+
+static final byte VERSION = 0x0007;
+
+static final byte SOURCE_FOLDER = 1;
+static final byte BINARY_FOLDER = 2;
+static final byte EXTERNAL_JAR = 3;
+static final byte INTERNAL_JAR = 4;
+
+State() {
+}
+
+protected State(PHPBuilder javaBuilder) {
+       this.knownPackageNames = null;
+       this.javaProjectName = javaBuilder.currentProject.getName();
+       
+//     this.sourceLocations = javaBuilder.nameEnvironment.sourceLocations;
+//     this.binaryLocations = javaBuilder.nameEnvironment.binaryLocations;
+       this.references = new SimpleLookupTable(7);
+       this.typeLocators = new SimpleLookupTable(7);
+
+       this.buildNumber = 0; // indicates a full build
+       this.lastStructuralBuildTime = System.currentTimeMillis();
+       this.structuralBuildTimes = new SimpleLookupTable(3);
+}
+
+void copyFrom(State lastState) {
+       try {
+               this.knownPackageNames = null;
+               this.buildNumber = lastState.buildNumber + 1;
+               this.lastStructuralBuildTime = lastState.lastStructuralBuildTime;
+               this.references = (SimpleLookupTable) lastState.references.clone();
+               this.typeLocators = (SimpleLookupTable) lastState.typeLocators.clone();
+       } catch (CloneNotSupportedException e) {
+               this.references = new SimpleLookupTable(lastState.references.elementSize);
+               Object[] keyTable = lastState.references.keyTable;
+               Object[] valueTable = lastState.references.valueTable;
+               for (int i = 0, l = keyTable.length; i < l; i++)
+                       if (keyTable[i] != null)
+                               this.references.put(keyTable[i], valueTable[i]);
+
+               this.typeLocators = new SimpleLookupTable(lastState.typeLocators.elementSize);
+               keyTable = lastState.typeLocators.keyTable;
+               valueTable = lastState.typeLocators.valueTable;
+               for (int i = 0, l = keyTable.length; i < l; i++)
+                       if (keyTable[i] != null)
+                               this.typeLocators.put(keyTable[i], valueTable[i]);
+       }
+}
+
+char[][] getDefinedTypeNamesFor(String typeLocator) {
+       Object c = references.get(typeLocator);
+//     if (c instanceof AdditionalTypeCollection)
+//             return ((AdditionalTypeCollection) c).definedTypeNames;
+       return null; // means only one type is defined with the same name as the file... saves space
+}
+
+boolean isDuplicateLocator(String qualifiedTypeName, String typeLocator) {
+       String existing = (String) typeLocators.get(qualifiedTypeName);
+       return existing != null && !existing.equals(typeLocator);
+}
+
+boolean isKnownPackage(String qualifiedPackageName) {
+       if (knownPackageNames == null) {
+               ArrayList names = new ArrayList(typeLocators.elementSize);
+               Object[] keyTable = typeLocators.keyTable;
+               for (int i = 0, l = keyTable.length; i < l; i++) {
+                       if (keyTable[i] != null) {
+                               String packageName = (String) keyTable[i]; // is a type name of the form p1/p2/A
+                               int last = packageName.lastIndexOf('/');
+                               packageName = last == -1 ? null : packageName.substring(0, last);
+                               while (packageName != null && !names.contains(packageName)) {
+                                       names.add(packageName);
+                                       last = packageName.lastIndexOf('/');
+                                       packageName = last == -1 ? null : packageName.substring(0, last);
+                               }
+                       }
+               }
+               knownPackageNames = new String[names.size()];
+               names.toArray(knownPackageNames);
+       }
+       for (int i = 0, l = knownPackageNames.length; i < l; i++)
+               if (knownPackageNames[i].equals(qualifiedPackageName))
+                       return true;
+       return false;
+}
+
+void record(String typeLocator, char[][][] qualifiedRefs, char[][] simpleRefs, char[] mainTypeName, ArrayList typeNames) {
+//     if (typeNames.size() == 1 && CharOperation.equals(mainTypeName, (char[]) typeNames.get(0))) {
+//                     references.put(typeLocator, new ReferenceCollection(qualifiedRefs, simpleRefs));
+//     } else {
+//             char[][] definedTypeNames = new char[typeNames.size()][]; // can be empty when no types are defined
+//             typeNames.toArray(definedTypeNames);
+//             references.put(typeLocator, new AdditionalTypeCollection(definedTypeNames, qualifiedRefs, simpleRefs));
+//     }
+}
+
+void recordLocatorForType(String qualifiedTypeName, String typeLocator) {
+       this.knownPackageNames = null;
+       typeLocators.put(qualifiedTypeName, typeLocator);
+}
+
+void recordStructuralDependency(IProject prereqProject, State prereqState) {
+       if (prereqState != null)
+               structuralBuildTimes.put(prereqProject.getName(), new Long(prereqState.lastStructuralBuildTime));
+}
+
+void removeLocator(String typeLocatorToRemove) {
+       this.knownPackageNames = null;
+       references.removeKey(typeLocatorToRemove);
+       typeLocators.removeValue(typeLocatorToRemove);
+}
+
+void removePackage(IResourceDelta sourceDelta) {
+       IResource resource = sourceDelta.getResource();
+       switch(resource.getType()) {
+               case IResource.FOLDER :
+                       IResourceDelta[] children = sourceDelta.getAffectedChildren();
+                       for (int i = 0, l = children.length; i < l; i++)
+                               removePackage(children[i]);
+                       return;
+               case IResource.FILE :
+                       IPath typeLocatorPath = resource.getProjectRelativePath();
+                       if (Util.isJavaFileName(typeLocatorPath.lastSegment()))
+                               removeLocator(typeLocatorPath.toString());
+       }
+}
+
+void removeQualifiedTypeName(String qualifiedTypeNameToRemove) {
+       this.knownPackageNames = null;
+       typeLocators.removeKey(qualifiedTypeNameToRemove);
+}
+
+static State read(IProject project, DataInputStream in) throws IOException {
+//     if (JavaBuilder.DEBUG)
+//             System.out.println("About to read state..."); //$NON-NLS-1$
+       if (VERSION != in.readByte()) {
+//             if (JavaBuilder.DEBUG)
+//                     System.out.println("Found non-compatible state version... answered null"); //$NON-NLS-1$
+               return null;
+       }
+
+       State newState = new State();
+       newState.javaProjectName = in.readUTF();
+       if (!project.getName().equals(newState.javaProjectName)) {
+//             if (JavaBuilder.DEBUG)
+//                     System.out.println("Project's name does not match... answered null"); //$NON-NLS-1$
+               return null;
+       }
+       newState.buildNumber = in.readInt();
+       newState.lastStructuralBuildTime = in.readLong();
+
+       int length = in.readInt();
+       newState.sourceLocations = new ClasspathMultiDirectory[length];
+       for (int i = 0; i < length; i++) {
+               IContainer sourceFolder = project, outputFolder = project;
+               String folderName;
+               if ((folderName = in.readUTF()).length() > 0) sourceFolder = project.getFolder(folderName);
+               if ((folderName = in.readUTF()).length() > 0) outputFolder = project.getFolder(folderName);
+               ClasspathMultiDirectory md =
+                       (ClasspathMultiDirectory) ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in));
+               if (in.readBoolean())
+                       md.hasIndependentOutputFolder = true;
+               newState.sourceLocations[i] = md;
+       }
+
+       length = in.readInt();
+       newState.binaryLocations = new ClasspathLocation[length];
+       IWorkspaceRoot root = project.getWorkspace().getRoot();
+       for (int i = 0; i < length; i++) {
+               switch (in.readByte()) {
+                       case SOURCE_FOLDER :
+                               newState.binaryLocations[i] = newState.sourceLocations[in.readInt()];
+                               break;
+                       case BINARY_FOLDER :
+                               IPath path = new Path(in.readUTF());
+                               IContainer outputFolder = path.segmentCount() == 1
+                                       ? (IContainer) root.getProject(path.toString())
+                                       : (IContainer) root.getFolder(path);
+                               newState.binaryLocations[i] = ClasspathLocation.forBinaryFolder(outputFolder, in.readBoolean());
+                               break;
+//                     case EXTERNAL_JAR :
+//                             newState.binaryLocations[i] = ClasspathLocation.forLibrary(in.readUTF());
+//                             break;
+//                     case INTERNAL_JAR :
+//                             newState.binaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())));
+               }
+       }
+
+       newState.structuralBuildTimes = new SimpleLookupTable(length = in.readInt());
+       for (int i = 0; i < length; i++)
+               newState.structuralBuildTimes.put(in.readUTF(), new Long(in.readLong()));
+
+       String[] internedTypeLocators = new String[length = in.readInt()];
+       for (int i = 0; i < length; i++)
+               internedTypeLocators[i] = in.readUTF();
+
+       newState.typeLocators = new SimpleLookupTable(length = in.readInt());
+       for (int i = 0; i < length; i++)
+               newState.typeLocators.put(in.readUTF(), internedTypeLocators[in.readInt()]);
+
+//     char[][] internedSimpleNames = ReferenceCollection.internSimpleNames(readNames(in), false);
+//     char[][][] internedQualifiedNames = new char[length = in.readInt()][][];
+//     for (int i = 0; i < length; i++) {
+//             int qLength = in.readInt();
+//             char[][] qName = new char[qLength][];
+//             for (int j = 0; j < qLength; j++)
+//                     qName[j] = internedSimpleNames[in.readInt()];
+//             internedQualifiedNames[i] = qName;
+//     }
+//     internedQualifiedNames = ReferenceCollection.internQualifiedNames(internedQualifiedNames);
+
+//     newState.references = new SimpleLookupTable(length = in.readInt());
+//     for (int i = 0; i < length; i++) {
+//             String typeLocator = internedTypeLocators[in.readInt()];
+//             ReferenceCollection collection = null;
+//             switch (in.readByte()) {
+//                     case 1 :
+//                             char[][] additionalTypeNames = readNames(in);
+//                             char[][][] qualifiedNames = new char[in.readInt()][][];
+//                             for (int j = 0, m = qualifiedNames.length; j < m; j++)
+//                                     qualifiedNames[j] = internedQualifiedNames[in.readInt()];
+//                             char[][] simpleNames = new char[in.readInt()][];
+//                             for (int j = 0, m = simpleNames.length; j < m; j++)
+//                                     simpleNames[j] = internedSimpleNames[in.readInt()];
+//                             collection = new AdditionalTypeCollection(additionalTypeNames, qualifiedNames, simpleNames);
+//                             break;
+//                     case 2 :
+//                             char[][][] qNames = new char[in.readInt()][][];
+//                             for (int j = 0, m = qNames.length; j < m; j++)
+//                                     qNames[j] = internedQualifiedNames[in.readInt()];
+//                             char[][] sNames = new char[in.readInt()][];
+//                             for (int j = 0, m = sNames.length; j < m; j++)
+//                                     sNames[j] = internedSimpleNames[in.readInt()];
+//                             collection = new ReferenceCollection(qNames, sNames);
+//             }
+//             newState.references.put(typeLocator, collection);
+//     }
+//     if (JavaBuilder.DEBUG)
+//             System.out.println("Successfully read state for " + newState.javaProjectName); //$NON-NLS-1$
+       return newState;
+}
+
+private static char[][] readNames(DataInputStream in) throws IOException {
+       int length = in.readInt();
+       char[][] names = new char[length][];
+       for (int i = 0; i < length; i++) {
+               int nLength = in.readInt();
+               char[] name = new char[nLength];
+               for (int j = 0; j < nLength; j++)
+                       name[j] = in.readChar();
+               names[i] = name;
+       }
+       return names;
+}
+
+void tagAsNoopBuild() {
+       this.buildNumber = -1; // tag the project since it has no source folders and can be skipped
+}
+
+boolean wasNoopBuild() {
+       return buildNumber == -1;
+}
+
+void tagAsStructurallyChanged() {
+       this.lastStructuralBuildTime = System.currentTimeMillis();
+}
+
+boolean wasStructurallyChanged(IProject prereqProject, State prereqState) {
+       if (prereqState != null) {
+               Object o = structuralBuildTimes.get(prereqProject.getName());
+               long previous = o == null ? 0 : ((Long) o).longValue();
+               if (previous == prereqState.lastStructuralBuildTime) return false;
+       }
+       return true;
+}
+
+void write(DataOutputStream out) throws IOException {
+       int length;
+       Object[] keyTable;
+       Object[] valueTable;
+
+/*
+ * byte                        VERSION
+ * String              project name
+ * int                         build number
+ * int                         last structural build number
+*/
+       out.writeByte(VERSION);
+       out.writeUTF(javaProjectName);
+       out.writeInt(buildNumber);
+       out.writeLong(lastStructuralBuildTime);
+
+/*
+ * ClasspathMultiDirectory[]
+ * int                         id
+ * String              path(s)
+*/
+       out.writeInt(length = sourceLocations.length);
+       for (int i = 0; i < length; i++) {
+               ClasspathMultiDirectory md = sourceLocations[i];
+               out.writeUTF(md.sourceFolder.getProjectRelativePath().toString());
+               out.writeUTF(md.binaryFolder.getProjectRelativePath().toString());
+               writeNames(md.exclusionPatterns, out);
+               out.writeBoolean(md.hasIndependentOutputFolder);
+       }
+
+/*
+ * ClasspathLocation[]
+ * int                         id
+ * String              path(s)
+*/
+       out.writeInt(length = binaryLocations.length);
+       next : for (int i = 0; i < length; i++) {
+               ClasspathLocation c = binaryLocations[i];
+               if (c instanceof ClasspathMultiDirectory) {
+                       out.writeByte(SOURCE_FOLDER);
+                       for (int j = 0, m = sourceLocations.length; j < m; j++) {
+                               if (sourceLocations[j] == c) {
+                                       out.writeInt(j);
+                                       continue next;
+                               }
+                       }
+               } else if (c instanceof ClasspathDirectory) {
+                       out.writeByte(BINARY_FOLDER);
+                       ClasspathDirectory cd = (ClasspathDirectory) c;
+                       out.writeUTF(cd.binaryFolder.getFullPath().toString());
+                       out.writeBoolean(cd.isOutputFolder);
+               } else {
+//                     ClasspathJar jar = (ClasspathJar) c;
+//                     if (jar.resource == null) {
+//                             out.writeByte(EXTERNAL_JAR);
+//                             out.writeUTF(jar.zipFilename);
+//                     } else {
+//                             out.writeByte(INTERNAL_JAR);
+//                             out.writeUTF(jar.resource.getFullPath().toString());
+//                     }
+               }
+       }
+
+/*
+ * Structural build numbers table
+ * String              prereq project name
+ * int                         last structural build number
+*/
+       out.writeInt(length = structuralBuildTimes.elementSize);
+       if (length > 0) {
+               keyTable = structuralBuildTimes.keyTable;
+               valueTable = structuralBuildTimes.valueTable;
+               for (int i = 0, l = keyTable.length; i < l; i++) {
+                       if (keyTable[i] != null) {
+                               length--;
+                               out.writeUTF((String) keyTable[i]);
+                               out.writeLong(((Long) valueTable[i]).longValue());
+                       }
+               }
+//             if (JavaBuilder.DEBUG && length != 0)
+//                     System.out.println("structuralBuildNumbers table is inconsistent"); //$NON-NLS-1$
+       }
+
+/*
+ * String[]            Interned type locators
+ */
+       out.writeInt(length = references.elementSize);
+       ArrayList internedTypeLocators = new ArrayList(length);
+       if (length > 0) {
+               keyTable = references.keyTable;
+               for (int i = 0, l = keyTable.length; i < l; i++) {
+                       if (keyTable[i] != null) {
+                               length--;
+                               String key = (String) keyTable[i];
+                               out.writeUTF(key);
+                               internedTypeLocators.add(key);
+                       }
+               }
+//             if (JavaBuilder.DEBUG && length != 0)
+//                     System.out.println("references table is inconsistent"); //$NON-NLS-1$
+       }
+
+/*
+ * Type locators table
+ * String              type name
+ * int                         interned locator id
+ */
+       out.writeInt(length = typeLocators.elementSize);
+       if (length > 0) {
+               keyTable = typeLocators.keyTable;
+               valueTable = typeLocators.valueTable;
+               for (int i = 0, l = keyTable.length; i < l; i++) {
+                       if (keyTable[i] != null) {
+                               length--;
+                               out.writeUTF((String) keyTable[i]);
+                               out.writeInt(internedTypeLocators.indexOf((String) valueTable[i]));
+                       }
+               }
+//             if (JavaBuilder.DEBUG && length != 0)
+//                     System.out.println("typeLocators table is inconsistent"); //$NON-NLS-1$
+       }
+
+/*
+ * char[][][]  Interned qualified names
+ * char[][]            Interned simple names
+ */
+       ArrayList internedQualifiedNames = new ArrayList(31);
+       ArrayList internedSimpleNames = new ArrayList(31);
+       valueTable = references.valueTable;
+       for (int i = 0, l = valueTable.length; i < l; i++) {
+//             if (valueTable[i] != null) {
+//                     ReferenceCollection collection = (ReferenceCollection) valueTable[i];
+//                     char[][][] qNames = collection.qualifiedNameReferences;
+//                     for (int j = 0, m = qNames.length; j < m; j++) {
+//                             char[][] qName = qNames[j];
+//                             if (!internedQualifiedNames.contains(qName)) { // remember the names have been interned
+//                                     internedQualifiedNames.add(qName);
+//                                     for (int k = 0, n = qName.length; k < n; k++) {
+//                                             char[] sName = qName[k];
+//                                             if (!internedSimpleNames.contains(sName)) // remember the names have been interned
+//                                                     internedSimpleNames.add(sName);
+//                                     }
+//                             }
+//                     }
+//                     char[][] sNames = collection.simpleNameReferences;
+//                     for (int j = 0, m = sNames.length; j < m; j++) {
+//                             char[] sName = sNames[j];
+//                             if (!internedSimpleNames.contains(sName)) // remember the names have been interned
+//                                     internedSimpleNames.add(sName);
+//                     }
+//             }
+       }
+       char[][] internedArray = new char[internedSimpleNames.size()][];
+       internedSimpleNames.toArray(internedArray);
+       writeNames(internedArray, out);
+       // now write the interned qualified names as arrays of interned simple names
+       out.writeInt(length = internedQualifiedNames.size());
+       for (int i = 0; i < length; i++) {
+               char[][] qName = (char[][]) internedQualifiedNames.get(i);
+               int qLength = qName.length;
+               out.writeInt(qLength);
+               for (int j = 0; j < qLength; j++)
+                       out.writeInt(internedSimpleNames.indexOf(qName[j]));
+       }
+
+/*
+ * References table
+ * int                 interned locator id
+ * ReferenceCollection
+*/
+       out.writeInt(length = references.elementSize);
+       if (length > 0) {
+               keyTable = references.keyTable;
+               for (int i = 0, l = keyTable.length; i < l; i++) {
+//                     if (keyTable[i] != null) {
+//                             length--;
+//                             out.writeInt(internedTypeLocators.indexOf((String) keyTable[i]));
+//                             ReferenceCollection collection = (ReferenceCollection) valueTable[i];
+//                             if (collection instanceof AdditionalTypeCollection) {
+//                                     out.writeByte(1);
+//                                     AdditionalTypeCollection atc = (AdditionalTypeCollection) collection;
+//                                     writeNames(atc.definedTypeNames, out);
+//                             } else {
+//                                     out.writeByte(2);
+//                             }
+//                             char[][][] qNames = collection.qualifiedNameReferences;
+//                             int qLength = qNames.length;
+//                             out.writeInt(qLength);
+//                             for (int j = 0; j < qLength; j++)
+//                                     out.writeInt(internedQualifiedNames.indexOf(qNames[j]));
+//                             char[][] sNames = collection.simpleNameReferences;
+//                             int sLength = sNames.length;
+//                             out.writeInt(sLength);
+//                             for (int j = 0; j < sLength; j++)
+//                                     out.writeInt(internedSimpleNames.indexOf(sNames[j]));
+//                     }
+               }
+//             if (JavaBuilder.DEBUG && length != 0)
+//                     System.out.println("references table is inconsistent"); //$NON-NLS-1$
+       }
+}
+
+private void writeNames(char[][] names, DataOutputStream out) throws IOException {
+       int length = names == null ? 0 : names.length;
+       out.writeInt(length);
+       for (int i = 0; i < length; i++) {
+               char[] name = names[i];
+               int nLength = name.length;
+               out.writeInt(nLength);
+               for (int j = 0; j < nLength; j++)
+                       out.writeChar(name[j]);
+       }
+}
+
+/**
+ * Returns a string representation of the receiver.
+ */
+public String toString() {
+       return "State for " + javaProjectName //$NON-NLS-1$
+               + " (#" + buildNumber //$NON-NLS-1$
+                       + " @ " + new Date(lastStructuralBuildTime) //$NON-NLS-1$
+                               + ")"; //$NON-NLS-1$
+}
+
+/* Debug helper
+void dump() {
+       System.out.println("State for " + javaProjectName + " (" + buildNumber + " @ " + new Date(lastStructuralBuildTime) + ")");
+       System.out.println("\tClass path source locations:");
+       for (int i = 0, l = sourceLocations.length; i < l; i++)
+               System.out.println("\t\t" + sourceLocations[i]);
+       System.out.println("\tClass path binary locations:");
+       for (int i = 0, l = binaryLocations.length; i < l; i++)
+               System.out.println("\t\t" + binaryLocations[i]);
+
+       System.out.print("\tStructural build numbers table:");
+       if (structuralBuildTimes.elementSize == 0) {
+               System.out.print(" <empty>");
+       } else {
+               Object[] keyTable = structuralBuildTimes.keyTable;
+               Object[] valueTable = structuralBuildTimes.valueTable;
+               for (int i = 0, l = keyTable.length; i < l; i++)
+                       if (keyTable[i] != null)
+                               System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString());
+       }
+
+       System.out.print("\tType locators table:");
+       if (typeLocators.elementSize == 0) {
+               System.out.print(" <empty>");
+       } else {
+               Object[] keyTable = typeLocators.keyTable;
+               Object[] valueTable = typeLocators.valueTable;
+               for (int i = 0, l = keyTable.length; i < l; i++)
+                       if (keyTable[i] != null)
+                               System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString());
+       }
+
+       System.out.print("\n\tReferences table:");
+       if (references.elementSize == 0) {
+               System.out.print(" <empty>");
+       } else {
+               Object[] keyTable = references.keyTable;
+               Object[] valueTable = references.valueTable;
+               for (int i = 0, l = keyTable.length; i < l; i++) {
+                       if (keyTable[i] != null) {
+                               System.out.print("\n\t\t" + keyTable[i].toString());
+                               ReferenceCollection c = (ReferenceCollection) valueTable[i];
+                               char[][][] qRefs = c.qualifiedNameReferences;
+                               System.out.print("\n\t\t\tqualified:");
+                               if (qRefs.length == 0)
+                                       System.out.print(" <empty>");
+                               else for (int j = 0, m = qRefs.length; j < m; j++)
+                                               System.out.print("  '" + CharOperation.toString(qRefs[j]) + "'");
+                               char[][] sRefs = c.simpleNameReferences;
+                               System.out.print("\n\t\t\tsimple:");
+                               if (sRefs.length == 0)
+                                       System.out.print(" <empty>");
+                               else for (int j = 0, m = sRefs.length; j < m; j++)
+                                               System.out.print("  " + new String(sRefs[j]));
+                               if (c instanceof AdditionalTypeCollection) {
+                                       char[][] names = ((AdditionalTypeCollection) c).definedTypeNames;
+                                       System.out.print("\n\t\t\tadditional type names:");
+                                       for (int j = 0, m = names.length; j < m; j++)
+                                               System.out.print("  " + new String(names[j]));
+                               }
+                       }
+               }
+       }
+       System.out.print("\n\n");
+}
+*/
+}