Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/CollectionGroups.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/CollectionGroups.java	(revision 31180)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/CollectionGroups.java	(revision 31181)
@@ -2,4 +2,5 @@
 
 import java.io.File;
+
 import org.apache.log4j.Logger;
 import org.greenstone.gsdl3.util.GSFile;
@@ -11,4 +12,5 @@
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+
 import java.util.Set;
 
@@ -19,4 +21,5 @@
 
 import java.util.HashSet;
+import java.util.Iterator;
 
 public class CollectionGroups extends ServiceRack {
@@ -26,4 +29,5 @@
 
 	private static final String GROUP_CONTENT = "GroupCurrentContent";
+	private static final String UNIQUE_COLLECTIONS = "UniqueCollections";
 
 	static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.BerryBasket.class.getName());
@@ -35,5 +39,5 @@
 	}
 
-	String[] _services = { GROUP_CONTENT };
+	String[] _services = { GROUP_CONTENT, UNIQUE_COLLECTIONS };
 
 	public boolean configure(Element info, Element extra_info) {
@@ -60,7 +64,10 @@
 
 		Document doc = XMLConverter.newDOM();
-
 		UserContext userContext = new UserContext(request);
 
+	  // Prepare basic response
+		Element result = GSXML.createBasicResponse(doc, GSXML.SERVICE_TYPE_GROUPINFO);
+		
+		
 		// Get param list from request
 		Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
@@ -79,30 +86,15 @@
 		groupPath = groupPath.replaceAll("(^/+)|(/+$)", "");
 
-		// Get the message router info
-		Element mr_info_message = doc.createElement(GSXML.MESSAGE_ELEM);
-		Element mr_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", userContext);
-		mr_info_message.appendChild(mr_request);
-		Element mr_info_response_message = (Element) this.router.process(mr_info_message);
-		if (mr_info_response_message == null) {
-			logger.error(" couldn't query the message router!");
-			return null;
-		}
-		Element mr_info_response = (Element) GSXML.getChildByTagName(mr_info_response_message, GSXML.RESPONSE_ELEM);
-		if (mr_info_response == null) {
-			logger.error("couldn't query the message router!");
-			return null;
-		}
-
-		Element mr_collection_list = (Element) GSXML.getChildByTagName(mr_info_response,
-				GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
+		Element mrCollectionList = getMRCollectionList(userContext);
+		if (mrCollectionList == null){
+			result.appendChild(doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER));
+			return result;
+		}
 		//Get current groups and collections
 		Element groupContent = getCurrentContent(groupPath);
 	
 		//Get ungrouped collection list
-		Element ungroupedCollections = getUngroupedCollections(mr_collection_list);
-		
-		// Prepare basic response
-		Element result = GSXML.createBasicResponse(doc, GSXML.SERVICE_TYPE_GROUPINFO);
-
+		Element ungroupedCollections = getUngroupedCollections(mrCollectionList);
+		
 		// If groupContent is empty return empty collection list
 		if (groupContent == null) {
@@ -135,5 +127,5 @@
 					String collection_name = collection.getAttribute(GSXML.NAME_ATT);
 					// Check whether collection from current view exists in message router response
-					Element checkedCollection = GSXML.getNamedElement(mr_collection_list, GSXML.COLLECTION_ELEM,GSXML.NAME_ATT, collection_name);
+					Element checkedCollection = GSXML.getNamedElement(mrCollectionList, GSXML.COLLECTION_ELEM,GSXML.NAME_ATT, collection_name);
 					if (checkedCollection != null) {
 						//Set position value
@@ -184,4 +176,69 @@
 	}
 
+	protected Element processUniqueCollections(Element request) {
+		Document doc = XMLConverter.newDOM();
+		UserContext userContext = new UserContext(request);
+		// Prepare basic response
+		Element result = GSXML.createBasicResponse(doc, GSXML.SERVICE_TYPE_GROUPINFO);
+		Element resultCollections = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
+		result.appendChild(resultCollections);
+		Element mrCollectionList = getMRCollectionList(userContext);
+		//Collections from message router check
+		if (mrCollectionList == null){
+			logger.error("mrCollectionList is null!");
+			return result;
+		}
+		//paramList check
+		Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
+		if (paramList == null) {
+			logger.error("UniqueCollections request had no paramList.");
+			return result;
+		}
+		//Add collections from request
+		Set<String> uniq_colls = new HashSet<String>();
+		Element collParam = GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GSXML.COLLECTION_ELEM);
+		if (collParam != null){
+			String colls = GSXML.getValue(collParam);
+			if (!colls.isEmpty())
+			{
+				String[] _colls = colls.split(",");
+				for (int i=0;i < _colls.length;i++){
+					uniq_colls.add(_colls[i]);
+				}
+			}
+		}
+		//groupParam check
+		Element groupParam = GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GSXML.GROUP_ELEM);
+		if (groupParam == null) {
+			logger.error("UniqueCollections request had no groupParam.");
+			return result;
+		}
+		//Add collections from groups
+		String[] groups = null;
+		groups = GSXML.getValue(groupParam).split(",");
+		for (int i = 0; i < groups.length; i++) {
+			Element groupContent = getCurrentContent(groups[i]);
+			//If group exists
+			if (groupContent != null) {
+				NodeList collectionNodes = GSXML.getChildrenByTagName(groupContent, GSXML.COLLECTION_ELEM);
+				for (int j = 0; j < collectionNodes.getLength(); j++) {
+					String collName = ((Element) collectionNodes.item(j)).getAttribute(GSXML.NAME_ATT);
+					uniq_colls.add(collName);
+				}
+			}
+	
+		}
+		//Fill result collectionList 
+		for (Iterator<String> iterator = uniq_colls.iterator(); iterator.hasNext();) {
+			String collectionName = (String) iterator.next();
+			Element checkedCollection = GSXML.getNamedElement(mrCollectionList, GSXML.COLLECTION_ELEM,GSXML.NAME_ATT, collectionName);
+			if (checkedCollection != null){
+				resultCollections.appendChild(doc.importNode(checkedCollection, true));
+			}
+		}
+		return result;
+
+	}
+	
 	private Element getCurrentContent(String path) {
 
@@ -195,4 +252,8 @@
 			 path = "";
 		}
+		
+		path = path.replaceAll("(/+)", "/");
+		path = path.replaceAll("(^/+)|(/+$)", "");
+		
 		String[] pathSteps = path.split("/");
 
@@ -203,4 +264,7 @@
 			if (!pathSteps[i].isEmpty()) {
 				currentView = GSXML.getNamedElement(currentView, GSXML.GROUP_ELEM, GSXML.NAME_ATT, pathSteps[i]);
+				if (currentView == null){
+					break;
+				}
 			}
 		}
@@ -330,4 +394,24 @@
 		return pathInfo;
 	}
-
+	private Element getMRCollectionList(UserContext userContext){
+		Document doc = XMLConverter.newDOM();
+		// Get the message router info
+		Element mr_info_message = doc.createElement(GSXML.MESSAGE_ELEM);
+		Element mr_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", userContext);
+		mr_info_message.appendChild(mr_request);
+		Element mr_info_response_message = (Element) this.router.process(mr_info_message);
+		if (mr_info_response_message == null) {
+			logger.error(" couldn't query the message router!");
+			return null;
+		}
+		Element mr_info_response = (Element) GSXML.getChildByTagName(mr_info_response_message, GSXML.RESPONSE_ELEM);
+		if (mr_info_response == null) {
+			logger.error("Message router response is null!");
+			return null;
+		}
+		
+		Element mr_collection_list = (Element) GSXML.getChildByTagName(mr_info_response, GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
+		
+		return mr_collection_list;
+	}
 }
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/CrossCollectionSearch.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/CrossCollectionSearch.java	(revision 31180)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/CrossCollectionSearch.java	(revision 31181)
@@ -48,4 +48,5 @@
 	protected static final String QUERY_PARAM = "query";
 	protected static final String COLLECTION_PARAM = "collection";
+	protected static final String GROUP_PARAM = "group";
   protected static final String MAXDOCS_PARAM = "maxDocs"; // matches standard maxDocs, but in this case, means max docs per collection
   protected static final String HITS_PER_PAGE_PARAM = "hitsPerPage";
@@ -172,5 +173,4 @@
 			return result; // Return the empty result
 		}
-
 		// get the collection list
 		String[] colls_list = coll_ids_list_no_all;
@@ -184,4 +184,6 @@
 			}
 		}
+			
+		colls_list = mergeGroups(userContext, param_list, colls_list);
 		
 		String maxdocs = MAXDOCS_DEFAULT;
@@ -266,4 +268,7 @@
 
 	//     }
+	
+	
+	
 	protected boolean initCollectionList(String lang)
 	{
@@ -489,3 +494,72 @@
 		return result;
 	}
+	
+	private String[] mergeGroups(UserContext userContext, Element paramList, String[] collArray){
+		Document doc = XMLConverter.newDOM();
+		Element groupParam = GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GROUP_PARAM);
+		Element collParam = GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, COLLECTION_PARAM);
+		//Group param not null and coll param null or not 'all'
+		if (groupParam != null && (collParam == null || !GSXML.getValue(collParam).equals("all")))
+		{	
+			//GroupInfo service to get uniq collections
+			String uniqCollServiceName = "UniqueCollections";
+			Element infoResponse = getMRInfo(userContext);
+			Element serviceList = (Element) GSXML.getChildByTagName(infoResponse, GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER);
+			if (serviceList == null) { 
+				logger.error("Service list is null!");
+				return collArray;
+			}
+			Element groupInfoService = GSXML.getNamedElement(serviceList, GSXML.SERVICE_ELEM, GSXML.NAME_ATT,	uniqCollServiceName);
+			if (groupInfoService == null){
+				logger.error("UniqueCollections service unavailable; Check your groupConfig.xml");
+				return collArray;
+			}
+			Element groupQueryMessage = doc.createElement(GSXML.MESSAGE_ELEM);
+			Element groupQueryRequest = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_PROCESS, uniqCollServiceName, userContext);
+			groupQueryMessage.appendChild(groupQueryRequest);
+			Element groupParamList = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
+			groupQueryRequest.appendChild(groupParamList);
+			if (collParam != null){
+				groupParamList.appendChild(doc.importNode(GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GSXML.COLLECTION_ELEM), true));	
+			}
+			groupParamList.appendChild(doc.importNode(GSXML.getNamedElement(paramList, GSXML.PARAM_ELEM, GSXML.NAME_ATT, GSXML.GROUP_ELEM), true));
+			Element groupQueryResult = (Element) this.router.process(groupQueryMessage);
+			Element groupQueryResonse = (Element) GSXML.getChildByTagName(groupQueryResult, GSXML.RESPONSE_ELEM);
+			Element collList = (Element) GSXML.getChildByTagName(groupQueryResonse, GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
+			NodeList collections = GSXML.getChildrenByTagName(collList, GSXML.COLLECTION_ELEM);
+			collArray = new String[collections.getLength()];
+			for (int i = 0; i < collections.getLength(); i++){
+				String collName = ((Element) collections.item(i)).getAttribute(GSXML.NAME_ATT);
+				collArray[i] = collName;
+			}
+			return collArray;
+		}
+		return collArray;
+		
+	}
+	private Element getMRInfo(UserContext userContext){
+		Document doc = XMLConverter.newDOM();
+		Element infoMessage = doc.createElement(GSXML.MESSAGE_ELEM);
+		Element infoRequest = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", userContext);
+		Element paramList = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
+		infoRequest.appendChild(paramList);
+		GSXML.addParameterToList(paramList, GSXML.SUBSET_PARAM, GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER);
+		infoMessage.appendChild(infoRequest);
+		Element responseMessage = (Element) this.router.process(infoMessage);
+		if (responseMessage == null)
+		{
+			logger.error("couldn't query the message router!");
+			return null;
+		}
+		Element infoResponse = (Element) GSXML.getChildByTagName(responseMessage, GSXML.RESPONSE_ELEM);
+		if (infoResponse == null)
+		{
+			logger.error("response from message router is null!");
+			return null;
+		}
+		
+		return infoResponse;
+		
+	}
+	
 }
