Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/LibraryCommandline.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/LibraryCommandline.java	(revision 27616)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/LibraryCommandline.java	(revision 27617)
@@ -64,5 +64,5 @@
 	{
 
-		HashMap<String, Comparable> config_params = new HashMap<String, Comparable>();
+		HashMap<String, Object> config_params = new HashMap<String, Object>();
 		//config_params.put(GSConstants.GSDL3_HOME, gsdl_home);
 		config_params.put(GSConstants.SITE_NAME, site_name);
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/LibraryServlet.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/LibraryServlet.java	(revision 27616)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/LibraryServlet.java	(revision 27617)
@@ -1,9 +1,14 @@
 package org.greenstone.gsdl3;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.Serializable;
 import java.lang.reflect.Type;
+import java.nio.channels.FileChannel;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -21,5 +26,9 @@
 import javax.servlet.http.HttpSessionBindingEvent;
 import javax.servlet.http.HttpSessionBindingListener;
-
+import javax.servlet.http.Part;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
@@ -36,4 +45,5 @@
 import org.greenstone.gsdl3.util.UserContext;
 import org.greenstone.gsdl3.util.XMLConverter;
+import org.greenstone.util.GlobalProperties;
 import org.json.JSONObject;
 import org.w3c.dom.Document;
@@ -169,5 +179,5 @@
 		}
 
-		HashMap<String, Comparable> config_params = new HashMap<String, Comparable>();
+		HashMap<String, Object> config_params = new HashMap<String, Object>();
 
 		config_params.put(GSConstants.LIBRARY_NAME, library_name);
@@ -315,5 +325,4 @@
 	public class UserSessionCache implements HttpSessionBindingListener
 	{
-
 		String session_id = "";
 
@@ -368,9 +377,8 @@
 	}
 
-	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+	public void doGetOrPost(HttpServletRequest request, HttpServletResponse response, Map<String, String[]> queryMap) throws ServletException, IOException
 	{
 		logUsageInfo(request);
 
-		Map<String, String[]> queryMap = request.getParameterMap();
 		if (queryMap != null)
 		{
@@ -380,4 +388,5 @@
 			String rl = null;
 			String el = null;
+
 			while (queryIter.hasNext())
 			{
@@ -437,5 +446,5 @@
 		PrintWriter out = response.getWriter();
 
-		String lang = request.getParameter(GSParams.LANGUAGE);
+		String lang = getFirstParam(GSParams.LANGUAGE, queryMap);
 		if (lang == null || lang.equals(""))
 		{
@@ -454,4 +463,7 @@
 		if (request.getAuthType() != null)
 		{
+			//Get the username
+			userContext.setUsername(request.getUserPrincipal().getName());
+
 			//Get the groups for the user
 			Element acquireGroupMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
@@ -461,5 +473,5 @@
 			Element paramList = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
 			acquireGroupRequest.appendChild(paramList);
-			paramList.appendChild(GSXML.createParameter(this.doc, "username", request.getUserPrincipal().getName()));
+			paramList.appendChild(GSXML.createParameter(this.doc, GSXML.USERNAME_ATT, request.getUserPrincipal().getName()));
 
 			Element aquireGroupsResponseMessage = (Element) this.recept.process(acquireGroupMessage);
@@ -478,5 +490,5 @@
 		session.setAttribute(GSParams.LANGUAGE, lang);
 
-		String output = request.getParameter(GSParams.OUTPUT);
+		String output = getFirstParam(GSParams.OUTPUT, queryMap);
 		if (output == null || output.equals(""))
 		{
@@ -517,9 +529,9 @@
 		xml_message.appendChild(xml_request);
 
-		String action = request.getParameter(GSParams.ACTION);
-		String subaction = request.getParameter(GSParams.SUBACTION);
-		String collection = request.getParameter(GSParams.COLLECTION);
-		String document = request.getParameter(GSParams.DOCUMENT);
-		String service = request.getParameter(GSParams.SERVICE);
+		String action = getFirstParam(GSParams.ACTION, queryMap);
+		String subaction = getFirstParam(GSParams.SUBACTION, queryMap);
+		String collection = getFirstParam(GSParams.COLLECTION, queryMap);
+		String document = getFirstParam(GSParams.DOCUMENT, queryMap);
+		String service = getFirstParam(GSParams.SERVICE, queryMap);
 
 		// We clean up the cache session_ids_table if system
@@ -536,5 +548,5 @@
 			// collection param is in the sc parameter.
 			// don't like the fact that it is hard coded here
-			String coll = request.getParameter(GSParams.SYSTEM_CLUSTER);
+			String coll = getFirstParam(GSParams.SYSTEM_CLUSTER, queryMap);
 			if (coll != null && !coll.equals(""))
 			{
@@ -547,5 +559,5 @@
 				if (subaction.equals("a") || subaction.equals("d"))
 				{
-					String module_name = request.getParameter("sn");
+					String module_name = getFirstParam("sn", queryMap);
 					if (module_name != null && !module_name.equals(""))
 					{
@@ -655,5 +667,5 @@
 
 					String value = "";
-					String[] values = request.getParameterValues(name);
+					String[] values = queryMap.get(name);
 					value = values[0];
 					if (values.length > 1)
@@ -722,5 +734,5 @@
 
 		//Add custom HTTP headers if requested
-		String httpHeadersParam = request.getParameter(GSParams.HTTP_HEADER_FIELDS);
+		String httpHeadersParam = getFirstParam(GSParams.HTTP_HEADER_FIELDS, queryMap);
 		if (httpHeadersParam != null && httpHeadersParam.length() > 0)
 		{
@@ -768,5 +780,5 @@
 		xml_request.setAttribute("fullURL", fullURL.replace("&", "&amp;"));
 
-		if (!runSecurityChecks(request, xml_request, userContext, out, baseURL, collection, document))
+		if (!runSecurityChecks(request, xml_request, userContext, out, baseURL, collection, document, queryMap))
 		{
 			return;
@@ -798,14 +810,17 @@
 
 		displaySize(session_ids_table);
-
+	}
+
+	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+	{
+		doGetOrPost(request, response, request.getParameterMap());
 	} //end of doGet(HttpServletRequest, HttpServletResponse)
 
-	private boolean runSecurityChecks(HttpServletRequest request, Element xml_request, UserContext userContext, PrintWriter out, String baseURL, String collection, String document) throws ServletException
+	private boolean runSecurityChecks(HttpServletRequest request, Element xml_request, UserContext userContext, PrintWriter out, String baseURL, String collection, String document, Map<String, String[]> queryMap) throws ServletException
 	{
 		//Check if we need to login or logout
-		Map<String, String[]> params = request.getParameterMap();
-		String[] username = params.get("username");
-		String[] password = params.get("password");
-		String[] logout = params.get("logout");
+		String username = getFirstParam("username", queryMap);
+		String password = getFirstParam("password", queryMap);
+		String logout = getFirstParam("logout", queryMap);
 
 		if (logout != null)
@@ -822,115 +837,22 @@
 			}
 
+			//This try/catch block catches when the login request fails (e.g. The user enters an incorrect password).
 			try
 			{
-				password[0] = Authentication.hashPassword(password[0]);
-				request.login(username[0], password[0]);
+				//Try a global login first
+				password = Authentication.hashPassword(password);
+				request.login(username, password);
 			}
 			catch (Exception ex)
 			{
-				//The user entered in either the wrong username or the wrong password
-				Element loginPageMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
-				Element loginPageRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PAGE, "", userContext);
-				loginPageRequest.setAttribute(GSXML.ACTION_ATT, "p");
-				loginPageRequest.setAttribute(GSXML.SUBACTION_ATT, "login");
-				loginPageRequest.setAttribute(GSXML.OUTPUT_ATT, "html");
-				loginPageRequest.setAttribute(GSXML.BASE_URL, baseURL);
-				loginPageMessage.appendChild(loginPageRequest);
-
-				Element paramList = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
-				loginPageRequest.appendChild(paramList);
-
-				Element messageParam = this.doc.createElement(GSXML.PARAM_ELEM);
-				messageParam.setAttribute(GSXML.NAME_ATT, "loginMessage");
-				messageParam.setAttribute(GSXML.VALUE_ATT, "Either your username or password was incorrect, please try again.");
-				paramList.appendChild(messageParam);
-
-				Element urlParam = this.doc.createElement(GSXML.PARAM_ELEM);
-				urlParam.setAttribute(GSXML.NAME_ATT, "redirectURL");
-				String queryString = "";
-				if (request.getQueryString() != null)
-				{
-					queryString = "?" + request.getQueryString().replace("&", "&amp;");
-				}
-				urlParam.setAttribute(GSXML.VALUE_ATT, this.getServletName() + queryString);
-				paramList.appendChild(urlParam);
-
-				Node loginPageResponse = this.recept.process(loginPageMessage);
-				out.println(this.converter.getPrettyString(loginPageResponse));
-
-				return false;
-			}
-		}
-
-		//If a user is logged in
-		if (request.getAuthType() != null)
-		{
-			Element userInformation = this.doc.createElement(GSXML.USER_INFORMATION_ELEM);
-			userInformation.setAttribute("username", request.getUserPrincipal().getName());
-
-			Element userInfoMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
-			Element userInfoRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_SECURITY, "GetUserInformation", userContext);
-			userInfoMessage.appendChild(userInfoRequest);
-
-			Element paramList = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
-			userInfoRequest.appendChild(paramList);
-
-			Element param = this.doc.createElement(GSXML.PARAM_ELEM);
-			param.setAttribute(GSXML.NAME_ATT, GSXML.USERNAME_ATT);
-			param.setAttribute(GSXML.VALUE_ATT, request.getUserPrincipal().getName());
-			paramList.appendChild(param);
-
-			Element userInformationResponse = (Element) GSXML.getChildByTagName(this.recept.process(userInfoMessage), GSXML.RESPONSE_ELEM);
-			Element responseParamList = (Element) GSXML.getChildByTagName(userInformationResponse, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
-			if (responseParamList == null)
-			{
-				logger.error("Can't get the groups for user " + request.getUserPrincipal().getName());
-			}
-			else
-			{
-				HashMap<String, Serializable> responseParams = GSXML.extractParams(responseParamList, true);
-				String groups = (String) responseParams.get(GSXML.GROUPS_ATT);
-
-				userInformation.setAttribute(GSXML.GROUPS_ATT, groups);
-				xml_request.appendChild(userInformation);
-			}
-		}
-
-		//If we are in a collection-related page then make sure this user is allowed to access it
-		if (collection != null && !collection.equals(""))
-		{
-			//Get the security info for this collection
-			Element securityMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
-			Element securityRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_SECURITY, collection, userContext);
-			securityMessage.appendChild(securityRequest);
-			if (document != null && !document.equals(""))
-			{
-				securityRequest.setAttribute(GSXML.NODE_OID, document);
-			}
-
-			Element securityResponse = (Element) GSXML.getChildByTagName(this.recept.process(securityMessage), GSXML.RESPONSE_ELEM);
-			if (securityResponse == null)
-			{
-				return false;
-			}
-
-			ArrayList<String> groups = GSXML.getGroupsFromSecurityResponse(securityResponse);
-
-			//If guests are not allowed to access this page then check to see if the user is in a group that is allowed to access the page
-			if (!groups.contains(""))
-			{
-				boolean found = false;
-				for (String group : groups)
-				{
-					if (request.isUserInRole(group))
-					{
-						found = true;
-						break;
-					}
-				}
-
-				//The current user is not allowed to access the page so produce a login page
-				if (!found)
-				{
+				try
+				{
+					//If the global login fails then try a site-level login
+					String siteName = (String) this.recept.getConfigParams().get(GSConstants.SITE_NAME);
+					request.login(siteName + "-" + username, password);
+				}
+				catch (Exception exc)
+				{
+					//The user entered in either the wrong username or the wrong password
 					Element loginPageMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
 					Element loginPageRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PAGE, "", userContext);
@@ -946,4 +868,108 @@
 					Element messageParam = this.doc.createElement(GSXML.PARAM_ELEM);
 					messageParam.setAttribute(GSXML.NAME_ATT, "loginMessage");
+					messageParam.setAttribute(GSXML.VALUE_ATT, "Either your username or password was incorrect, please try again.");
+					paramList.appendChild(messageParam);
+
+					Element urlParam = this.doc.createElement(GSXML.PARAM_ELEM);
+					urlParam.setAttribute(GSXML.NAME_ATT, "redirectURL");
+					String queryString = "";
+					if (request.getQueryString() != null)
+					{
+						queryString = "?" + request.getQueryString().replace("&", "&amp;");
+					}
+					urlParam.setAttribute(GSXML.VALUE_ATT, this.getServletName() + queryString);
+					paramList.appendChild(urlParam);
+
+					Node loginPageResponse = this.recept.process(loginPageMessage);
+					out.println(this.converter.getPrettyString(loginPageResponse));
+
+					return false;
+				}
+			}
+		}
+
+		//If a user is logged in
+		if (request.getAuthType() != null)
+		{
+			Element userInformation = this.doc.createElement(GSXML.USER_INFORMATION_ELEM);
+			userInformation.setAttribute(GSXML.USERNAME_ATT, request.getUserPrincipal().getName());
+
+			Element userInfoMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
+			Element userInfoRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_SECURITY, "GetUserInformation", userContext);
+			userInfoMessage.appendChild(userInfoRequest);
+
+			Element paramList = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
+			userInfoRequest.appendChild(paramList);
+
+			Element param = this.doc.createElement(GSXML.PARAM_ELEM);
+			param.setAttribute(GSXML.NAME_ATT, GSXML.USERNAME_ATT);
+			param.setAttribute(GSXML.VALUE_ATT, request.getUserPrincipal().getName());
+			paramList.appendChild(param);
+
+			Element userInformationResponse = (Element) GSXML.getChildByTagName(this.recept.process(userInfoMessage), GSXML.RESPONSE_ELEM);
+			Element responseParamList = (Element) GSXML.getChildByTagName(userInformationResponse, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
+			if (responseParamList == null)
+			{
+				logger.error("Can't get the groups for user " + request.getUserPrincipal().getName());
+			}
+			else
+			{
+				HashMap<String, Serializable> responseParams = GSXML.extractParams(responseParamList, true);
+				String groups = (String) responseParams.get(GSXML.GROUPS_ATT);
+
+				userInformation.setAttribute(GSXML.GROUPS_ATT, groups);
+				xml_request.appendChild(userInformation);
+			}
+		}
+
+		//If we are in a collection-related page then make sure this user is allowed to access it
+		if (collection != null && !collection.equals(""))
+		{
+			//Get the security info for this collection
+			Element securityMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
+			Element securityRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_SECURITY, collection, userContext);
+			securityMessage.appendChild(securityRequest);
+			if (document != null && !document.equals(""))
+			{
+				securityRequest.setAttribute(GSXML.NODE_OID, document);
+			}
+
+			Element securityResponse = (Element) GSXML.getChildByTagName(this.recept.process(securityMessage), GSXML.RESPONSE_ELEM);
+			if (securityResponse == null)
+			{
+				return false;
+			}
+
+			ArrayList<String> groups = GSXML.getGroupsFromSecurityResponse(securityResponse);
+
+			//If guests are not allowed to access this page then check to see if the user is in a group that is allowed to access the page
+			if (!groups.contains(""))
+			{
+				boolean found = false;
+				for (String group : groups)
+				{
+					if (request.isUserInRole(group))
+					{
+						found = true;
+						break;
+					}
+				}
+
+				//The current user is not allowed to access the page so produce a login page
+				if (!found)
+				{
+					Element loginPageMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
+					Element loginPageRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PAGE, "", userContext);
+					loginPageRequest.setAttribute(GSXML.ACTION_ATT, "p");
+					loginPageRequest.setAttribute(GSXML.SUBACTION_ATT, "login");
+					loginPageRequest.setAttribute(GSXML.OUTPUT_ATT, "html");
+					loginPageRequest.setAttribute(GSXML.BASE_URL, baseURL);
+					loginPageMessage.appendChild(loginPageRequest);
+
+					Element paramList = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
+					loginPageRequest.appendChild(paramList);
+
+					Element messageParam = this.doc.createElement(GSXML.PARAM_ELEM);
+					messageParam.setAttribute(GSXML.NAME_ATT, "loginMessage");
 					if (request.getAuthType() == null)
 					{
@@ -1020,5 +1046,4 @@
 	protected void encodeURLs(Node dataNode, HttpServletResponse response)
 	{
-
 		if (dataNode == null)
 		{
@@ -1087,4 +1112,15 @@
 	}
 
+	protected String getFirstParam(String name, Map<String, String[]> map)
+	{
+		String[] val = map.get(name);
+		if (val == null || val.length == 0)
+		{
+			return null;
+		}
+
+		return val[0];
+	}
+
 	synchronized protected int getNextUserId()
 	{
@@ -1095,5 +1131,54 @@
 	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
 	{
-		doGet(request, response);
+		//Check if we need to process a file upload
+		if (ServletFileUpload.isMultipartContent(request))
+		{
+			DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
+
+			int sizeLimit = System.getProperties().containsKey("servlet.upload.filesize.limit") ? Integer.parseInt(System.getProperty("servlet.upload.filesize.limit")) : 100 * 1024 * 1024;
+
+			File tempDir = new File(GlobalProperties.getGSDL3Home() + File.separator + "tmp");
+			if (!tempDir.exists())
+			{
+				tempDir.mkdirs();
+			}
+
+			//We want all files to be stored on disk (hence the 0)
+			fileItemFactory.setSizeThreshold(0);
+			fileItemFactory.setRepository(tempDir);
+
+			ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);
+			uploadHandler.setFileSizeMax(sizeLimit);
+
+			HashMap<String, String[]> queryMap = new HashMap<String, String[]>();
+			try
+			{
+				List items = uploadHandler.parseRequest(request);
+				Iterator iter = items.iterator();
+				while (iter.hasNext())
+				{
+					FileItem current = (FileItem) iter.next();
+					if (current.isFormField())
+					{
+						queryMap.put(current.getFieldName(), new String[] { current.getString() });
+					}
+					else if (current.getName() != null && !current.getName().equals(""))
+					{
+						File file = new File(tempDir, current.getName());
+						current.write(file);
+					}
+				}
+			}
+			catch (Exception e)
+			{
+				e.printStackTrace();
+			}
+
+			doGetOrPost(request, response, queryMap);
+		}
+		else
+		{
+			doGetOrPost(request, response, request.getParameterMap());
+		}
 	}
 }
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/Action.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/Action.java	(revision 27616)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/Action.java	(revision 27617)
@@ -23,5 +23,5 @@
 
 	/** the system set up variables */
-	protected HashMap<String, Comparable> config_params = null;
+	protected HashMap<String, Object> config_params = null;
 	/** container Document to create XML Nodes */
 	protected Document doc = null;
@@ -43,5 +43,5 @@
 
 	/** the config variables must be set before configure is called */
-	public void setConfigParams(HashMap<String, Comparable> params)
+	public void setConfigParams(HashMap<String, Object> params)
 	{
 		this.config_params = params;
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/DepositorAction.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/DepositorAction.java	(revision 27617)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/DepositorAction.java	(revision 27617)
@@ -0,0 +1,231 @@
+package org.greenstone.gsdl3.action;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.greenstone.gsdl3.util.DerbyWrapper;
+import org.greenstone.gsdl3.util.GSConstants;
+import org.greenstone.gsdl3.util.GSXML;
+import org.greenstone.gsdl3.util.GSXSLT;
+import org.greenstone.gsdl3.util.UserContext;
+import org.greenstone.util.GlobalProperties;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+public class DepositorAction extends Action
+{
+	//Sub actions
+	private final String DE_RETRIEVE_WIZARD = "getWizard";
+
+	public Node process(Node message)
+	{
+		Element request = (Element) GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
+
+		UserContext uc = new UserContext((Element) request);
+		String currentUsername = uc.getUsername();
+
+		Element responseMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
+		Element response = GSXML.createBasicResponse(this.doc, this.getClass().getSimpleName());
+		responseMessage.appendChild(response);
+
+		Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
+		HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
+
+		String collection = (String) params.get("c");
+
+		int pageNum = -1;
+		boolean parseFail = false;
+		try
+		{
+			pageNum = Integer.parseInt(((String) params.get("dePage")));
+		}
+		catch (Exception ex)
+		{
+			parseFail = true;
+			ex.printStackTrace();
+		}
+
+		DerbyWrapper database = new DerbyWrapper();
+		database.connectDatabase(GlobalProperties.getGSDL3Home() + File.separator + "sites" + File.separator + this.config_params.get(GSConstants.SITE_NAME) + File.separatorChar + "etc" + File.separatorChar + "usersDB", false);
+		if (parseFail)
+		{
+			try
+			{
+				pageNum = Integer.parseInt(database.getUserData(currentUsername, "DE___" + collection + "___CACHED_PAGE"));
+			}
+			catch (Exception ex)
+			{
+				pageNum = 1;
+			}
+		}
+
+		String subaction = ((Element) request).getAttribute(GSXML.SUBACTION_ATT);
+		if (subaction.equals(DE_RETRIEVE_WIZARD))
+		{
+			//Save given metadata
+			StringBuilder saveString = new StringBuilder("[");
+			Iterator<String> paramIter = params.keySet().iterator();
+			while (paramIter.hasNext())
+			{
+				String paramName = paramIter.next();
+				if (paramName.startsWith("md___"))
+				{
+					Object paramValue = params.get(paramName);
+
+					if (paramValue instanceof String)
+					{
+						saveString.append("{name:\"" + paramName + "\", value:\"" + (String) paramValue + "\"},");
+					}
+					else if (paramValue instanceof HashMap)
+					{
+						HashMap<String, String> subMap = (HashMap<String, String>) paramValue;
+						Iterator<String> subKeyIter = subMap.keySet().iterator();
+						while (subKeyIter.hasNext())
+						{
+							String subName = subKeyIter.next();
+							saveString.append("{name:\"" + paramName + "." + subName + "\", value:\"" + subMap.get(subName) + "\"},");
+						}
+					}
+				}
+			}
+			if (saveString.length() > 2)
+			{
+				saveString.deleteCharAt(saveString.length() - 1);
+				saveString.append("]");
+
+				database.addUserData(currentUsername, "DE___" + collection + "___" + pageNum + "___CACHED_VALUES", saveString.toString());
+			}
+
+			//Construct the xsl
+			Document compiledDepositorFile = null;
+			try
+			{
+				compiledDepositorFile = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+			}
+			catch (Exception ex)
+			{
+				ex.printStackTrace();
+			}
+			Document depositorBaseFile = GSXSLT.mergedXSLTDocumentCascade("depositor/depositor.xsl", (String) this.config_params.get(GSConstants.SITE_NAME), collection, (String) this.config_params.get(GSConstants.INTERFACE_NAME), (ArrayList<String>) this.config_params.get(GSConstants.BASE_INTERFACES), false);
+
+			Element numOfPagesElement = GSXML.getNamedElement(depositorBaseFile.getDocumentElement(), "xsl:variable", "name", "numOfPages");
+			int numberOfPages = Integer.parseInt(numOfPagesElement.getTextContent());
+
+			compiledDepositorFile.appendChild(compiledDepositorFile.importNode(depositorBaseFile.getDocumentElement(), true));
+
+			ArrayList<Document> pageDocs = new ArrayList<Document>();
+			ArrayList<String> pageNames = new ArrayList<String>();
+			for (int i = 1; i <= numberOfPages; i++)
+			{
+				Document page = GSXSLT.mergedXSLTDocumentCascade("depositor/de_page" + i + ".xsl", (String) this.config_params.get(GSConstants.SITE_NAME), collection, (String) this.config_params.get(GSConstants.INTERFACE_NAME), (ArrayList<String>) this.config_params.get(GSConstants.BASE_INTERFACES), false);
+				pageDocs.add(page);
+
+				Element pageTitleElem = (Element) GSXML.getNamedElement(page.getDocumentElement(), "xsl:variable", "name", "title");
+				pageNames.add(pageTitleElem.getTextContent());
+
+				Element wizardPageElem = (Element) GSXML.getNamedElement(page.getDocumentElement(), "xsl:template", "name", "wizardPage");
+				wizardPageElem.setAttribute("name", "wizardPage" + i);
+				compiledDepositorFile.getDocumentElement().appendChild(compiledDepositorFile.importNode(wizardPageElem, true));
+			}
+
+			//Create the wizard bar
+			Element wizardBarTemplate = GSXML.getNamedElement(compiledDepositorFile.getDocumentElement(), "xsl:template", "name", "wizardBar");
+			Element wizardBar = compiledDepositorFile.createElement("ul");
+			wizardBar.setAttribute("id", "wizardBar");
+			wizardBarTemplate.appendChild(wizardBar);
+
+			for (int i = 0; i < pageNames.size(); i++)
+			{
+				String pageName = pageNames.get(i);
+				Element pageLi = compiledDepositorFile.createElement("li");
+				if (pageNum == i + 1)
+				{
+					pageLi.setAttribute("class", "wizardStepLink ui-state-active ui-corner-all");
+				}
+				else
+				{
+					pageLi.setAttribute("class", "wizardStepLink ui-state-default ui-corner-all");
+				}
+				Element link = compiledDepositorFile.createElement("a");
+				pageLi.appendChild(link);
+
+				link.setAttribute(GSXML.HREF_ATT, "javascript:;");
+				link.setAttribute("page", "" + (i + 1));
+				link.appendChild(compiledDepositorFile.createTextNode(pageName));
+				wizardBar.appendChild(pageLi);
+			}
+
+			//Add a call-template call to the appropriate page in the xsl
+			Element mainDePageElem = GSXML.getNamedElement(compiledDepositorFile.getDocumentElement(), "xsl:template", "match", "/page");
+			Element wizardContainer = GSXML.getNamedElement(mainDePageElem, "div", "id", "wizardContainer");
+			Element formContainer = GSXML.getNamedElement(wizardContainer, "form", "name", "depositorform");
+			Element callToPage = compiledDepositorFile.createElement("xsl:call-template");
+			callToPage.setAttribute("name", "wizardPage" + pageNum);
+			formContainer.appendChild(callToPage);
+
+			Element cachedValueElement = this.doc.createElement("cachedValues");
+			response.appendChild(cachedValueElement);
+			try
+			{
+				for (int i = pageNum; i > 0; i--)
+				{
+					Element page = this.doc.createElement("pageCache");
+					page.setAttribute("pageNum", "" + pageNum);
+					String cachedValues = database.getUserData(currentUsername, "DE___" + collection + "___" + i + "___CACHED_VALUES");
+					page.appendChild(this.doc.createTextNode(cachedValues));
+					cachedValueElement.appendChild(page);
+				}
+			}
+			catch (Exception ex)
+			{
+				ex.printStackTrace();
+			}
+
+			try
+			{
+				Transformer transformer = TransformerFactory.newInstance().newTransformer();
+
+				File newFileDir = new File(GlobalProperties.getGSDL3Home() + File.separator + "sites" + File.separator + this.config_params.get(GSConstants.SITE_NAME) + File.separator + "collect" + File.separator + collection + File.separator + "transform" + File.separator + "depositor");
+				newFileDir.mkdirs();
+
+				File newFile = new File(newFileDir, File.separator + "compiledDepositor.xsl");
+
+				//initialize StreamResult with File object to save to file
+				StreamResult sresult = new StreamResult(new FileWriter(newFile));
+				DOMSource source = new DOMSource(compiledDepositorFile);
+				transformer.transform(source, sresult);
+			}
+			catch (Exception ex)
+			{
+				ex.printStackTrace();
+			}
+			database.closeDatabase();
+		}
+
+		return responseMessage;
+	}
+
+	public Element getCollectionsInSite()
+	{
+		Element message = this.doc.createElement(GSXML.MESSAGE_ELEM);
+		Element request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, "", new UserContext());
+		message.appendChild(request);
+		Element responseMessage = (Element) this.mr.process(message);
+
+		Element response = (Element) GSXML.getChildByTagName(responseMessage, GSXML.RESPONSE_ELEM);
+		Element collectionList = (Element) GSXML.getChildByTagName(response, GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
+
+		return collectionList;
+	}
+}
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/PageAction.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/PageAction.java	(revision 27616)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/PageAction.java	(revision 27617)
@@ -1,18 +1,16 @@
 package org.greenstone.gsdl3.action;
 
+import java.io.Serializable;
+import java.util.HashMap;
+
+import org.apache.log4j.Logger;
+import org.greenstone.gsdl3.util.GSParams;
+import org.greenstone.gsdl3.util.GSPath;
+import org.greenstone.gsdl3.util.GSXML;
+import org.greenstone.gsdl3.util.UserContext;
 import org.greenstone.util.GlobalProperties;
-import org.greenstone.gsdl3.core.ModuleInterface;
-import org.greenstone.gsdl3.util.*;
-//XML classes
+import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import java.util.HashMap;
-import java.io.File;
-import java.io.Serializable;
-
-import org.apache.log4j.*;
 
 public class PageAction extends Action
@@ -31,5 +29,5 @@
 		Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
 		String collection = "";
-		if(paramList != null)
+		if (paramList != null)
 		{
 			HashMap<String, Serializable> params = GSXML.extractParams(paramList, false);
@@ -65,6 +63,4 @@
 		else
 		{ // unknown page
-
-			logger.error("unknown page specified!");
 			response = unknownPage(request);
 		}
@@ -84,4 +80,5 @@
 		result.appendChild(this.doc.importNode(response, true));
 		logger.debug("page action result: " + this.converter.getPrettyString(result));
+
 		return result;
 	}
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/Receptionist.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/Receptionist.java	(revision 27616)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/Receptionist.java	(revision 27617)
@@ -31,5 +31,5 @@
 
 	/** the set up variables */
-	protected HashMap<String, Comparable> config_params = null;
+	protected HashMap<String, Object> config_params = null;
 	/** container Document to create XML Nodes */
 	protected Document doc = null;
@@ -71,10 +71,10 @@
 	}
 
-	public void setConfigParams(HashMap<String, Comparable> params)
+	public void setConfigParams(HashMap<String, Object> params)
 	{
 		this.config_params = params;
 	}
 
-	public HashMap<String, Comparable> getConfigParams()
+	public HashMap<String, Object> getConfigParams()
 	{
 		return this.config_params;
@@ -316,4 +316,5 @@
 			}
 			base_interfaces.add(base_interface);
+			this.config_params.put(GSConstants.BASE_INTERFACES, base_interfaces);
 			// now see if this has a base interface
 			Document config_doc = this.converter.getDOM(base_interface_config_file);
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/TransformingReceptionist.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/TransformingReceptionist.java	(revision 27616)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/TransformingReceptionist.java	(revision 27617)
@@ -318,4 +318,9 @@
 				//Add the names from this file
 				ArrayList<String> currentNames = metaNames.get(currentFileTemp.getAbsolutePath());
+				if (currentNames == null)
+				{
+					continue;
+				}
+
 				fullNameList.addAll(currentNames);
 
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/DerbyWrapper.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/DerbyWrapper.java	(revision 27616)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/DerbyWrapper.java	(revision 27617)
@@ -21,4 +21,5 @@
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -36,4 +37,5 @@
 	static final String USERS = "users";
 	static final String ROLES = "roles";
+	static final String DATA = "data";
 	private Connection conn = null;
 	private Statement state = null;
@@ -142,4 +144,5 @@
 			state.execute("create table users (username varchar(40) not null, password varchar(40) not null, accountstatus varchar(10), comment varchar(100), email varchar(40), primary key(username))");
 			state.execute("create table roles (username varchar(40) not null, role varchar(40) not null, primary key (username, role))");
+			state.execute("create table data (username varchar(40) not null, name varchar(128) not null, value clob, primary key (username, name))");
 			state.execute("insert into " + USERS + " values ('admin', '" + Authentication.hashPassword("admin") + "', 'true', 'change the password for this account as soon as possible', '')");
 			state.execute("insert into " + ROLES + " values ('admin', 'administrator')");
@@ -174,5 +177,5 @@
 		for (HashMap<String, String> user : users)
 		{
-			ResultSet gs = state.executeQuery("SELECT role FROM roles WHERE username = '" + user.get("username") + "'");
+			ResultSet gs = state.executeQuery("SELECT role FROM " + ROLES + " WHERE username = '" + user.get("username") + "'");
 			String group = "";
 			while (gs.next())
@@ -196,4 +199,102 @@
 			return userQueryResult;
 		}
+	}
+
+	public boolean addUserData(String username, String name, String value)
+	{
+		//Check if we already have a value under this name
+		boolean found = false;
+		try
+		{
+			ResultSet rs = state.executeQuery("SELECT * FROM " + DATA + " WHERE username='" + username + "' AND name='" + name + "'");
+			if (rs.next())
+			{
+				found = true;
+			}
+			else
+			{
+				found = false;
+			}
+		}
+		catch (Exception ex)
+		{
+			System.out.println("exception thrown:");
+			if (ex instanceof SQLException)
+			{
+				printSQLError((SQLException) ex);
+			}
+			else
+			{
+				ex.printStackTrace();
+			}
+			closeDatabase();
+			System.out.println("Error:" + ex.getMessage());
+			return false;
+		}
+
+		try
+		{
+			if (!found)
+			{
+				PreparedStatement stmt = null;
+				stmt = conn.prepareStatement("INSERT INTO " + DATA + " VALUES (?, ?, ?)");
+				stmt.setString(1, username);
+				stmt.setString(2, name);
+				stmt.setString(3, value);
+				stmt.executeUpdate();
+			}
+			else
+			{
+				PreparedStatement stmt = null;
+				stmt = conn.prepareStatement("UPDATE " + DATA + " SET value=? WHERE username=? AND name=?");
+				stmt.setString(1, value);
+				stmt.setString(2, username);
+				stmt.setString(3, name);
+				stmt.executeUpdate();
+			}
+		}
+		catch (Exception ex)
+		{
+			System.out.println("exception thrown:");
+			if (ex instanceof SQLException)
+			{
+				printSQLError((SQLException) ex);
+			}
+			else
+			{
+				ex.printStackTrace();
+			}
+			closeDatabase();
+			System.out.println("Error:" + ex.getMessage());
+			return false;
+		}
+		return true;
+	}
+
+	public String getUserData(String username, String name)
+	{
+		try
+		{
+			ResultSet rs = state.executeQuery("SELECT * FROM " + DATA + " WHERE username='" + username + "' AND name='" + name + "'");
+			if (rs.next())
+			{
+				return rs.getString("value");
+			}
+		}
+		catch (Exception ex)
+		{
+			System.out.println("exception thrown:");
+			if (ex instanceof SQLException)
+			{
+				printSQLError((SQLException) ex);
+			}
+			else
+			{
+				ex.printStackTrace();
+			}
+			closeDatabase();
+			System.out.println("Error:" + ex.getMessage());
+		}
+		return null;
 	}
 
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSConstants.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSConstants.java	(revision 27616)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSConstants.java	(revision 27617)
@@ -20,18 +20,19 @@
 
 /** these constants are used for servlet args, and config variables */
-public class GSConstants {
+public class GSConstants
+{
+	public static final String GSDL3_HOME = "gsdl3_home";
+	public static final String INTERFACE_NAME = "interface_name";
+	public static final String SITE_NAME = "site_name";
+	public static final String LIBRARY_NAME = "library_name";
+	public static final String BASE_INTERFACES = "base_interfaces";
+	public static final String DEFAULT_LANG = "default_lang";
+	public static final String ALLOW_CLIENT_SIDE_XSLT = "allow_client_side_xslt";
+	public static final String CLIENT_SIDE_XSLT_INTERFACE_SUFFIX = "-client-xslt";
 
-    public static final String GSDL3_HOME = "gsdl3_home";
-    public static final String INTERFACE_NAME = "interface_name";
-    public static final String SITE_NAME = "site_name";
-    public static final String LIBRARY_NAME = "library_name";
-    public static final String DEFAULT_LANG = "default_lang";
-    public static final String ALLOW_CLIENT_SIDE_XSLT = "allow_client_side_xslt";
-    public static final String CLIENT_SIDE_XSLT_INTERFACE_SUFFIX = "-client-xslt";
-
-    public static final String META_RELATION_SEP = "_";
-    public static final String META_SEPARATOR_SEP = "*";
-    public static final String META_FIRST = "first";
-    public static final String META_LAST = "last";
-    public static final String META_POS = "pos";
+	public static final String META_RELATION_SEP = "_";
+	public static final String META_SEPARATOR_SEP = "*";
+	public static final String META_FIRST = "first";
+	public static final String META_LAST = "last";
+	public static final String META_POS = "pos";
 }
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java	(revision 27616)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java	(revision 27617)
@@ -788,26 +788,31 @@
 	{
 		Element request = owner.createElement(REQUEST_ELEM);
+		request.setAttribute(TO_ATT, to);
 		request.setAttribute(TYPE_ATT, request_type);
-		request.setAttribute(LANG_ATT, userContext._lang);
-		request.setAttribute(TO_ATT, to);
-		request.setAttribute(USER_ID_ATT, userContext._userID);
-		
-		if(userContext._groups != null)
+
+		Element userContextElem = owner.createElement("userContext");
+		request.appendChild(userContextElem);
+		userContextElem.setAttribute(LANG_ATT, userContext._lang);
+		userContextElem.setAttribute(USERNAME_ATT, userContext._username);
+		userContextElem.setAttribute(USER_ID_ATT, userContext._userID);
+
+		if (userContext._groups != null)
 		{
 			String groupString = "";
-			for(int i = 0; i < userContext._groups.length; i++)
+			for (int i = 0; i < userContext._groups.length; i++)
 			{
 				groupString += userContext._groups[i];
-				if(i != userContext._groups.length - 1)
+				if (i != userContext._groups.length - 1)
 				{
 					groupString += ",";
 				}
 			}
-			
-			if(groupString.length() > 0)
-			{
-				request.setAttribute(GROUPS_ATT, groupString);
-			}
-		}
+
+			if (groupString.length() > 0)
+			{
+				userContextElem.setAttribute(GROUPS_ATT, groupString);
+			}
+		}
+
 		return request;
 	}
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/UserContext.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/UserContext.java	(revision 27616)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/UserContext.java	(revision 27617)
@@ -2,8 +2,10 @@
 
 import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
 
 public class UserContext
 {
 	protected String _userID = null;
+	protected String _username = null;
 	protected String _lang = null;
 	protected String[] _groups = null;
@@ -15,14 +17,27 @@
 	public UserContext(Element xmlRequest)
 	{
-		_lang = xmlRequest.getAttribute(GSXML.LANG_ATT);
-		_userID = xmlRequest.getAttribute(GSXML.USER_ID_ATT);
-		_groups = xmlRequest.getAttribute(GSXML.GROUPS_ATT).split(",");
+		NodeList elems = xmlRequest.getElementsByTagName("userContext");
+
+		if (elems.getLength() > 0)
+		{
+			Element userContext = (Element) elems.item(0);
+			_userID = userContext.getAttribute(GSXML.USER_ID_ATT);
+			_username = userContext.getAttribute(GSXML.USERNAME_ATT);
+			_lang = userContext.getAttribute(GSXML.LANG_ATT);
+			_groups = userContext.getAttribute(GSXML.GROUPS_ATT).split(",");
+		}
 	}
 
-	public UserContext(String lang, String userID, String[] groups)
+	public UserContext(String lang, String username, String userID, String[] groups)
 	{
+		_userID = userID;
+		_username = username;
 		_lang = lang;
-		_userID = userID;
 		_groups = groups;
+	}
+
+	public void setUsername(String username)
+	{
+		_username = username;
 	}
 
@@ -60,4 +75,13 @@
 	}
 
+	public String getUsername()
+	{
+		if (_username != null)
+		{
+			return _username;
+		}
+		return "";
+	}
+
 	public String[] getGroups()
 	{
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XMLTransformer.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XMLTransformer.java	(revision 27616)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XMLTransformer.java	(revision 27617)
@@ -217,10 +217,10 @@
 	}
 
-	public Node transform(Document stylesheet, Document source, HashMap<String, Comparable> parameters)
+	public Node transform(Document stylesheet, Document source, HashMap<String, Object> parameters)
 	{
 		return transform(stylesheet, source, parameters, null, null);
 	}
 
-	public Node transform(Document stylesheet, Document source, HashMap<String, Comparable> parameters, Document docDocType)
+	public Node transform(Document stylesheet, Document source, HashMap<String, Object> parameters, Document docDocType)
 	{
 		return transform(stylesheet, source, parameters, docDocType, null);
@@ -229,5 +229,5 @@
 	// This method will now set the docType in the new document created and returned, if any are specified in the
 	// (merged) stylesheet being applied. The docDocType parameter is therefore no longer necessary nor used by default.
-	protected Node transform(Document stylesheet, Document source, HashMap<String, Comparable> parameters, Document docDocType, Document resultNode)
+	protected Node transform(Document stylesheet, Document source, HashMap<String, Object> parameters, Document docDocType, Document resultNode)
 	{
 		try
