Preparing for merging
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/BucketIndex.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/BucketIndex.java
index 083a01f..301a36f 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/BucketIndex.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/BucketIndex.java
@@ -21,18 +21,29 @@
 
 public class BucketIndex {
 
+	/**
+	 * A entry in the bucket index. Each entry has one file path and a collection
+	 * of states, which by their turn contain a (UUID, timestamp) pair.  
+	 */
 	public static final class Entry {
-		public final static int LONG_LENGTH = 8;
-		public final static int UUID_LENGTH = UniversalUniqueIdentifier.BYTES_SIZE;
-		public final static int DATA_LENGTH = UUID_LENGTH + LONG_LENGTH;		
+		// the length of a long in bytes
+		private final static int LONG_LENGTH = 8;
+		// the length of a UUID in bytes
+		private final static int UUID_LENGTH = UniversalUniqueIdentifier.BYTES_SIZE;
+		public final static int DATA_LENGTH = UUID_LENGTH + LONG_LENGTH;
 		byte[][] data;
 		IPath path;
 
+		/**
+		 * Returns the byte array representation of a (UUID, timestamp) pair. 
+		 */
 		public static byte[] getDataAsByteArray(byte[] uuid, long timestamp) {
 			byte[] item = new byte[DATA_LENGTH];
 			System.arraycopy(uuid, 0, item, 0, uuid.length);
-			for (int j = 0; j < LONG_LENGTH; j++)
-				item[UUID_LENGTH + j] = (byte) (0xFF & (timestamp >>> (j * 8)));
+			for (int j = 0; j < LONG_LENGTH; j++) {
+				item[UUID_LENGTH + j] = (byte) (0xFF & timestamp);
+				timestamp >>>= 8;
+			}
 			return item;
 		}
 
@@ -47,7 +58,7 @@
 			return new UniversalUniqueIdentifier(item);
 		}
 
-		Entry(IPath path, byte[][] data) {
+		public Entry(IPath path, byte[][] data) {
 			this.path = path;
 			this.data = data;
 		}
@@ -111,29 +122,46 @@
 		public boolean isEmpty() {
 			return data == null || data.length == 0;
 		}
+		
+		public void sortStates() {
+			sortStates(this.data);
+		}
 
+		public static void sortStates(byte[][] data) {
+			Arrays.sort(data, new Comparator() {
+				// sort in inverse order
+				public int compare(Object o1, Object o2) {
+					byte[] state1 = (byte[]) o1;
+					byte[] state2 = (byte[]) o2;
+					long timestamp1 = getTimestamp(state1);
+					long timestamp2 = getTimestamp(state2);
+					if (timestamp1 == timestamp2)
+						return -UniversalUniqueIdentifier.compareTime(state1, state2);
+					return timestamp1 < timestamp2 ? +1 : -1;
+				}
+			});
+		}
 	}
 
 	public abstract static interface Visitor {
-
-		// should stop the traversal
+		// should continue the traversal
 		public final static int CONTINUE = 0;
 		// should delete this entry (can be combined with the other constants except for UPDATE)
 		public final static int DELETE = 0x100;
 		// should stop looking at states for files in this container (or any of its children)	
 		public final static int RETURN = 2;
-		// keep visiting, still happy	
+		// should stop the traversal	
 		public final static int STOP = 1;
 		// should update this entry (can be combined with the other constants except for DELETE)		
 		public final static int UPDATE = 0x200;
 
 		/** 
-		 * @return either STOP, CONTINUE or RETURN and optionally DELETE
+		 * @return either STOP, CONTINUE or RETURN and optionally DELETE or UPDATE
 		 */
 		public int visit(Entry entry);
 	}
 
-	private static final String BUCKET = ".bucket"; //$NON-NLS-1$
+	private static final String BUCKET = "bucket.index"; //$NON-NLS-1$
 
 	public final static byte VERSION = 1;
 
@@ -175,7 +203,7 @@
 	 * @return one of STOP, RETURN or CONTINUE constants
 	 * @throws CoreException
 	 */
-	public int accept(Visitor visitor, IPath filter, boolean exactMatch, boolean sorted) throws CoreException {
+	public int accept(Visitor visitor, IPath filter, boolean exactMatch) throws CoreException {
 		if (entries.isEmpty())
 			return Visitor.CONTINUE;
 		try {
@@ -187,6 +215,7 @@
 					continue;
 				// calls the visitor passing all uuids for the entry
 				final Entry fileEntry = new Entry(path, (byte[][]) entry.getValue());
+				fileEntry.sortStates();
 				int outcome = visitor.visit(fileEntry);
 				if ((outcome & Visitor.UPDATE) != 0) {
 					needSaving = true;
@@ -228,7 +257,6 @@
 		byte[][] newValue = new byte[existing.length + 1][];
 		System.arraycopy(existing, 0, newValue, 0, existing.length);
 		newValue[newValue.length - 1] = item;
-		sortUUIDs(newValue);
 		entries.put(pathAsString, newValue);
 		needSaving = true;
 	}
@@ -279,7 +307,6 @@
 		byte[][] existing = (byte[][]) entries.get(pathAsString);
 		if (existing == null)
 			return new Entry(path, null);
-		sortUUIDs(existing);
 		return new Entry(path, existing);
 	}
 
@@ -290,6 +317,7 @@
 	public void load(File baseLocation) throws CoreException {
 		load(baseLocation, false);
 	}
+
 	public void load(File baseLocation, boolean force) throws CoreException {
 		try {
 			// avoid reloading
@@ -362,15 +390,7 @@
 		}
 	}
 
-	private void sortUUIDs(byte[][] uuids) {
-		Arrays.sort(uuids, new Comparator() {
-			public int compare(Object o1, Object o2) {
-				return -UniversalUniqueIdentifier.compareTime((byte[]) o1, (byte[]) o2);
-			}
-		});
-	}
-
 	public int getEntryCount() {
-		return entries.size();		
+		return entries.size();
 	}
 }
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/FileSystemResourceManager.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/FileSystemResourceManager.java
index 8fed670..a11a301 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/FileSystemResourceManager.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/FileSystemResourceManager.java
@@ -150,18 +150,19 @@
 	/**
 	 * Factory method for creating history stores. 
 	 */
-	private static IHistoryStore createHistoryStore(Workspace workspace, IPath location, int limit) {
-		if (Boolean.getBoolean(ENABLE_NEW_HISTORY_STORE)) {
-			HistoryStore2 newHistoryStore = new HistoryStore2(workspace, location, limit);
-			if (Boolean.getBoolean(CONVERT_HISTORY_STORE)) {
-				IStatus conversionOutcome = new HistoryStoreConverter().convertHistory(workspace, location, limit, newHistoryStore, true);
-				if (conversionOutcome.getSeverity() != IStatus.OK)
-					// if either we fail or succeed, a non-OK status is returned
-					ResourcesPlugin.getPlugin().getLog().log(conversionOutcome);
-			}
+	private static IHistoryStore createHistoryStore(Workspace workspace, IPath location, int limit) {		
+		if (!Boolean.getBoolean(ENABLE_NEW_HISTORY_STORE))
+			// keep using the old history store
+			return new HistoryStore(workspace, location, limit);
+		HistoryStore2 newHistoryStore = new HistoryStore2(workspace, location, limit);
+		if (!Boolean.getBoolean(CONVERT_HISTORY_STORE))
+			// do not try to convert - return as it is
 			return newHistoryStore;
-		}
-		return new HistoryStore(workspace, location, limit);
+		IStatus result = new HistoryStoreConverter().convertHistory(workspace, location, limit, newHistoryStore, true);
+		if (result.getSeverity() != IStatus.OK)
+			// if we do anything (either we fail or succeed converting), a non-OK status is returned
+			ResourcesPlugin.getPlugin().getLog().log(result);
+		return newHistoryStore;
 	}
 
 	public void delete(IResource target, boolean force, boolean convertToPhantom, boolean keepHistory, IProgressMonitor monitor) throws CoreException {
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore.java
index 15a294b..b44bbeb 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore.java
@@ -400,7 +400,7 @@
 		}
 		return blobStore.getBlob(((FileState) target).getUUID());
 	}
-	
+
 	/**
 	 * @see IHistoryStore#getStates(IPath, IProgressMonitor)
 	 */
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore2.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore2.java
index b1eef9f..d1b23e4 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore2.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStore2.java
@@ -38,17 +38,13 @@
 		this.currentBucket = createBucketTable();
 	}
 
-	public void accept(Visitor visitor, IPath root, int depth) throws CoreException {
-		accept(visitor, root, depth, false);
-	}
-
 	/**
 	 * From a starting point in the tree, visit all nodes under it. 
 	 * @param visitor
 	 * @param root
 	 * @param depth
 	 */
-	public void accept(Visitor visitor, IPath root, int depth, boolean sorted) throws CoreException {
+	public void accept(Visitor visitor, IPath root, int depth) throws CoreException {
 		// we only do anything for the root if depth == infinite
 		if (root.isRoot()) {
 			if (depth != IResource.DEPTH_INFINITE)
@@ -60,7 +56,7 @@
 				return;
 			for (int i = 0; i < projects.length; i++)
 				if (projects[i].isDirectory())
-					if (!internalAccept(visitor, root.append(projects[i].getName()), projects[i], IResource.DEPTH_INFINITE, sorted))
+					if (!internalAccept(visitor, root.append(projects[i].getName()), projects[i], IResource.DEPTH_INFINITE))
 						break;
 			// done
 			return;
@@ -68,10 +64,10 @@
 		// handles the case the starting point is a file path
 		if (root.segmentCount() > 1) {
 			currentBucket.load(locationFor(root.removeLastSegments(1)));
-			if (currentBucket.accept(visitor, root, true, sorted) != Visitor.CONTINUE || depth == IResource.DEPTH_ZERO)
+			if (currentBucket.accept(visitor, root, true) != Visitor.CONTINUE || depth == IResource.DEPTH_ZERO)
 				return;
 		}
-		internalAccept(visitor, root, locationFor(root), depth, sorted);
+		internalAccept(visitor, root, locationFor(root), depth);
 	}
 
 	/**
@@ -135,7 +131,7 @@
 					}
 					return changed ? UPDATE : CONTINUE;
 				}
-			}, root, IResource.DEPTH_INFINITE, true);
+			}, root, IResource.DEPTH_INFINITE);
 			// remove unreferenced blobs
 			blobStore.deleteBlobs(blobsToRemove);
 			blobsToRemove = new HashSet();
@@ -266,19 +262,8 @@
 						states.add(new FileState(HistoryStore2.this, fileEntry.getPath(), fileEntry.getTimestamp(i), fileEntry.getUUID(i)));
 					return CONTINUE;
 				}
-			}, filePath, IResource.DEPTH_ZERO, true);
-			IFileState[] result = (IFileState[]) states.toArray(new IFileState[states.size()]);
-			// sort states based on modification time + uuid 
-			Arrays.sort(result, new Comparator() {
-				public int compare(Object o1, Object o2) {
-					FileState fs1 = (FileState) o1;
-					FileState fs2 = (FileState) o2;
-					if (fs1.getModificationTime() == fs1.getModificationTime())
-						return -UniversalUniqueIdentifier.compareTime(fs1.getUUID(), fs2.getUUID());
-					return (fs1.getModificationTime() < fs2.getModificationTime()) ? 1 : -1;
-				}
-			});
-			return result;
+			}, filePath, IResource.DEPTH_ZERO);
+			return (IFileState[]) states.toArray(new IFileState[states.size()]);
 		} catch (CoreException ce) {
 			ResourcesPlugin.getPlugin().getLog().log(ce.getStatus());
 			return new IFileState[0];
@@ -289,9 +274,9 @@
 	 * 
 	 * @return whether to continue visiting other branches 
 	 */
-	private boolean internalAccept(Visitor visitor, IPath root, File bucketDir, int depth, boolean sorted) throws CoreException {
+	private boolean internalAccept(Visitor visitor, IPath root, File bucketDir, int depth) throws CoreException {
 		currentBucket.load(bucketDir);
-		int outcome = currentBucket.accept(visitor, root, depth == IResource.DEPTH_ZERO, sorted);
+		int outcome = currentBucket.accept(visitor, root, depth == IResource.DEPTH_ZERO);
 		if (outcome != Visitor.CONTINUE)
 			return outcome == Visitor.RETURN;
 		// nothing else to be done
@@ -302,7 +287,7 @@
 			return true;
 		for (int i = 0; i < subDirs.length; i++)
 			if (subDirs[i].isDirectory())
-				if (!internalAccept(visitor, root, subDirs[i], IResource.DEPTH_INFINITE, sorted))
+				if (!internalAccept(visitor, root, subDirs[i], IResource.DEPTH_INFINITE))
 					return false;
 		return true;
 	}
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStoreConverter.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStoreConverter.java
index 4048e3e..56badac 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStoreConverter.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/HistoryStoreConverter.java
@@ -18,8 +18,6 @@
 import org.eclipse.core.runtime.*;
 
 public class HistoryStoreConverter {
-	private static final String BACKUP_FILE_EXTENSION = "bak"; //$NON-NLS-1$
-
 	/**
 	 * Converts an existing history store lying on disk to the new history store.
 	 * Returns Status.OK_STATUS if nothing is done, an IStatus.INFO status if
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java
index 26a02a5..f2b65bd 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java
@@ -53,7 +53,6 @@
 	public static boolean DEBUG_SAVE_SYNCINFO = false;
 	public static boolean DEBUG_SAVE_TREE = false;
 	public static boolean DEBUG_SAVE_METAINFO = false;
-	public static boolean DEBUG_SAVE_SNAPSHOTS = false;
 	public static boolean DEBUG_SAVE_MASTERTABLE = false;
 
 	public static boolean DEBUG_AUTO_REFRESH = false;
@@ -85,7 +84,6 @@
 			DEBUG_SAVE_SYNCINFO = sTrue.equalsIgnoreCase(Platform.getDebugOption(ResourcesPlugin.PI_RESOURCES + "/save/syncinfo")); //$NON-NLS-1$ 
 			DEBUG_SAVE_TREE = sTrue.equalsIgnoreCase(Platform.getDebugOption(ResourcesPlugin.PI_RESOURCES + "/save/tree")); //$NON-NLS-1$ 
 			DEBUG_SAVE_METAINFO = sTrue.equalsIgnoreCase(Platform.getDebugOption(ResourcesPlugin.PI_RESOURCES + "/save/metainfo")); //$NON-NLS-1$ 
-			DEBUG_SAVE_SNAPSHOTS = sTrue.equalsIgnoreCase(Platform.getDebugOption(ResourcesPlugin.PI_RESOURCES + "/save/snapshots")); //$NON-NLS-1$ 
 			DEBUG_SAVE_MASTERTABLE = sTrue.equalsIgnoreCase(Platform.getDebugOption(ResourcesPlugin.PI_RESOURCES + "/save/mastertable")); //$NON-NLS-1$ 
 			DEBUG_SAVE = sTrue.equalsIgnoreCase(Platform.getDebugOption(ResourcesPlugin.PI_RESOURCES + "/save")); //$NON-NLS-1$ 
 
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/UniversalUniqueIdentifier.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/UniversalUniqueIdentifier.java
index a484496..7299722 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/UniversalUniqueIdentifier.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/UniversalUniqueIdentifier.java
@@ -100,15 +100,10 @@
 	 @see #BYTES_SIZE
 	 */
 	public UniversalUniqueIdentifier(byte[] byteValue) {
-		this(byteValue, 0);
-	}
-	
-	public UniversalUniqueIdentifier(byte[] byteValue, int start) {
 		fBits = new byte[BYTES_SIZE];
-		if (byteValue.length - start >= BYTES_SIZE)
-			System.arraycopy(byteValue, start, fBits, 0, fBits.length);
+		if (byteValue.length >= BYTES_SIZE)
+			System.arraycopy(byteValue, 0, fBits, 0, BYTES_SIZE);
 	}
-	
 
 	/**
 	 Construct an instance whose internal representation is defined by the given string.  
@@ -123,7 +118,7 @@
 		// Check to ensure it is a String of the right length.
 		// do not use Assert to avoid having to call Policy.bind ahead of time
 		if (string.length() != PrintStringSize)
-			throw new IllegalArgumentException(Policy.bind("utils.wrongLength", string)); //$NON-NLS-1$
+			Assert.isTrue(false, Policy.bind("utils.wrongLength", string)); //$NON-NLS-1$
 
 		char[] newChars = string.toCharArray();
 
@@ -174,6 +169,22 @@
 	}
 
 	/**
+	 * Compares the time component of two UUIDs.
+	 * 
+	 * @see Comparable#compareTo(java.lang.Object)
+	 */
+	public int compareTime(UniversalUniqueIdentifier other) {
+		return compareTime(this.fBits, other.fBits);
+	}
+	
+	public static int compareTime(byte[] fBits1, byte[] fBits2) {
+		for (int i = TIME_FIELD_STOP; i >= 0; i--) 
+			if (fBits1[i] != fBits2[i])
+				return (0xFF & fBits1[i]) - (0xFF & fBits2[i]);		
+		return 0;
+	}		
+
+	/**
 	 * Answers the node address attempting to mask the IP
 	 * address of this machine.
 	 * 
@@ -460,64 +471,4 @@
 		}
 		return result + "}"; //$NON-NLS-1$
 	}
-
-//	public static void main(String[] args) throws Exception {
-//		StringWriter writer = new StringWriter(2000);
-//		PrintWriter pw = new PrintWriter(writer);		
-//		int j = 0;
-//		while (true) {
-//			j++;
-//			UniversalUniqueIdentifier uuid = new UniversalUniqueIdentifier();
-//			byte[] bytes = uuid.toBytes();
-//			for (int i = 0; i < 6; i++) {
-//				pw.print(Integer.toHexString(bytes[i] & 0xFF));
-//				pw.print(" ");
-//			}
-//			pw.print(Integer.toHexString(bytes[7] & HIGH_NIBBLE_MASK));
-//			pw.print(" -- ");
-//			pw.println(uuid);
-//			if (j % 80 == 0) {
-//				pw.flush();
-//				System.out.println(writer.getBuffer());
-//				writer.getBuffer().setLength(0);
-//			}
-//		}
-//	}
-	
-	public static void main(String[] args) throws Exception {
-		int i = 0;
-		UniversalUniqueIdentifier last = new UniversalUniqueIdentifier();
-		while (true) {
-			i++;
-			UniversalUniqueIdentifier current = new UniversalUniqueIdentifier();
-			if (compareTime(last, current) >= 0) {
-				System.out.println("Broke comparison at  " + i);
-				System.out.println(last);
-				System.out.println(current);
-				break;				
-			}
-//				
-//			if (current.toBytes()[0] == last.toBytes()[0]) {
-//				System.out.println("Collision at  " + i);
-//				System.out.println(last);
-//				System.out.println(current);
-//				break;
-//			}
-			last = current;
-		}
-	}
-
-	public static int compareTime(UniversalUniqueIdentifier uuid1, UniversalUniqueIdentifier uuid2) {
-		return compareTime(uuid1.fBits, uuid2.fBits);
-	}
-	public static int compareTime(byte[] fBits1, byte[] fBits2) {
-		for (int i = TIME_FIELD_STOP; i >= 0; i--) 
-			if (fBits1[i] != fBits2[i])
-				return (0xFF & fBits1[i]) - (0xFF & fBits2[i]);		
-		return 0;
-	}	
-	public static int compareTime(String uuid1, String uuid2) {
-		// TODO this must be more efficient
-		return compareTime(new UniversalUniqueIdentifier(uuid1), new UniversalUniqueIdentifier(uuid2));
-	}
 }
\ No newline at end of file