Index: /main/trunk/gli/src/org/greenstone/gatherer/cdm/CollectionConfigXMLReadWrite.java
===================================================================
--- /main/trunk/gli/src/org/greenstone/gatherer/cdm/CollectionConfigXMLReadWrite.java	(revision 26354)
+++ /main/trunk/gli/src/org/greenstone/gatherer/cdm/CollectionConfigXMLReadWrite.java	(revision 26355)
@@ -30,4 +30,5 @@
 import java.io.File;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -52,7 +53,10 @@
 	static final private String PLUGOUT_ELEMENT = "plugout";//used by building flax collections
 
+  // a list of all known top level elements
+  static final private String known_element_names_array[] = {StaticStrings.METADATALIST_STR, StaticStrings.DISPLAYITEMLIST_STR, StaticStrings.FORMAT_STR, StaticStrings.SEARCH_STR, StaticStrings.INFODB_STR, StaticStrings.BROWSE_STR, StaticStrings.IMPORT_STR,  StaticStrings.DISPLAY_STR, StaticStrings.REPLACELISTREF_STR, StaticStrings.REPLACELIST_STR, StaticStrings.SERVICE_RACK_LIST_ELEMENT};
+  static final private Set known_element_names = new HashSet(Arrays.asList(known_element_names_array));
 	/**
 	 * *************************************************************************
-	 * ******************************* The code from this point below are used
+	 * ******************************* The code in this file is used
 	 * for greenstone 3 collection configuration, i.e., read ColletionConfig.xml
 	 * into the internal DOM tree, and convert the internal DOM tree back to
@@ -160,11 +164,10 @@
 			Element index_element = to.createElement(StaticStrings.INDEX_ELEMENT);//<Index>
 
-			// For mg, it's the 'Old G2.38 and earlier' that use level:source tuplets, but we double check it anyway
-			boolean old_index = true;
 			if (index_str.indexOf(StaticStrings.COLON_CHARACTER) == -1)
 			{
 				// It doesn't contain ':' character
 				System.err.println("Something is wrong! the index should be level:source tuplets.");
-				old_index = false;
+				// assume document level
+				index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, StaticStrings.DOCUMENT_STR);
 			}
 			else
@@ -172,6 +175,7 @@
 				// Handling 'index' element
 				index_element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, index_str.substring(0, index_str.indexOf(StaticStrings.COLON_CHARACTER)));
+			
 				index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
-
+			}
 				//Each index may have a list of comma-separated strings.
 				//split them into 'content' elements in the internal structure
@@ -186,14 +190,8 @@
 					// Since the contents of indexes have to be certain keywords, or metadata elements,
 					//if the content isn't a keyword and doesn't yet have a namespace, append the extracted metadata namespace.
-					if (content_str.indexOf(StaticStrings.NS_SEP) == -1)
+					if (content_str.indexOf(StaticStrings.NS_SEP) == -1 && !(content_str.equals(StaticStrings.TEXT_STR)))
 					{
-						if (content_str.equals(StaticStrings.TEXT_STR) || (!old_index && content_str.equals(StaticStrings.ALLFIELDS_STR)))
-						{
-							// in this case, do nothing
-						}
-						else
-						{
 							content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str;
-						}
+						
 					}
 
@@ -209,5 +207,4 @@
 				ArrayList collectionmetadata_list = doDisplayItemList(to, e, StaticStrings.NAME_ATTRIBUTE, index_str_display);
 				appendArrayList(toElement, collectionmetadata_list);
-			} //else ends
 		} //for loop ends
 		appendProperly(toElement, indexes_element);
@@ -268,14 +265,13 @@
 			// Handling 'index' element
 			// Double check to make sure it's not colon separated style index.
-			boolean old_index = false;
 			if (index_str.indexOf(StaticStrings.COLON_CHARACTER) != -1)
 			{
 				System.err.println("Something is wrong! the index should NOT be level:source tuplets style.");
-				old_index = true;
+				index_str = index_str.substring(index_str.indexOf(StaticStrings.COLON_CHARACTER) + 1);
+				
 			}
 			//Each index may have a list of comma-separated strings.
 			//split them into 'content' elements in the internal structure
 			StringTokenizer content_tokenizer = new StringTokenizer(index_str, StaticStrings.COMMA_CHARACTER);
-			//index_str = "";
 			while (content_tokenizer.hasMoreTokens())
 			{
@@ -285,14 +281,7 @@
 				String content_str = content_tokenizer.nextToken();
 				// Since the contents of indexes have to be certain keywords, or metadata elements, if the content isn't a keyword and doesn't yet have a namespace, append the extracted metadata namespace.
-				if (content_str.indexOf(StaticStrings.NS_SEP) == -1)
-				{
-					if (content_str.equals(StaticStrings.TEXT_STR))
-					{
-						// in this case, do nothing
-					}
-					else
-					{
+				if (content_str.indexOf(StaticStrings.NS_SEP) == -1 && !(content_str.equals(StaticStrings.TEXT_STR)|| content_str.equals(StaticStrings.ALLFIELDS_STR)))
+				{
 						content_str = StaticStrings.EXTRACTED_NAMESPACE + content_str;
-					}
 				}
 				content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, content_str);
@@ -1012,15 +1001,17 @@
 
 		NodeList replace_elements = from.getElementsByTagName(StaticStrings.REPLACELISTREF_STR);
-		int num_elems = replace_elements.getLength();
-		if (num_elems < 1)
-		{
-			return;
-		}
-		for (int i = 0; i < num_elems; i++)
-		{
-			Element to_element = XMLTools.duplicateElement(to, (Element) replace_elements.item(i), true);
-			toElement.appendChild(to_element);
-		}
-	}
+		XMLTools.duplicateElementList(to, toElement, replace_elements, true);
+	}
+	// 	int num_elems = replace_elements.getLength();
+	// 	if (num_elems < 1)
+	// 	{
+	// 		return;
+	// 	}
+	// 	for (int i = 0; i < num_elems; i++)
+	// 	{
+	// 		Element to_element = XMLTools.duplicateElement(to, (Element) replace_elements.item(i), true);
+	// 		toElement.appendChild(to_element);
+	// 	}
+	// }
 
 	static private void convertReplaceListRef(Document from, Document to)
@@ -1029,16 +1020,47 @@
 
 		NodeList replace_elements = from.getDocumentElement().getElementsByTagName(StaticStrings.REPLACELISTREF_STR);
-		int num_elems = replace_elements.getLength();
-		if (num_elems < 1)
-		{
-			return;
-		}
-		for (int i = 0; i < num_elems; i++)
-		{
-			Element to_element = XMLTools.duplicateElement(to, (Element) replace_elements.item(i), true);
-			toElement.appendChild(to_element);
-		}
-	}
-
+		XMLTools.duplicateElementList(to, toElement, replace_elements, true);
+	}
+		// int num_elems = replace_elements.getLength();
+		// if (num_elems < 1)
+		// {
+		// 	return;
+		// }
+		// for (int i = 0; i < num_elems; i++)
+		// {
+		// 	Element to_element = XMLTools.duplicateElement(to, (Element) replace_elements.item(i), true);
+		// 	toElement.appendChild(to_element);
+		// }
+  //	}
+
+  /* replacelist currently not editable in GLI, just copy it in and back out again */
+	static private void doReplaceList(Document to, Element from)
+	{
+		Element toElement = to.getDocumentElement();
+
+		Node rl_element = XMLTools.getChildByTagName(from, StaticStrings.REPLACELIST_STR);
+		if (rl_element == null)
+		{
+			return; // such an element not found
+		}
+
+		Element to_element = XMLTools.duplicateElement(to, (Element) rl_element, true);
+		toElement.appendChild(to_element);
+	}
+
+	static private void convertReplaceList(Document from, Document to)
+	{
+		Element toElement = to.getDocumentElement();
+
+		Node rl_element = XMLTools.getChildByTagName(from.getDocumentElement(), StaticStrings.REPLACELIST_STR);
+		if (rl_element == null)
+		{
+			return; // such an element not found
+		}
+
+		Element to_element = XMLTools.duplicateElement(to, (Element) rl_element, true);
+		toElement.appendChild(to_element);
+	}
+ 
 	/**
 	 * serviceRackList is currently not editable in GLI - just copy it in from
@@ -1097,14 +1119,15 @@
 	{
 		Element toElement = to.getDocumentElement();
-		Node index_option_node = XMLTools.getChildByTagName(searchNode, StaticStrings.INDEXOPTION_STR);
-		if (index_option_node == null)
-		{
-			return;
-		}
-		NodeList option_children = ((Element) index_option_node).getElementsByTagName(StaticStrings.OPTION_STR);
-		int option_nodes = option_children.getLength();
+		//Node index_option_node = XMLTools.getChildByTagName(searchNode, StaticStrings.INDEXOPTION_STR);
+		//if (index_option_node == null)
+		//{
+		//	return;
+		//}
+		//NodeList option_children = ((Element) index_option_node).getElementsByTagName(StaticStrings.OPTION_STR);
+		NodeList option_children = ((Element) searchNode).getElementsByTagName(StaticStrings.INDEXOPTION_STR);
+		int num_options = option_children.getLength();
 
 		// for lucene, there is no 'indexOption'. We build a default 'indexOption' and 'assigned=false' in case the user switches to mg or mgpp
-		if (option_nodes < 1)
+		if (num_options < 1)
 		{
 			Element index_option = to.createElement(StaticStrings.INDEXOPTIONS_ELEMENT);
@@ -1126,5 +1149,5 @@
 		index_option.setAttribute(StaticStrings.NAME_STR, StaticStrings.INDEXOPTIONS_STR);
 
-		for (int i = 0; i < option_nodes; i++)
+		for (int i = 0; i < num_options; i++)
 		{
 			String option_str = ((Element) option_children.item(i)).getAttribute(StaticStrings.NAME_ATTRIBUTE);
@@ -2056,5 +2079,5 @@
 			DebugStream.println("There should be an IndexOption element which is assigned 'true': possible bug.");
 		}
-		Element indexOptionEl = to.createElement(StaticStrings.INDEXOPTION_STR);
+		//Element indexOptionEl = to.createElement(StaticStrings.INDEXOPTION_STR);
 		NodeList option_elements = index_option.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
 		int num_elements = option_elements.getLength();
@@ -2064,5 +2087,5 @@
 			return;//
 		}
-		search.appendChild(indexOptionEl);
+		//search.appendChild(indexOptionEl);
 
 		for (int k = 0; k < num_elements; k++)
@@ -2070,10 +2093,49 @@
 			Element e = (Element) option_elements.item(k);
 			String name_att = e.getAttribute(StaticStrings.NAME_ATTRIBUTE);
-			Element optionEl = to.createElement(StaticStrings.OPTION_STR);
+			Element optionEl = to.createElement(StaticStrings.INDEXOPTION_STR);
 			optionEl.setAttribute(StaticStrings.NAME_ATTRIBUTE, name_att);
-			indexOptionEl.appendChild(optionEl);
-		}
-
-	}
+			// default value?? on/off
+			//indexOptionEl.appendChild(optionEl);
+			search.appendChild(optionEl);
+		}
+
+	}
+
+  // handle top level elements which GLI knows nothing about
+  // we store them internally in a Unknown element for easy access when
+  // we write them out.
+  static private void doUnknownElements(Document to, Element from) {
+    Element toElement = to.getDocumentElement();
+    Element unknownElement = to.createElement(StaticStrings.UNKNOWN_ELEMENT);
+    toElement.appendChild(unknownElement);
+    
+    Node child = from.getFirstChild();
+    while (child != null)
+      {
+	System.err.println("child name=" +child.getNodeName());
+	if (child.getNodeType() == Node.ELEMENT_NODE && ! known_element_names.contains(child.getNodeName())) {
+	  unknownElement.appendChild(XMLTools.duplicateElement(to, (Element) child, true));
+	}
+	child = child.getNextSibling();
+      }
+    
+  }
+
+    // just copy all children of Unknown element into output doc.
+  static private void convertUnknownElements(Document from, Document to) {
+
+    Element toElement = to.getDocumentElement();
+    Node unknown_element = XMLTools.getChildByTagName(from.getDocumentElement(), StaticStrings.UNKNOWN_ELEMENT);
+
+    Node child = unknown_element.getFirstChild();
+    while (child != null)
+      {
+	Element to_element = XMLTools.duplicateElement(to, (Element) child, true);
+	toElement.appendChild(to_element);
+	
+	child = child.getNextSibling();
+      }
+
+  }
 
 	// Append the element son to the element mother in the appropriate position.
@@ -2379,6 +2441,7 @@
 		doDisplayFormat(dOc, fromElement);
 		doReplaceListRef(dOc, fromElement);
+		doReplaceList(dOc, fromElement);
 		doServiceRackList(dOc, fromElement);
-
+		doUnknownElements(dOc, fromElement); 
 		// the official displayItems in the displayItemList element have already been handled above
 		// and created as collectionmetadata elements in the dOc object
@@ -2445,4 +2508,5 @@
 		//first parse an empty skeleton of xml config file
 		//The aim is to convert the internal structure into this skeleton
+	  // This skeleton just has the CollectionConfig element and nothing else
 		Document skeleton = XMLTools.parseXMLFile("xml/CollectionConfig.xml", true);
 		//Element internal = dOc.getDocumentElement();
@@ -2462,5 +2526,7 @@
 		convertDisplayFormat(dOc, skeleton);
 		convertReplaceListRef(dOc, skeleton);
+		convertReplaceList(dOc, skeleton);
 		convertServiceRackList(dOc, skeleton);
+		convertUnknownElements(dOc, skeleton); // try to catch everything GLI doesn't know about
 
 		return skeleton;
