Index: src/edu/ucsb/nceas/metacat/MetacatResultSet.java
===================================================================
--- src/edu/ucsb/nceas/metacat/MetacatResultSet.java	(revision 3245)
+++ src/edu/ucsb/nceas/metacat/MetacatResultSet.java	(nonexistent)
@@ -1,358 +0,0 @@
-/**
- *  '$RCSfile$'
- *  Copyright: 2007 Regents of the University of California and the
- *             National Center for Ecological Analysis and Synthesis
- *    Authors: Chad Berkley
- *
- *   '$Author$'
- *     '$Date$'
- * '$Revision$'
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-package edu.ucsb.nceas.metacat;
-
-import java.io.*;
-import java.util.*;
-
-import org.w3c.dom.*;
-import org.apache.xpath.*;
-
-import org.apache.log4j.Logger;
-
-import org.apache.log4j.Logger;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.ext.DeclHandler;
-import org.xml.sax.ext.LexicalHandler;
-import org.xml.sax.helpers.DefaultHandler;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-
-/**
- * this class implements a metacat resultset and can be serialized to xml
- * for printing to the servlet output stream.
- */
-public class MetacatResultSet extends DefaultHandler
-{    
-  private Logger log = Logger.getLogger(MetacatResultSet.class);
-  private Vector results = new Vector();
-  private Result currentResult = null;
-  private String currentElementName = "";
-  Attributes atts = null;
-  
-  /**
-   * constructor that can process a dom.  WARNING: this is very slow.
-   */
-  public MetacatResultSet(Document d)
-    throws Exception
-  {
-    log.warn("#####################processing resultset...");
-    NodeList nl = XPathAPI.selectNodeList(d, "//document");
-    for(int i=0; i<nl.getLength(); i++)
-    { //get each of the document nodes
-      Node docNode = nl.item(i);
-      Node docidNode = XPathAPI.selectSingleNode(docNode, "./docid");
-      log.warn("processing " + docidNode.getFirstChild().getNodeValue());
-      Node docnameNode = XPathAPI.selectSingleNode(docNode, "./docname");
-      Node doctypeNode = XPathAPI.selectSingleNode(docNode, "./doctype");
-      Node createdateNode = XPathAPI.selectSingleNode(docNode, "./createdate");
-      Node updatedateNode = XPathAPI.selectSingleNode(docNode, "./updatedate");
-      //process the returnfields
-      NodeList returnfieldNL = XPathAPI.selectNodeList(docNode, "./param");
-      Hashtable returnfieldHash = new Hashtable();
-      for(int j=0; j<returnfieldNL.getLength(); j++)
-      {
-        Node returnfieldNode = returnfieldNL.item(j);
-        Node nameNode = XPathAPI.selectSingleNode(returnfieldNode, "@name");
-        String value = returnfieldNode.getFirstChild().getNodeValue();
-        String name = nameNode.getNodeValue();
-        returnfieldHash.put(name, value);
-      }
-      
-      Result r = new Result(docidNode.getFirstChild().getNodeValue(),
-                            docnameNode.getFirstChild().getNodeValue(),
-                            doctypeNode.getFirstChild().getNodeValue(),
-                            createdateNode.getFirstChild().getNodeValue(),
-                            updatedateNode.getFirstChild().getNodeValue(),
-                            returnfieldHash);
-      addResult(r);
-    }
-  }
-  
-  /**
-   * process a resultset using SAX
-   */
-  public MetacatResultSet(String xmlDoc)
-    throws SAXException, IOException
-  {
-    double mrsStart = System.currentTimeMillis() / 1000;
-    log.warn("###############parsing for paged results.....");
-    XMLReader parser = null;
-    String parserName = MetaCatUtil.getOption("saxparser");
-    parser = XMLReaderFactory.createXMLReader(parserName);
-    parser.setContentHandler(this);
-    parser.setErrorHandler(this);
-    parser.parse(new InputSource(new StringReader(xmlDoc)));
-    double mrsStop = System.currentTimeMillis() / 1000;
-    log.warn("##############done parsing for paged results.  total time: " + 
-      (mrsStop - mrsStart) + " seconds");
-    
-  }
-  
-  /**
-   * process the beginning of an element
-   */
-  public void startElement(String uri, String localName, String qName, 
-    Attributes atts) throws SAXException
-  {
-    //get the attributes
-    this.atts = atts;
-    if(localName.equals("document"))
-    {
-      currentResult = new Result();
-    }
-    else if(localName.equals("docid") ||
-            localName.equals("docname") ||
-            localName.equals("doctype") ||
-            localName.equals("createdate") ||
-            localName.equals("updatedate") ||
-            localName.equals("param"))
-    { //set the current element name
-      currentElementName = localName;
-    }
-  }
-  
-  /**
-   * process the end of an element
-   */
-  public void endElement(String uri, String localName, String qName)
-    throws SAXException
-  {
-    if(localName.equals("document"))
-    { //if we're closing a document, save the result
-      addResult(new Result(currentResult));
-      currentResult = new Result();
-      currentElementName = "";
-    }
-  }
-  
-  /**
-   * process character data
-   */
-  public void characters(char[] cbuf, int start, int len) 
-    throws SAXException
-  { //get the character data for each node we care about
-    String s = new String(cbuf, start, len);
-    if(currentElementName.equals("docid"))
-    {
-      currentResult.docid = s;
-    }
-    else if(currentElementName.equals("docname"))
-    {
-      currentResult.docname = s;
-    }
-    else if(currentElementName.equals("doctype"))
-    {
-      currentResult.doctype = s;
-    }
-    else if(currentElementName.equals("createdate"))
-    {
-      currentResult.createDate = s;
-    }
-    else if(currentElementName.equals("updatedate"))
-    {
-      currentResult.updateDate = s;
-    }
-    else if(currentElementName.equals("param"))
-    { //add the returnfields to the hashtable
-      for (int i = 0; i < atts.getLength(); i++)
-      {
-        String attributeName = atts.getQName(i);
-        String attributeValue = null;
-        if(attributeName.equals("name"))
-        {
-          attributeValue = atts.getValue(i);
-        }
-        currentResult.returnfields.put(attributeValue, s);
-      }
-    }
-  }
-  
-  /**
-   * SAX Handler that receives notification of fatal parsing errors
-   */
-  public void fatalError(SAXParseException exception) throws SAXException
-  {
-      log.fatal("FATALERROR while parsing/caching resultset: " + 
-        exception.getMessage());
-      throw (new SAXException("Fatal error processing/caching resultset.", 
-        exception));
-  }
-
-  /**
-   * SAX Handler that receives notification of recoverable parsing errors
-   */
-  public void error(SAXParseException exception) throws SAXException
-  {
-      log.error("ERROR while parsing/caching resultset: " + 
-        exception.getMessage());
-      throw (new SAXException("Error in processing/caching resultset.", 
-        exception));
-  }
-
-  /**
-   * SAX Handler that receives notification of warnings
-   */
-  public void warning(SAXParseException exception) throws SAXException
-  {
-      log.warn("WARNING while parsing/caching resultset: " + 
-        exception.getMessage());
-      throw (new SAXException("Warning.", exception));
-  }
-  
-  /**
-   * add a new result to the resultSet
-   */
-  public void addResult(Result r)
-  {
-    results.addElement(r);
-  }
-  
-  /**
-   * returns a vector of the results
-   */
-  public Vector getResults()
-  {
-    return results;
-  }
-  
-  /**
-   * serialize a selection of the results.  This will print the results from
-   * start to end-1.  if end is 0, nothing will be printed.
-   */
-  public String serializeToXML(int start, int end)
-  {
-    StringBuffer sb = new StringBuffer();
-    if(start > results.size() || end > results.size())
-    { //make sure we don't go over the edge of the vector
-      start = results.size() - 10;
-      end = results.size();
-    }
-    
-    for(int i=start; i<end; i++)
-    {
-      Result r = (Result)results.elementAt(i);
-      sb.append(r.toString());
-      sb.append("\n");
-    }
-    return sb.toString();
-  }
-  
-  /**
-   * returns an xml representation of this object
-   */
-  public String toString()
-  {
-    StringBuffer sb = new StringBuffer();
-    for(int i=0; i<results.size(); i++)
-    {
-      Result r = (Result)results.elementAt(i);
-      sb.append(r.toString());
-      sb.append("\n");
-    }
-    return sb.toString();
-  }
-  
-  
-  /**
-   * a class to store one result
-   */
-  public class Result
-  {
-    protected String docid;
-    protected String docname;
-    protected String doctype;
-    protected String createDate;
-    protected String updateDate;
-    protected Hashtable returnfields;
-    
-    /**
-     * copy constructor
-     */
-    public Result(Result r)
-    {
-      if(r != null)
-      {
-        docid = r.docid;
-        docname = r.docname;
-        doctype = r.doctype;
-        createDate = r.createDate;
-        updateDate = r.updateDate;
-        returnfields = r.returnfields;
-      }
-    }
-    
-    /**
-     * constructor
-     */
-    public Result(String docid, String docname, String doctype, 
-      String createDate, String updateDate, Hashtable returnfields)
-    {
-      this.docid = docid;
-      this.doctype = doctype;
-      this.createDate = createDate;
-      this.updateDate = updateDate;
-      this.returnfields = returnfields;
-    }
-    
-    /**
-     * default constructor
-     */
-    public Result()
-    {
-      returnfields = new Hashtable();
-    }
-    
-    /**
-     * returns serialized version of this result
-     */
-    public String toString()
-    {
-      StringBuffer sb = new StringBuffer();
-      sb.append("<document>\n");
-      sb.append("  <docid>" + docid + "</docid>\n");
-      sb.append("  <docname>" + docname + "</docname>\n");
-      sb.append("  <doctype>" + doctype + "</doctype>\n");
-      sb.append("  <createdate>" + createDate + "</createdate>\n");
-      sb.append("  <updatedate>" + updateDate + "</updatedate>\n");
-      
-      Enumeration keys = returnfields.keys();
-      while(keys.hasMoreElements())
-      {
-        String key = (String)keys.nextElement();
-        String value = (String)returnfields.get(key);
-        sb.append("  <param name=\"" + key + "\">" + value + "</param>\n");
-      }
-      sb.append("</document>");
-      return sb.toString();
-    }
-  }
-}

Property changes on: src/edu/ucsb/nceas/metacat/MetacatResultSet.java
___________________________________________________________________
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Deleted: svn:executable
## -1 +0,0 ##
-*
\ No newline at end of property
Deleted: svn:keywords
## -1 +0,0 ##
-Author Date Id Revision
\ No newline at end of property
Index: src/edu/ucsb/nceas/metacat/QuerySpecification.java
===================================================================
--- src/edu/ucsb/nceas/metacat/QuerySpecification.java	(revision 3245)
+++ src/edu/ucsb/nceas/metacat/QuerySpecification.java	(revision 3246)
@@ -376,7 +376,7 @@
         	accessQuery = " AND (docid IN (" + allow + ")"
                 + " AND docid NOT IN (" + deny + "))";
         }
-        logMetacat.warn("accessquery is: " + accessQuery);
+        logMetacat.info("accessquery is: " + accessQuery);
         return accessQuery;
     }
 
@@ -1191,7 +1191,7 @@
                 self.append(" AND xml_nodes.rootnodeid = xml_documents.rootnodeid");
             }
 
-            logMetacat.warn("Attribute query: " + self.toString());
+            logMetacat.info("Attribute query: " + self.toString());
 
             return self.toString();
         }
Index: src/edu/ucsb/nceas/metacat/DBQuery.java
===================================================================
--- src/edu/ucsb/nceas/metacat/DBQuery.java	(revision 3245)
+++ src/edu/ucsb/nceas/metacat/DBQuery.java	(revision 3246)
@@ -30,27 +30,12 @@
 
 package edu.ucsb.nceas.metacat;
 
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintWriter;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.OutputStream;
+import java.io.*;
+import java.util.zip.*;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.StringTokenizer;
-import java.util.Vector;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
+import java.util.*;
 
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletResponse;
@@ -282,10 +267,10 @@
       // get query and qformat
       String xmlquery = ((String[])params.get("query"))[0];
 
-      logMetacat.warn("SESSIONID: " + sessionid);
-      logMetacat.warn("xmlquery: " + xmlquery);
+      logMetacat.info("SESSIONID: " + sessionid);
+      logMetacat.info("xmlquery: " + xmlquery);
       String qformat = ((String[])params.get("qformat"))[0];
-      logMetacat.warn("qformat: " + qformat);
+      logMetacat.info("qformat: " + qformat);
       // Get the XML query and covert it into a SQL statment
       QuerySpecification qspec = null;
       if ( xmlquery != null)
@@ -350,24 +335,7 @@
       }//else
 
   }
-    
-  /**
-   * this method parses the xml results in the string buffer and returns
-   * just those required by the paging params.
-   */
-  private StringBuffer getPagedResult(MetacatResultSet mrs, int pagestart, 
-    int pagesize)
-  {
-    //logMetacat.warn(mrs.toString());
-    if(pagesize == 0)
-    { //if pagesize is 0 then we return the whole resultset
-      return new StringBuffer(mrs.toString());
-    }
-    
-    return new StringBuffer(mrs.serializeToXML(pagestart, pagestart + pagesize));
-  }
   
-  
   /**
    * Transforms a hashtable of documents to an xml or html result and sent
    * the content to outputstream. Keep going untill hastable is empty. stop it.
@@ -418,7 +386,7 @@
     	cachedQuerySpec = (QuerySpecification)sess.getAttribute("query");
     }
     
-    if(cachedQuerySpec != null && 
+    /*if(cachedQuerySpec != null && 
        cachedQuerySpec.printSQL(false).equals(qspec.printSQL(false)))
     { //use the cached resultset if the query was the same as the last
       MetacatResultSet mrs = (MetacatResultSet)sess.getAttribute("results");
@@ -444,7 +412,7 @@
         returnString += "\n</resultset>\n";
         return new StringBuffer(returnString);
       }
-    }
+    }*/
     
     //no cached results...go on with a normal query
     
@@ -500,7 +468,7 @@
       out.println(closeRestultset);
     }
 
-    try
+    /*try
     {
       //cache the query result and the query
       logMetacat.warn("#################Caching query and resultset");
@@ -514,12 +482,13 @@
       returnString += pagedResultBuffer.toString();
       returnString += "\n</resultset>\n";
       return new StringBuffer(returnString);
+      
     }
     catch(Exception e)
     {
       logMetacat.error("Could not parse resultset: " + e.getMessage());
       //e.printStackTrace();
-    }
+    }*/
     
     //default to returning the whole resultset
     return resultset;
@@ -539,7 +508,7 @@
       String query = null;
       int count = 0;
       int index = 0;
-      Hashtable docListResult = new Hashtable();
+      ResultDocumentSet docListResult = new ResultDocumentSet();
       PreparedStatement pstmt = null;
       String docid = null;
       String docname = null;
@@ -588,7 +557,6 @@
           queryBuffer.append( "'') " );
           query = queryBuffer.toString();
       } 
-
       String ownerQuery = getOwnerQuery(user);
       logMetacat.info("\n\n\n query: " + query);
       logMetacat.info("\n\n\n owner query: "+ownerQuery);
@@ -606,32 +574,59 @@
         } else {
             query = query + accessQuery.substring(4, accessQuery.length());
         }
-        logMetacat.warn("\n\n\n final query: " + query);
+        logMetacat.info("\n\n\n final query: " + query);
       }
 
       startTime = System.currentTimeMillis() / 1000;
       pstmt = dbconn.prepareStatement(query);
       rs = pstmt.executeQuery();
-      //now we need to process the resultset based on pagesize and pagestart
-      //if they are not 0
+
       double queryExecuteTime = System.currentTimeMillis() / 1000;
       logMetacat.warn("Time to execute query: "
                     + (queryExecuteTime - startTime));
-      boolean tableHasRows = rs.next();
+
+      boolean tableHasRows;
+      
+      //if(pagestart == 0)
+      //{ //if we're on page 0 then move to the first record
+        tableHasRows = rs.next();
+      //}
+      
+      /*for(int z=0; z<pagesize * pagestart; z++)
+      { //move to the start page
+        logMetacat.warn("############moving to: " + z);
+        tableHasRows = rs.next();
+        if(!tableHasRows)
+        {
+          break;
+        }
+      }*/
+      
+      if(pagesize == 0)
+      { //this makes sure we get all results if there is no paging
+        pagesize = 99999;
+        pagestart = 99999;
+      } 
+      
+      int currentIndex = 0;
       while (tableHasRows)
+      //for(int z=pagestart * pagesize; z<(pagesize * pagestart) + pagesize;)
       {
+        logMetacat.warn("############getting result: " + currentIndex);
         docid = rs.getString(1).trim();
+        logMetacat.warn("############processing: " + docid);
         docname = rs.getString(2);
         doctype = rs.getString(3);
+        logMetacat.warn("############processing: " + doctype);
         createDate = rs.getString(4);
         updateDate = rs.getString(5);
         rev = rs.getInt(6);
-
+        
         // if there are returndocs to match, backtracking can be performed
         // otherwise, just return the document that was hit
         Vector returndocVec = qspec.getReturnDocList();
-         if (returndocVec.size() != 0 && !returndocVec.contains(doctype)
-                        && !qspec.isPercentageSearch())
+        if (returndocVec.size() != 0 && !returndocVec.contains(doctype)
+             && !qspec.isPercentageSearch())
          {
            logMetacat.warn("Back tracing now...");
            String sep = MetaCatUtil.getOption("accNumSeparator");
@@ -726,10 +721,12 @@
                   document.append("<updatedate>" + updateDate+ "</updatedate>");
                 }
                 // Store the document id and the root node id
-                docListResult.put(docid, (String) document.toString());
+                docListResult.addResultDocument(
+                  new ResultDocument(docid, (String) document.toString()));
+                currentIndex++;
+                logMetacat.warn("$$$$$$$real result: " + docid);
                 count++;
 
-
                 // Get the next package document linked to our hit
                 hasBtRows = btrs.next();
               }//while
@@ -738,7 +735,7 @@
         }
         else if (returndocVec.size() == 0 || returndocVec.contains(doctype))
         {
-
+          logMetacat.warn("NOT Back tracing now...");
            document = new StringBuffer();
 
            String completeDocid = docid
@@ -762,29 +759,79 @@
              document.append("<updatedate>" + updateDate + "</updatedate>");
            }
            // Store the document id and the root node id
-           docListResult.put(docid, (String) document.toString());
+           
+           docListResult.addResultDocument(
+             new ResultDocument(docid, (String) document.toString()));
+           logMetacat.warn("$$$$$$$real result: " + docid);
+           currentIndex++;
            count++;
-
         }//else
+        
         // when doclist reached the offset number, send out doc list and empty
         // the hash table
-        if (count == offset)
-        {
+        if (count == offset && pagesize == 0)
+        { //if pagesize is not 0, do this later.
           //reset count
+          logMetacat.warn("############doing subset cache");
           count = 0;
-          handleSubsetResult(qspec,resultsetBuffer, out, docListResult,
+          handleSubsetResult(qspec, resultsetBuffer, out, docListResult,
                               user, groups,dbconn, useXMLIndex);
-          // reset docListResult
-          docListResult = new Hashtable();
-
+          //reset docListResult
+          docListResult = new ResultDocumentSet();
         }
+       
+        logMetacat.warn("currentIndex: " + currentIndex);
+       if(currentIndex >= ((pagesize * pagestart) + pagesize))
+       {
+         logMetacat.warn("docListResult: " + docListResult.toString());
+         ResultDocumentSet pagedResultsHash = new ResultDocumentSet();
+         for(int i=pagesize*pagestart; i<docListResult.size(); i++)
+         {
+           pagedResultsHash.put(docListResult.get(i));
+         }
+         
+         docListResult = pagedResultsHash;
+         break;
+       }
        // Advance to the next record in the cursor
        tableHasRows = rs.next();
+       if(!tableHasRows)
+       {
+         break;
+       }
      }//while
+     
+     //subset the docListResult by pages
+     /*Hashtable pagedResultsHash = new Hashtable();
+     Enumeration keys = docListResult.keys();
+     if(pagesize != 0)
+     {
+       for(int z=0; z<pagesize * pagestart; z++)
+       { //move to the start page
+         logMetacat.warn("############moving to: " + z);
+         keys.nextElement();
+       }
+     
+       for(int z=pagestart * pagesize; z<(pagesize * pagestart) + pagesize; z++)
+       {
+         try
+         {
+           logMetacat.warn("############hashing result: " + z);
+           String key = (String)keys.nextElement();
+           pagedResultsHash.put(key, docListResult.get(key));
+         }
+         catch(java.util.NoSuchElementException nsee)
+         {
+           break;
+         }
+       }
+       docListResult = pagedResultsHash;
+     }*/
+     
      rs.close();
      pstmt.close();
      //if docListResult is not empty, it need to be sent.
-     if (!docListResult.isEmpty())
+     if (docListResult.size() != 0)
      {
        handleSubsetResult(qspec,resultsetBuffer, out, docListResult,
                               user, groups,dbconn, useXMLIndex);
@@ -803,12 +850,12 @@
      */
     private StringBuffer handleSubsetResult(QuerySpecification qspec,
                                            StringBuffer resultset,
-                                           PrintWriter out, Hashtable partOfDoclist,
+                                           PrintWriter out, ResultDocumentSet partOfDoclist,
                                            String user, String[]groups,
                                        DBConnection dbconn, boolean useXMLIndex)
                                        throws Exception
    {
-
+     
      // check if there is a record in xml_returnfield
      // and get the returnfield_id and usage count
      int usage_count = getXmlReturnfieldsTableId(qspec, dbconn);
@@ -842,15 +889,15 @@
      // remove the keys in queryresultDocList from partOfDoclist
      Enumeration _keys = queryresultDocList.keys();
      while (_keys.hasMoreElements()){
-         partOfDoclist.remove(_keys.nextElement());
+         partOfDoclist.remove((String)_keys.nextElement());
      }
 
      // backup the keys-elements in partOfDoclist to check later
      // if the doc entry is indexed yet
      Hashtable partOfDoclistBackup = new Hashtable();
-     _keys = partOfDoclist.keys();
-     while (_keys.hasMoreElements()){
-       Object key = _keys.nextElement();
+     Iterator itt = partOfDoclist.getDocids();
+     while (itt.hasNext()){
+       Object key = itt.next();
          partOfDoclistBackup.put(key, partOfDoclist.get(key));
      }
 
@@ -860,12 +907,12 @@
 
      //add return fields for the documents in partOfDoclist
      partOfDoclist = addReturnfield(partOfDoclist, qspec, user, groups,
-                                        dbconn, useXMLIndex );
+                                        dbconn, useXMLIndex);
      //add relationship part part docid list for the documents in partOfDocList
      partOfDoclist = addRelationship(partOfDoclist, qspec, dbconn, useXMLIndex);
 
 
-     Enumeration keys = partOfDoclist.keys();
+     Iterator keys = partOfDoclist.getDocids();
      String key = null;
      String element = null;
      String query = null;
@@ -872,9 +919,9 @@
      int offset = (new Integer(MetaCatUtil
                                .getOption("queryresult_string_length")))
                                .intValue();
-     while (keys.hasMoreElements())
+     while (keys.hasNext())
      {
-         key = (String) keys.nextElement();
+         key = (String) keys.next();
          element = (String)partOfDoclist.get(key);
 
 	 // check if the enterRecords is true, elements is not null, element's
@@ -909,10 +956,10 @@
      }//while
 
 
-     keys = queryresultDocList.keys();
-     while (keys.hasMoreElements())
+     Enumeration keysE = queryresultDocList.keys();
+     while (keysE.hasMoreElements())
      {
-         key = (String) keys.nextElement();
+         key = (String) keysE.nextElement();
          element = (String)queryresultDocList.get(key);
          // A string with element
          String xmlElement = "  <document>" + element + "</document>";
@@ -932,7 +979,7 @@
     * queryresultstring as a hashtable
     */
    private Hashtable docidsInQueryresultTable(int returnfield_id,
-                                              Hashtable partOfDoclist,
+                                              ResultDocumentSet partOfDoclist,
                                               DBConnection dbconn){
 
          Hashtable returnValue = new Hashtable();
@@ -940,12 +987,12 @@
          ResultSet rs = null;
 
          // get partOfDoclist as string for the query
-         Enumeration keylist = partOfDoclist.keys();
+         Iterator keylist = partOfDoclist.getDocids();
          StringBuffer doclist = new StringBuffer();
-         while (keylist.hasMoreElements())
+         while (keylist.hasNext())
          {
              doclist.append("'");
-             doclist.append((String) keylist.nextElement());
+             doclist.append((String) keylist.next());
              doclist.append("',");
          }//while
 
@@ -1088,7 +1135,7 @@
     /*
      * A method to add return field to return doclist hash table
      */
-    private Hashtable addReturnfield(Hashtable docListResult,
+    private ResultDocumentSet addReturnfield(ResultDocumentSet docListResult,
                                       QuerySpecification qspec,
                                       String user, String[]groups,
                                       DBConnection dbconn, boolean useXMLIndex )
@@ -1107,14 +1154,14 @@
         qspec.setGroup(groups);
         Vector extendedFields = new Vector(qspec.getReturnFieldList());
         Vector results = new Vector();
-        Enumeration keylist = docListResult.keys();
+        Iterator keylist = docListResult.getDocids();
         StringBuffer doclist = new StringBuffer();
         Vector parentidList = new Vector();
         Hashtable returnFieldValue = new Hashtable();
-        while (keylist.hasMoreElements())
+        while (keylist.hasNext())
         {
           doclist.append("'");
-          doclist.append((String) keylist.nextElement());
+          doclist.append((String) keylist.next());
           doclist.append("',");
         }
         if (doclist.length() > 0)
@@ -1145,7 +1192,7 @@
 
            String extendedQuery =
                qspec.printExtendedSQL(doclist.toString(), controlPairs, useXMLIndex);
-           logMetacat.warn("Extended query: " + extendedQuery);
+           logMetacat.info("Extended query: " + extendedQuery);
 
            if(extendedQuery != null){
                pstmt = dbconn.prepareStatement(extendedQuery);
@@ -1215,15 +1262,16 @@
                    ReturnFieldValue object =
                        (ReturnFieldValue) xmlFieldValue.nextElement();
                    docid = object.getDocid();
-                   if (docListResult.containsKey(docid)) {
+                   if (docListResult.containsDocid(docid)) {
                        String removedelement = (String) docListResult.
                            remove(docid);
                        docListResult.
-                           put(docid,
-                               removedelement + object.getXMLFieldValue());
+                           addResultDocument(new ResultDocument(docid,
+                               removedelement + object.getXMLFieldValue()));
                    }
                    else {
-                       docListResult.put(docid, object.getXMLFieldValue());
+                       docListResult.addResultDocument(
+                         new ResultDocument(docid, object.getXMLFieldValue()));
                    }
                } //while
                double docListResultEnd = System.currentTimeMillis() / 1000;
@@ -1246,7 +1294,7 @@
     /*
     * A method to add relationship to return doclist hash table
     */
-   private Hashtable addRelationship(Hashtable docListResult,
+   private ResultDocumentSet addRelationship(ResultDocumentSet docListResult,
                                      QuerySpecification qspec,
                                      DBConnection dbconn, boolean useXMLIndex )
                                      throws Exception
@@ -1255,13 +1303,13 @@
     ResultSet rs = null;
     StringBuffer document = null;
     double startRelation = System.currentTimeMillis() / 1000;
-    Enumeration docidkeys = docListResult.keys();
-    while (docidkeys.hasMoreElements())
+    Iterator docidkeys = docListResult.getDocids();
+    while (docidkeys.hasNext())
     {
       //String connstring =
       // "metacat://"+util.getOption("server")+"?docid=";
       String connstring = "%docid=";
-      String docidkey = (String) docidkeys.nextElement();
+      String docidkey = (String) docidkeys.next();
       pstmt = dbconn.prepareStatement(QuerySpecification
                       .printRelationSQL(docidkey));
       pstmt.execute();
@@ -1408,8 +1456,8 @@
      * A method to return search result after running a query which return
      * field have attribue
      */
-    private Hashtable getAttributeValueForReturn(QuerySpecification squery,
-            Hashtable docInformationList, String docList, boolean useXMLIndex)
+    private ResultDocumentSet getAttributeValueForReturn(QuerySpecification squery,
+            ResultDocumentSet docInformationList, String docList, boolean useXMLIndex)
     {
         StringBuffer XML = null;
         String sql = null;
@@ -1450,7 +1498,7 @@
                     XML.append("</param>");
                     tableHasRows = rs.next();
 
-                    if (docInformationList.containsKey(docid)) {
+                    if (docInformationList.containsDocid(docid)) {
                         String removedelement = (String) docInformationList
                                 .remove(docid);
                         docInformationList.put(docid, removedelement
@@ -2476,4 +2524,169 @@
         }
 
     }
+    
+    /**
+     * a class to store one result document consisting of a docid and a document
+     */
+    private class ResultDocument
+    {
+      public String docid;
+      public String document;
+      
+      public ResultDocument(String docid, String document)
+      {
+        this.docid = docid;
+        this.document = document;
+      }
+    }
+    
+    /**
+     * a private class to handle a set of resultDocuments
+     */
+    private class ResultDocumentSet
+    {
+      private Vector docids;
+      private Vector documents;
+      
+      public ResultDocumentSet()
+      {
+        docids = new Vector();
+        documents = new Vector();
+      }
+      
+      /**
+       * adds a result document to the set
+       */
+      public void addResultDocument(ResultDocument rd)
+      {
+        if(rd.docid == null)
+          rd.docid = "";
+        if(rd.document == null)
+          rd.document = "";
+        
+        docids.addElement(rd.docid);
+        documents.addElement(rd.document);
+      }
+      
+      /**
+       * gets an iterator of docids
+       */
+      public Iterator getDocids()
+      {
+        return docids.iterator();
+      }
+      
+      /**
+       * gets an iterator of documents
+       */
+      public Iterator getDocuments()
+      {
+        return documents.iterator();
+      }
+      
+      /**
+       * returns the size of the set
+       */
+      public int size()
+      {
+        return docids.size();
+      }
+      
+      /**
+       * tests to see if this set contains the given docid
+       */
+      public boolean containsDocid(String docid)
+      {
+        for(int i=0; i<docids.size(); i++)
+        {
+          String docid0 = (String)docids.elementAt(i);
+          if(docid0.trim().equals(docid.trim()))
+          {
+            return true;
+          }
+        }
+        return false;
+      }
+      
+      /**
+       * removes the element with the given docid
+       */
+      public String remove(String docid)
+      {
+        for(int i=0; i<docids.size(); i++)
+        {
+          String docid0 = (String)docids.elementAt(i);
+          if(docid0.trim().equals(docid.trim()))
+          {
+            String returnDoc = (String)documents.elementAt(i);
+            documents.remove(i);
+            docids.remove(i);
+            return returnDoc;
+          }
+        }
+        return null;
+      }
+      
+      /**
+       * add a result document
+       */
+      public void put(ResultDocument rd)
+      {
+        addResultDocument(rd);
+      }
+      
+      /**
+       * add a result document by components
+       */
+      public void put(String docid, String document)
+      {
+        addResultDocument(new ResultDocument(docid, document));
+      }
+      
+      /**
+       * get the document part of the result document by docid
+       */
+      public Object get(String docid)
+      {
+        for(int i=0; i<docids.size(); i++)
+        {
+          String docid0 = (String)docids.elementAt(i);
+          if(docid0.trim().equals(docid.trim()))
+          {
+            return documents.elementAt(i);
+          }
+        }
+        return null;
+      }
+      
+      /**
+       * get the document part of the result document by an object
+       */
+      public Object get(Object o)
+      {
+        return get((String)o);
+      }
+      
+      /**
+       * get an entire result document by index number
+       */
+      public ResultDocument get(int index)
+      {
+        return new ResultDocument((String)docids.elementAt(index), 
+          (String)documents.elementAt(index));
+      }
+      
+      /**
+       * return a string representation of this object
+       */
+      public String toString()
+      {
+        String s = "";
+        for(int i=0; i<docids.size(); i++)
+        {
+          s += (String)docids.elementAt(i) + "\n";
+        }
+        return s;
+      }
+    }
 }
