Index: trunk/gli/src/org/greenstone/gatherer/msm/GDMDocument.java
===================================================================
--- trunk/gli/src/org/greenstone/gatherer/msm/GDMDocument.java	(revision 5794)
+++ trunk/gli/src/org/greenstone/gatherer/msm/GDMDocument.java	(revision 5808)
@@ -179,10 +179,16 @@
 		metadata_element.setAttribute(MODE_ATTRIBUTE, ACCUMULATE);
 	    }
-	    // As we can't possibly store all the metadata in memory, nor can we ensure that the indexes written to file remain the same until the new time we look at this file, and to avoid having to open a rewrite every collection document whenever any value tree changes, I'm adding a new attribute called hvalue which indicates the hierarchy value path as a '\\' separated string.
-	    GValueModel model = Gatherer.c_man.getCollection().msm.getValueTree(metadata.getElement());
-	    if(model != null && model.isHierarchy()) {
-		metadata_element.setAttribute(HVALUE_ATTRIBUTE, metadata.getValueNode().getFullPath(false));
-	    }
-	    String node_value = metadata.getAbsoluteValue();
+		// As we can't possibly store all the metadata in memory, nor can we ensure that the indexes written to file remain the same until the new time we look at this file, and to avoid having to open a rewrite every collection document whenever any value tree changes, I'm adding a new attribute called hvalue which indicates the hierarchy value path as a '|' separated string.
+		GValueModel model = Gatherer.c_man.getCollection().msm.getValueTree(metadata.getElement());
+		String node_value = null;
+		if(model != null && model.isHierarchy()) {
+			node_value = Codec.transform(metadata.getValueNode().getFullPath(false), Codec.TEXT_TO_DOM);
+			///ystem.err.println("Saving H Info: " + node_value);
+			metadata_element.setAttribute(HVALUE_ATTRIBUTE, node_value);
+		}
+		else {
+			node_value = metadata.getAbsoluteValue();
+			///ystem.err.println("Not H Info: " + node_value);
+		}
 	    ///ystem.err.println("Creating node in GDMDocument: '" + node_value + "'");
 	    metadata_element.appendChild(base_document.createTextNode(node_value));
@@ -280,7 +286,7 @@
 				// ***** LEGACY SUPPORT *****
 				// If this raw_value contains a '\' character, but no '\\', '[' or ']' characters, then replace the '\' with a '\\'
-				if(raw_value.indexOf(StaticStrings.ESCAPE_STR) != -1 && raw_value.indexOf(StaticStrings.ESCAPE_STR + StaticStrings.ESCAPE_STR) == -1 && raw_value.indexOf(StaticStrings.RBRACKET_CHARACTER) == -1 && raw_value.indexOf(StaticStrings.LBRACKET_CHARACTER) == -1) {
+				if(raw_value.indexOf(StaticStrings.ESCAPE_STR) != -1) {
 				    Gatherer.println("Detected Legacy Path: " + raw_value);
-				    raw_value = raw_value.replaceAll(StaticStrings.ESCAPE_PATTERN, StaticStrings.ESCAPE_PATTERN + StaticStrings.ESCAPE_PATTERN);
+				    raw_value = raw_value.replaceAll(StaticStrings.ESCAPE_PATTERN, StaticStrings.PIPE_STR);
 				    Gatherer.println("Updated Path To: " + raw_value);
 				    metadata_element.setAttribute(HVALUE_ATTRIBUTE, raw_value);
@@ -362,5 +368,8 @@
 				    }
 				    else {
-					String current_value = metadata.getAbsoluteValue();
+					//String current_value = metadata.getAbsoluteValue();
+					String current_value = Codec.transform(metadata.getValueNode().getFullPath(false), Codec.TEXT_TO_DOM);
+					///ystem.err.println("Checking the current hfile: " + current_value);
+ 					///ystem.err.println("Against whats in the hfile: " + current_value);
 					if(!raw_value.equals(current_value)) {
 					    // Remove old text
Index: trunk/gli/src/org/greenstone/gatherer/msm/GDMManager.java
===================================================================
--- trunk/gli/src/org/greenstone/gatherer/msm/GDMManager.java	(revision 5794)
+++ trunk/gli/src/org/greenstone/gatherer/msm/GDMManager.java	(revision 5808)
@@ -56,5 +56,5 @@
 */
 public class GDMManager
-    extends HashMap
+    extends LinkedHashMap
     implements MSMListener {
     /** A list of the known metadata instances, thus we only store one of each unique metadata, and reference the rest. */
@@ -64,4 +64,6 @@
     /** The threaded object responsible for loading all of the existing metadata.xml files prior to any save action. This is necessary so that hierarchy indexes within the metadata.xml files stay fresh. */
     private GDMLoader gdm_loader = null;
+    /** The maximum number of GDMDocuments to load at any one time */
+    static final private int MAX_DOCUMENTS = 25;
     static final private String METADATA_XML = "metadata.xml";
     /** Constructor. */
@@ -72,12 +74,12 @@
 	Gatherer.c_man.getCollection().msm.addMSMListener(this);
 	// Now create and start the synchronous GDM loader.
-	gdm_loader = new GDMLoader(false);
-	gdm_loader.start();
+	//gdm_loader = new GDMLoader();
+	//gdm_loader.start();
 	///atherer.println("New GDMManager created.");
     }
 
-    
-
-    
+
+
+
     public GDMManager(boolean dummy_load) {
 	super();
@@ -151,12 +153,15 @@
 	if(containsKey(metadata_file)) {
 	    metadata_xml = (GDMDocument) get(metadata_file);
+	    ///ystem.err.println("Get the GDMDocument for " + metadata_file.getAbsolutePath());
 	}
 	else {
 	    // Now the two potential cache misses. The first requires us to load an existing metadata.xml
 	    if(metadata_file.exists()) {
+		///ystem.err.println("Reload the GDMDocument for " + metadata_file.getAbsolutePath());
 		metadata_xml = new GDMDocument(metadata_file);
 	    }
 	    // The final case is where no current metadata.xml exists. Create a new one just by creating a new GDMDocument.
 	    else {
+		///ystem.err.println("Create a new GDMDocument for " + metadata_file.getAbsolutePath());
 		metadata_xml = new GDMDocument();
 	    }
@@ -198,5 +203,5 @@
 	GDMDocument document = getDummyDocument(file);
 
-	
+
     }
     /** Recover the metadata associated with a particular file. Note that this call is synchronized, so that all of the data holders don't need to be. */
@@ -365,4 +370,5 @@
 	    GDMDocument document = (GDMDocument) get(file);
 	    if(!document.isUpToDate()) {
+		//ystem.err.println("Saving: " + file.getAbsolutePath());
 		// First purge any old references.
 		document.getMetadata(null, false, null, null, true);
@@ -405,4 +411,16 @@
     }
 
+    /** Write out the latest copy of a certain document. */
+    public void save(File file, GDMDocument document) {
+		if(!document.isUpToDate()) {
+			// First purge any old references.
+			document.getMetadata(null, false, null, null, true);
+			// Now write the xml
+			Utility.export(document.getDocument(), file);
+			document.setUpToDate(true);
+		}
+    }
+
+
     /** Method that is called whenever the metadata set collection changes in some way, such as the addition of a new set or the merging of two sets. If a set changes, mark all cached GDMDocuments as being stale.
      * @param event A <strong>MSMEvent</strong> containing details of the event that caused this message to be fired.
@@ -421,5 +439,7 @@
 
     public void waitUntilComplete() {
-	gdm_loader.waitUntilComplete();
+		if(gdm_loader != null) {
+		gdm_loader.waitUntilComplete();
+		}
     }
 
@@ -445,5 +465,5 @@
 	}
 
-	
+
 	public void run() {
 	    // Can't open a collections metadata when the collection isn't open!
@@ -471,4 +491,9 @@
 			remaining.add(record.getChildAt(i));
 		    }
+
+		    ///atherer.println("Retrieving metadata.xml for " + record);
+		    getMetadata(record.getFile());
+
+		    record.unmap();
 		}
 		record = null;
@@ -488,3 +513,18 @@
 	}
     }
+
+	protected boolean removeEldestEntry(Map.Entry eldest) {
+        if(size() > MAX_DOCUMENTS) {
+        	// Save the oldest document before its dumped
+        	File file = (File) eldest.getKey();
+        	///ystem.err.println("Dumping oldest Document: " + file.getAbsolutePath());
+			GDMDocument document = (GDMDocument) eldest.getValue();
+			save(file, document);
+        	// And then dump it
+        	return true;
+		}
+		else {
+			return false;
+		}
+     }
 }
