Index: /gsdl/trunk/src/recpt/dynamicclassifieraction.cpp
===================================================================
--- /gsdl/trunk/src/recpt/dynamicclassifieraction.cpp	(revision 16003)
+++ /gsdl/trunk/src/recpt/dynamicclassifieraction.cpp	(revision 16004)
@@ -155,4 +155,5 @@
   // The metadata element to classify by should be left after all the options have been parsed off
   classifier_options["metadata_element_name"] = classifier_specification;
+  classifier_options["current_position"] = args["dcn"];
 
   // Output the "<ID>Header" format statement if there is one
@@ -193,11 +194,118 @@
   get_metadata_values (metadata_element_name, "", args["c"], collectproto, metadata_values_response, logout);
 
-  // Deal with any hierarchical metadata values
-  map<text_t, int, lttext_t> classifier_nodes;
-  ResultDocInfo_tarray::iterator metadata_value_iterator = metadata_values_response.docInfo.begin();
-  while (metadata_value_iterator != metadata_values_response.docInfo.end())
-  {
+  // After processing any hierarchical metadata values, we're left with the top-level classifer nodes
+  map<text_t, int, lttext_t> classifier_nodes = process_metadata_values (classifier_options, metadata_values_response.docInfo);
+
+  // Display the top-level classifier nodes
+  map<text_t, int, lttext_t>::iterator classifier_nodes_iterator = classifier_nodes.begin();
+  while (classifier_nodes_iterator != classifier_nodes.end())
+  {
+    text_t classifier_node_OID = (*classifier_nodes_iterator).first;
+    text_t classifier_node_label = (*classifier_nodes_iterator).first;
+    int classifier_node_numleafdocs = (*classifier_nodes_iterator).second;
+    output_classifier_node (classifier_node_OID, classifier_node_label, classifier_node_numleafdocs, 0, args, collectproto, browsers, disp, outconvert, textout, logout);
+    classifier_nodes_iterator++;
+  }
+}
+
+
+void dynamicclassifieraction::output_internal_page (text_tmap classifier_options, cgiargsclass &args,
+						    recptproto *collectproto, browsermapclass *browsers,
+						    displayclass &disp, outconvertclass &outconvert,
+						    ostream &textout, ostream &logout)
+{
+  text_t arg_dcn = args["dcn"];
+  text_t classifier_node_OID = arg_dcn;
+  text_t classifier_node_metadata_value = arg_dcn;
+  int node_indent = 0;
+
+  // Get all the classifier nodes at this level
+  text_t metadata_element_name = classifier_options["metadata_element_name"];
+  text_t metadata_value_filter = classifier_node_metadata_value + "|*";
+  FilterResponse_t metadata_values_response;
+  get_metadata_values (metadata_element_name, metadata_value_filter, args["c"], collectproto, metadata_values_response, logout);
+
+  // Get all the documents at this level
+  FilterResponse_t document_OIDs_response;
+  get_documents_with_metadata_value (metadata_element_name, classifier_node_metadata_value, "dls.Title", args["c"], collectproto, document_OIDs_response, logout);
+
+  // Check there are some classifier nodes or some documents at this level, otherwise the "dcn" argument was invalid
+  if (metadata_values_response.docInfo.empty() && document_OIDs_response.docInfo.empty())
+  {
+    textout << outconvert << disp << "Error: Invalid dcn value \"" << arg_dcn << "\".\n";
+    return;
+  }
+
+  // Determine the parent classifier nodes
+  text_tarray parent_classifier_node_labels;
+  splitchar(classifier_node_OID.begin(), classifier_node_OID.end(), '|', parent_classifier_node_labels);
+  text_t classifier_node_label = parent_classifier_node_labels.back();
+  parent_classifier_node_labels.pop_back();
+
+  // Display the parent classifier nodes
+  text_t parent_classifier_node_OID = "";
+  text_tarray::iterator parent_classifier_node_labels_iterator = parent_classifier_node_labels.begin();
+  while (parent_classifier_node_labels_iterator != parent_classifier_node_labels.end())
+  {
+    parent_classifier_node_OID += (parent_classifier_node_OID != "" ? "|" : "");
+    parent_classifier_node_OID += *parent_classifier_node_labels_iterator;
+    text_t parent_classifier_node_label = *parent_classifier_node_labels_iterator;
+    text_t parent_classifier_node_numleafdocs = "?";  // We can't determine this without more database requests
+    output_classifier_node (parent_classifier_node_OID, parent_classifier_node_label, parent_classifier_node_numleafdocs, node_indent, args, collectproto, browsers, disp, outconvert, textout, logout);
+    node_indent++;
+
+    parent_classifier_node_labels_iterator++;
+  }
+
+  // Display the selected classifier node
+  int classifier_node_numleafdocs = metadata_values_response.docInfo.size() + document_OIDs_response.docInfo.size();
+  output_classifier_node (classifier_node_OID, classifier_node_label, classifier_node_numleafdocs, node_indent, args, collectproto, browsers, disp, outconvert, textout, logout);
+  node_indent++;
+
+  // After processing any hierarchical metadata values, we're left with the child classifer nodes
+  map<text_t, int, lttext_t> child_classifier_nodes = process_metadata_values (classifier_options, metadata_values_response.docInfo);
+
+  // Display the child classifier nodes
+  map<text_t, int, lttext_t>::iterator child_classifier_nodes_iterator = child_classifier_nodes.begin();
+  while (child_classifier_nodes_iterator != child_classifier_nodes.end())
+  {
+    text_t child_classifier_node_OID = classifier_node_OID + "|" + (*child_classifier_nodes_iterator).first;
+    text_t child_classifier_node_label = (*child_classifier_nodes_iterator).first;
+    int child_classifier_node_numleafdocs = (*child_classifier_nodes_iterator).second;
+    output_classifier_node (child_classifier_node_OID, child_classifier_node_label, child_classifier_node_numleafdocs, node_indent, args, collectproto, browsers, disp, outconvert, textout, logout);
+    child_classifier_nodes_iterator++;
+  }
+
+  // Display the documents at this level
+  text_tarray document_OIDs;
+  ResultDocInfo_tarray::iterator document_OID_iterator = document_OIDs_response.docInfo.begin();
+  while (document_OID_iterator != document_OIDs_response.docInfo.end())
+  {
+    document_OIDs.push_back ((*document_OID_iterator).OID);
+    document_OID_iterator++;
+  }
+
+  output_document_nodes (document_OIDs, node_indent, args, collectproto, browsers, disp, outconvert, textout, logout);
+}
+
+
+map<text_t, int, lttext_t> dynamicclassifieraction::process_metadata_values (text_tmap classifier_options,
+									     ResultDocInfo_tarray metadata_values)
+{
+  map<text_t, int, lttext_t> metadata_values_grouped;
+
+  text_t current_position = classifier_options["current_position"];
+  ResultDocInfo_tarray::iterator metadata_value_iterator = metadata_values.begin();
+  while (metadata_value_iterator != metadata_values.end())
+  {
+    text_t metadata_value = (*metadata_value_iterator).OID;
+
+    // If we're not at the top-level we need to remove the current position from the metadata values
+    if (current_position != "" && starts_with(metadata_value, current_position + "|"))
+    {
+      metadata_value = substr(metadata_value.begin() + (current_position + "|").size(), metadata_value.end());
+    }
+
     // Is this metadata value hierarchical?
-    text_t metadata_value = (*metadata_value_iterator).OID;
     text_t::iterator hierarchy_split_position = findchar(metadata_value.begin(), metadata_value.end(), '|');
     if (hierarchy_split_position != metadata_value.end())
@@ -208,135 +316,16 @@
 
     // Create a node for this metadata value if we haven't seen it before
-    if (classifier_nodes.find(metadata_value) == classifier_nodes.end())
+    if (metadata_values_grouped.find(metadata_value) == metadata_values_grouped.end())
     {
-      classifier_nodes[metadata_value] = 0;
+      metadata_values_grouped[metadata_value] = 0;
     }
 
     // Increment the occurrence count
-    classifier_nodes[metadata_value] += (*metadata_value_iterator).result_num;
+    metadata_values_grouped[metadata_value] += (*metadata_value_iterator).result_num;
 
     metadata_value_iterator++;
   }
 
-  // Display the top-level classifier nodes
-  map<text_t, int, lttext_t>::iterator classifier_nodes_iterator = classifier_nodes.begin();
-  while (classifier_nodes_iterator != classifier_nodes.end())
-  {
-    text_t classifier_node_OID = (*classifier_nodes_iterator).first;
-    text_t classifier_node_label = (*classifier_nodes_iterator).first;
-    int classifier_node_numleafdocs = (*classifier_nodes_iterator).second;
-    output_classifier_node (classifier_node_OID, classifier_node_label, classifier_node_numleafdocs, 0, args, collectproto, browsers, disp, outconvert, textout, logout);
-    classifier_nodes_iterator++;
-  }
-}
-
-
-void dynamicclassifieraction::output_internal_page (text_tmap classifier_options, cgiargsclass &args,
-						    recptproto *collectproto, browsermapclass *browsers,
-						    displayclass &disp, outconvertclass &outconvert,
-						    ostream &textout, ostream &logout)
-{
-  text_t arg_dcn = args["dcn"];
-  text_t classifier_node_OID = arg_dcn;
-  text_t classifier_node_metadata_value = arg_dcn;
-  int node_indent = 0;
-
-  // Get all the classifier nodes at this level
-  text_t metadata_element_name = classifier_options["metadata_element_name"];
-  text_t metadata_value_filter = classifier_node_metadata_value + "|*";
-  FilterResponse_t metadata_values_response;
-  get_metadata_values (metadata_element_name, metadata_value_filter, args["c"], collectproto, metadata_values_response, logout);
-
-  // Get all the documents at this level
-  FilterResponse_t document_OIDs_response;
-  get_documents_with_metadata_value (metadata_element_name, classifier_node_metadata_value, "dls.Title", args["c"], collectproto, document_OIDs_response, logout);
-
-  // Check there are some classifier nodes or some documents at this level, otherwise the "dcn" argument was invalid
-  if (metadata_values_response.docInfo.empty() && document_OIDs_response.docInfo.empty())
-  {
-    textout << outconvert << disp << "Error: Invalid dcn value \"" << arg_dcn << "\".\n";
-    return;
-  }
-
-  // Determine the parent classifier nodes
-  text_tarray parent_classifier_node_labels;
-  splitchar(classifier_node_OID.begin(), classifier_node_OID.end(), '|', parent_classifier_node_labels);
-  text_t classifier_node_label = parent_classifier_node_labels.back();
-  parent_classifier_node_labels.pop_back();
-
-  // Display the parent classifier nodes
-  text_t parent_classifier_node_OID = "";
-  text_tarray::iterator parent_classifier_node_labels_iterator = parent_classifier_node_labels.begin();
-  while (parent_classifier_node_labels_iterator != parent_classifier_node_labels.end())
-  {
-    parent_classifier_node_OID += (parent_classifier_node_OID != "" ? "|" : "");
-    parent_classifier_node_OID += *parent_classifier_node_labels_iterator;
-    text_t parent_classifier_node_label = *parent_classifier_node_labels_iterator;
-    text_t parent_classifier_node_numleafdocs = "?";  // We can't determine this without more database requests
-    output_classifier_node (parent_classifier_node_OID, parent_classifier_node_label, parent_classifier_node_numleafdocs, node_indent, args, collectproto, browsers, disp, outconvert, textout, logout);
-    node_indent++;
-
-    parent_classifier_node_labels_iterator++;
-  }
-
-  // Display the selected classifier node
-  int classifier_node_numleafdocs = metadata_values_response.docInfo.size() + document_OIDs_response.docInfo.size();
-  output_classifier_node (classifier_node_OID, classifier_node_label, classifier_node_numleafdocs, node_indent, args, collectproto, browsers, disp, outconvert, textout, logout);
-  node_indent++;
-
-  // Determine the child classifier nodes
-  map<text_t, int, lttext_t> child_classifier_nodes;
-  ResultDocInfo_tarray::iterator metadata_value_iterator = metadata_values_response.docInfo.begin();
-  while (metadata_value_iterator != metadata_values_response.docInfo.end())
-  {
-    text_t metadata_value = (*metadata_value_iterator).OID;
-
-    // If the classifier is hierarchical we need to remove the current position from the metadata value
-    if (starts_with(metadata_value, arg_dcn + "|"))
-    {
-      metadata_value = substr(metadata_value.begin() + (arg_dcn + "|").size(), metadata_value.end());
-    }
-
-    // Is this metadata value hierarchical?
-    text_t::iterator hierarchy_split_position = findchar(metadata_value.begin(), metadata_value.end(), '|');
-    if (hierarchy_split_position != metadata_value.end())
-    {
-      // Yes, so split off the first part of the hierarchy for the classifier node
-      metadata_value = substr(metadata_value.begin(), hierarchy_split_position);
-    }
-
-    // Create a node for this metadata value if we haven't seen it before
-    if (child_classifier_nodes.find(metadata_value) == child_classifier_nodes.end())
-    {
-      child_classifier_nodes[metadata_value] = 0;
-    }
-
-    // Increment the occurrence count
-    child_classifier_nodes[metadata_value] += (*metadata_value_iterator).result_num;
-
-    metadata_value_iterator++;
-  }
-
-  // Display the child classifier nodes
-  map<text_t, int, lttext_t>::iterator child_classifier_nodes_iterator = child_classifier_nodes.begin();
-  while (child_classifier_nodes_iterator != child_classifier_nodes.end())
-  {
-    text_t child_classifier_node_OID = classifier_node_OID + "|" + (*child_classifier_nodes_iterator).first;
-    text_t child_classifier_node_label = (*child_classifier_nodes_iterator).first;
-    int child_classifier_node_numleafdocs = (*child_classifier_nodes_iterator).second;
-    output_classifier_node (child_classifier_node_OID, child_classifier_node_label, child_classifier_node_numleafdocs, node_indent, args, collectproto, browsers, disp, outconvert, textout, logout);
-    child_classifier_nodes_iterator++;
-  }
-
-  // Display the documents at this level
-  text_tarray document_OIDs;
-  ResultDocInfo_tarray::iterator document_OID_iterator = document_OIDs_response.docInfo.begin();
-  while (document_OID_iterator != document_OIDs_response.docInfo.end())
-  {
-    document_OIDs.push_back ((*document_OID_iterator).OID);
-    document_OID_iterator++;
-  }
-
-  output_document_nodes (document_OIDs, node_indent, args, collectproto, browsers, disp, outconvert, textout, logout);
+  return metadata_values_grouped;
 }
 
Index: /gsdl/trunk/src/recpt/dynamicclassifieraction.h
===================================================================
--- /gsdl/trunk/src/recpt/dynamicclassifieraction.h	(revision 16003)
+++ /gsdl/trunk/src/recpt/dynamicclassifieraction.h	(revision 16004)
@@ -73,4 +73,7 @@
 			     ostream &textout, ostream &logout);
 
+  map<text_t, int, lttext_t> process_metadata_values (text_tmap classifier_options,
+						      ResultDocInfo_tarray metadata_values);
+
   void output_classifier_node (text_t classifier_node_OID, text_t classifier_node_label,
 			       text_t classifier_node_numleafdocs, int classifier_node_indent,
