Index: gsdl/trunk/src/oaiservr/listsetsaction.cpp
===================================================================
--- gsdl/trunk/src/oaiservr/listsetsaction.cpp	(revision 15198)
+++ gsdl/trunk/src/oaiservr/listsetsaction.cpp	(revision 15387)
@@ -18,5 +18,5 @@
   while (param_iterator != params.end())
   {
-    if (param_iterator->first != "verb")
+    if (param_iterator->first != "verb" && param_iterator->first != "resumptionToken")
     {
       params.erase(param_iterator->first);
@@ -26,7 +26,16 @@
   }
 
-  if(params_size != 1){
+  if (params_size != params.getSize()) {
     this->errorType = "badArgument";
     return false;
+  }
+
+  if (params["resumptionToken"] != "") {
+    ResumptionToken token(params["resumptionToken"]);
+    // TO DO: Resumption token validation checking (the token.isValid() function is useless for ListSets)
+    // if (!token.isValid()) {
+    //   this->errorType = "badResumptionToken";
+    //   return false;
+    // }
   }
 
@@ -57,5 +66,4 @@
   text_tset        metadata;
   ofstream         logout("oai.log", ios::app);
-  text_tarray *result = new text_tarray;
   
   // get a list of the collections available
@@ -65,12 +73,34 @@
   }
 
+  // check resumption token
+  int startSet = 0;
+  if (params["resumptionToken"] != "") {
+    ResumptionToken token(params["resumptionToken"]);
+    startSet = token.getPosition() - 1; // first document is said to be 1..
+  }
+  this->replyToken = NULL;
+
+  this->setNumber = 0;
+  this->setsOutput = 0;
   for(int current_col = 0; current_col < collections.size(); ++current_col) {
     // output the collection as a set, first, then its children
     text_t gsdlCollect = collections[current_col];
 
-    output << "  <set>" << endl;
-    output << "    <setSpec>" << gsdlCollect << "</setSpec>" << endl;;
-    output << "    <setName>" << gsdlCollect << "</setName>" << endl;
-    output << "  </set>" << endl;
+    if (this->setsOutput == this->configuration->resumeAfter())
+    {
+      this->replyToken = new ResumptionToken("", "", "");
+      this->replyToken->setPosition("", this->setNumber+1);
+      break;
+    }
+
+    if (this->setNumber >= startSet)
+    {
+      output << "  <set>" << endl;
+      output << "    <setSpec>" << gsdlCollect << "</setSpec>" << endl;;
+      output << "    <setName>" << gsdlCollect << "</setName>" << endl;
+      output << "  </set>" << endl;
+      this->setsOutput++;
+    }
+    setNumber++;
 
     // get all the children of the (relevant) classifier data structures
@@ -78,6 +108,13 @@
     // and send them to the "recurse_content" list
     for (int c = 0; c < response.numDocs; ++c) {
-      this->recurse_content(output, protocol, gsdlCollect, response.docInfo[c].OID, gsdlCollect);
-    }
+      this->recurse_content(output, protocol, gsdlCollect, response.docInfo[c].OID, gsdlCollect, startSet);
+    }
+  }
+
+  // do a resumption token if required; errors cancel a token...
+  if (this->replyToken != NULL && this->errorType == "") {
+    output << "  <resumptionToken>" << endl;
+    output << "    " << this->replyToken->getToken() << endl;
+    output << "  </resumptionToken>" << endl;
   }
 
@@ -86,5 +123,5 @@
 
 void listsetsaction::recurse_content(ostream &output, recptproto *protocol, text_t &collection, 
-				     const text_t &classifier, text_t setHierarchy)
+				     const text_t &classifier, text_t setHierarchy, int startSet)
 {
   // metadata for this call
@@ -92,4 +129,11 @@
   text_tset        metadata;
   ofstream         logout("oai.log", ios::app);
+
+  if (this->setsOutput == this->configuration->resumeAfter())
+  {
+    this->replyToken = new ResumptionToken("", "", "");
+    this->replyToken->setPosition("", this->setNumber+1);
+    return;
+  }
 
   metadata.insert("contains");
@@ -135,20 +179,25 @@
   // output the xml for this set; use the classifier id for the name
   // if the title is blank
-  output << "  <set>" << endl;
-  text_t oai_classifier = classifier;
-  oaiclassifier::toOAI(collection, oai_classifier);
-  output << "    <setSpec>" << oai_classifier << "</setSpec>" << endl;
-  output << "    <setName>";
   // curSet holds the colon-separated sequence of parent sets of the current set
   text_t curSet;
-  if (!title.empty()) {
-    curSet = setHierarchy + ":" + title;
-  }
-  else {
-    curSet = classifier; // Pretty much never gets here (shouldn't, at least)
-  }
-  output << curSet;
-  output << "</setName>" << endl;
-  output << "  </set>" << endl;
+  if (this->setNumber >= startSet)
+  {
+    output << "  <set>" << endl;
+    text_t oai_classifier = classifier;
+    oaiclassifier::toOAI(collection, oai_classifier);
+    output << "    <setSpec>" << oai_classifier << "</setSpec>" << endl;
+    output << "    <setName>";
+    if (!title.empty()) {
+      curSet = setHierarchy + ":" + title;
+    }
+    else {
+      curSet = classifier; // Pretty much never gets here (shouldn't, at least)
+    }
+    output << curSet;
+    output << "</setName>" << endl;
+    output << "  </set>" << endl;
+    this->setsOutput++;
+  }
+  this->setNumber++;
 
   // get the children of this classifier and iterate them
@@ -173,5 +222,5 @@
     // parent sets. curSet is pass-by-value, so that as we step out of recursion we remember
     // old set hierarchies.
-    this->recurse_content(output, protocol, collection, child, curSet);
+    this->recurse_content(output, protocol, collection, child, curSet, startSet);
   }
   
