Index: main/trunk/gli/src/org/greenstone/gatherer/cdm/CollectionConfigXMLReadWrite.java
===================================================================
--- main/trunk/gli/src/org/greenstone/gatherer/cdm/CollectionConfigXMLReadWrite.java	(revision 25166)
+++ main/trunk/gli/src/org/greenstone/gatherer/cdm/CollectionConfigXMLReadWrite.java	(revision 25206)
@@ -639,5 +639,5 @@
 		if (format != null && format.hasChildNodes())
 		{ // not an empty format statement
-			String gsf_text = XMLTools.xmlNodeToStringWithoutIndenting(format);
+			String gsf_text = XMLTools.xmlNodeToString(format);
 			
 			//We don't want the <format> elements in the string
@@ -2366,9 +2366,7 @@
 	static public void save(File collect_config_xml_file, Document doc)
 	{
-
 		Document collection_config_xml_document = convertInternalToCollectionConfig(doc);
 		String[] nonEscapingTagNames = { StaticStrings.FORMAT_STR, StaticStrings.DISPLAYITEM_STR };
 		XMLTools.writeXMLFile(collect_config_xml_file, collection_config_xml_document, nonEscapingTagNames);
-
 	}
 
Index: main/trunk/gli/src/org/greenstone/gatherer/util/XMLTools.java
===================================================================
--- main/trunk/gli/src/org/greenstone/gatherer/util/XMLTools.java	(revision 25166)
+++ main/trunk/gli/src/org/greenstone/gatherer/util/XMLTools.java	(revision 25206)
@@ -712,6 +712,7 @@
 					xml.append("\n");
 				}
-				else {
-				  System.err.println(line);
+				else
+				{
+					System.err.println(line);
 				}
 			}
@@ -791,4 +792,51 @@
 	}
 
+	static public void indentXML(Element elem, int depth)
+	{
+		Document doc = elem.getOwnerDocument();
+
+		String startIndentString = "\n";
+		for (int i = 0; i < depth; i++)
+		{
+			startIndentString += "\t";
+		}
+		Node startTextNode = doc.createTextNode(startIndentString);
+
+		String endIndentString = "\n";
+		for (int i = 0; i < depth - 1; i++)
+		{
+			endIndentString += "\t";
+		}
+		Node endTextNode = doc.createTextNode(endIndentString);
+
+		boolean found = false;
+		Node child = elem.getFirstChild();
+		while (child != null)
+		{
+			if (child.getNodeType() == Node.ELEMENT_NODE)
+			{
+				found = true;
+				break;
+			}
+			child = child.getNextSibling();
+		}
+
+		if (found)
+		{
+			elem.appendChild(endTextNode);
+		}
+
+		child = elem.getFirstChild();
+		while (child != null)
+		{
+			if (child.getNodeType() == Node.ELEMENT_NODE)
+			{
+				elem.insertBefore(startTextNode.cloneNode(false), child);
+				indentXML((Element) child, depth + 1);
+			}
+			child = child.getNextSibling();
+		}
+	}
+
 	/**
 	 * Write an XML document to a given file with the text node of the specified
@@ -797,4 +845,5 @@
 	static public void writeXMLFile(File xml_file, Document document, String[] nonEscapingTagNames)
 	{
+		indentXML(document.getDocumentElement(), 1);
 		try
 		{
@@ -895,13 +944,134 @@
 	{
 		StringBuffer sb = new StringBuffer("");
-		xmlNodeToString(sb, e, 0);
+		xmlNodeToString(sb, e, true, 2);
 		return sb.toString();
 	}
 
-	private static void xmlNodeToString(StringBuffer sb, Node e, int depth)
+	private static void xmlNodeToString(StringBuffer sb, Node e, boolean indent, int depth)
+	{
+		if (e.getNodeType() == Node.TEXT_NODE)
+		{
+			if (e.getNodeValue() != "")
+			{
+				String text = e.getNodeValue();
+				text = text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("^[\\n\\r\\t\\s]*", "");
+				sb.append(text);
+			}
+			return;
+		}
+
+		if (e.getNodeType() == Node.COMMENT_NODE)
+		{
+			if (e.getNodeValue() != "")
+			{
+				sb.append("<!--" + e.getNodeValue() + "-->");
+			}
+			return;
+		}
+
+		if (indent)
+		{
+			for (int i = 0; i < depth; i++)
+			{
+				sb.append('\t');
+			}
+		}
+
+		sb.append('<');
+		sb.append(e.getNodeName());
+		NamedNodeMap attrs = e.getAttributes();
+		if (attrs != null)
+		{
+			for (int i = 0; i < attrs.getLength(); i++)
+			{
+				Node attr = attrs.item(i);
+				sb.append(' ');
+				sb.append(attr.getNodeName());
+				sb.append("=\"");
+				sb.append(attr.getNodeValue().replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;"));
+				sb.append('"');
+			}
+		}
+		NodeList children = e.getChildNodes();
+
+		boolean hasElements = false;
+		boolean indentSwapped = false;
+		for (int i = 0; i < children.getLength(); i++)
+		{
+			if (children.item(i).getNodeType() == Node.ELEMENT_NODE)
+			{
+				hasElements = true;
+			}
+			if (children.item(i).getNodeType() == Node.TEXT_NODE && indent)
+			{
+				if (children.item(i).getNodeValue().matches("[^\\s]*"))
+				{
+					indentSwapped = true;
+					indent = false;
+				}
+			}
+		}
+
+		if (children == null || children.getLength() == 0)
+		{
+			sb.append("/>");
+
+			if (indent)
+			{
+				sb.append("\n");
+			}
+		}
+		else
+		{
+			sb.append(">");
+			if (hasElements && indent)
+			{
+				sb.append("\n");
+			}
+
+			int len = children.getLength();
+			for (int i = 0; i < len; i++)
+			{
+				xmlNodeToString(sb, children.item(i), indent, depth + 1);
+			}
+
+			if (indent)
+			{
+				for (int i = 0; i < depth; i++)
+				{
+					sb.append('\t');
+				}
+			}
+
+			sb.append("</" + e.getNodeName() + ">");
+
+			if ((hasElements && indent) || indentSwapped)
+			{
+				sb.append("\n");
+			}
+		}
+	}
+
+	public static String xmlNodeToStringWithoutIndenting(Node e)
+	{
+		StringBuffer sb = new StringBuffer("");
+		xmlNodeToStringWithoutNewline(sb, e, -1);
+		return sb.toString();
+	}
+
+	public static String xmlNodeToStringWithoutNewline(Node e)
+	{
+		StringBuffer sb = new StringBuffer("");
+		xmlNodeToStringWithoutNewline(sb, e, 0);
+		return sb.toString();
+	}
+
+	private static void xmlNodeToStringWithoutNewline(StringBuffer sb, Node e, int depth)
 	{
 
 		for (int i = 0; i < depth; i++)
+		{
 			sb.append(' ');
+		}
 
 		if (e.getNodeType() == Node.TEXT_NODE)
@@ -909,9 +1079,9 @@
 			if (e.getNodeValue() != "")
 			{
-				sb.append(e.getNodeValue());
+				sb.append(e.getNodeValue().replaceAll("&", "&amp;").replaceAll("<", "&lt;").replace(">", "&gt;"));
 			}
 			return;
 		}
-		
+
 		if (e.getNodeType() == Node.COMMENT_NODE)
 		{
@@ -941,14 +1111,21 @@
 
 		if (children == null || children.getLength() == 0)
-			sb.append("/>\n");
+			sb.append("/>");
 		else
 		{
 
-			sb.append(">\n");
+			sb.append(">");
 
 			int len = children.getLength();
 			for (int i = 0; i < len; i++)
 			{
-				xmlNodeToString(sb, children.item(i), depth + 1);
+				if (depth >= 0)
+				{
+					xmlNodeToStringWithoutNewline(sb, children.item(i), depth + 1);
+				}
+				else
+				{
+					xmlNodeToStringWithoutNewline(sb, children.item(i), depth);
+				}
 			}
 
@@ -956,89 +1133,4 @@
 				sb.append(' ');
 
-			sb.append("</" + e.getNodeName() + ">\n");
-		}
-
-	}
-
-	public static String xmlNodeToStringWithoutIndenting(Node e)
-	{
-		StringBuffer sb = new StringBuffer("");
-		xmlNodeToStringWithoutNewline(sb, e, -1);
-		return sb.toString();
-	}
-
-	public static String xmlNodeToStringWithoutNewline(Node e)
-	{
-		StringBuffer sb = new StringBuffer("");
-		xmlNodeToStringWithoutNewline(sb, e, 0);
-		return sb.toString();
-	}
-
-	private static void xmlNodeToStringWithoutNewline(StringBuffer sb, Node e, int depth)
-	{
-
-		for (int i = 0; i < depth; i++)
-		{
-			sb.append(' ');
-		}
-
-		if (e.getNodeType() == Node.TEXT_NODE)
-		{
-			if (e.getNodeValue() != "")
-			{
-				sb.append(e.getNodeValue().replaceAll("&", "&amp;").replaceAll("<", "&lt;").replace(">", "&gt;"));
-			}
-			return;
-		}
-		
-		if (e.getNodeType() == Node.COMMENT_NODE)
-		{
-			if (e.getNodeValue() != "")
-			{
-				sb.append("<!--" + e.getNodeValue() + "-->");
-			}
-			return;
-		}
-
-		sb.append('<');
-		sb.append(e.getNodeName());
-		NamedNodeMap attrs = e.getAttributes();
-		if (attrs != null)
-		{
-			for (int i = 0; i < attrs.getLength(); i++)
-			{
-				Node attr = attrs.item(i);
-				sb.append(' ');
-				sb.append(attr.getNodeName());
-				sb.append("=\"");
-				sb.append(attr.getNodeValue());
-				sb.append('"');
-			}
-		}
-		NodeList children = e.getChildNodes();
-
-		if (children == null || children.getLength() == 0)
-			sb.append("/>");
-		else
-		{
-
-			sb.append(">");
-
-			int len = children.getLength();
-			for (int i = 0; i < len; i++)
-			{
-				if (depth >= 0)
-				{
-					xmlNodeToStringWithoutNewline(sb, children.item(i), depth + 1);
-				}
-				else
-				{
-					xmlNodeToStringWithoutNewline(sb, children.item(i), depth);
-				}
-			}
-
-			for (int i = 0; i < depth; i++)
-				sb.append(' ');
-
 			sb.append("</" + e.getNodeName() + ">");
 		}
