Index: gsdl/trunk/runtime-src/src/recpt/formattools.cpp
===================================================================
--- gsdl/trunk/runtime-src/src/recpt/formattools.cpp	(revision 16915)
+++ gsdl/trunk/runtime-src/src/recpt/formattools.cpp	(revision 19046)
@@ -61,4 +61,5 @@
   mqualifier.sibling = sNone;
   mqualifier.child   = cNone;
+  pre_tree_traverse.clear();
   parentoptions.clear();
   siblingoptions.clear();
@@ -470,15 +471,61 @@
   }
 
-  if (meta.size() > 7 && (substr (meta.begin(), meta.begin()+6) == "parent")) {
-    getParents = true;
-    metaoption.metacommand |= mParent;
-    get_parent_options (meta, metaoption);
-  } 
-  else if (meta.size() > 6 && (substr (meta.begin(), meta.begin()+5) == "child")) {
-    metaoption.metacommand |= mChild;
-    get_child_options (meta, metaoption);
-    metadata.insert("contains");
-  } 
-  // parent and child can have sibling also
+  bool had_parent_or_child = true;
+  bool prev_was_parent = false;
+  bool prev_was_child  = false;
+
+  while (had_parent_or_child) {
+    if (meta.size() > 7 
+	&& (substr (meta.begin(), meta.begin()+6) == "parent")) {
+
+      // clear out sibling and child (cmd and options)
+      metaoption.metacommand &= ~(mChild|mSibling);
+      metaoption.childoptions.clear();
+      metaoption.siblingoptions.clear();
+
+      getParents = true;
+      metaoption.metacommand |= mParent;
+      get_parent_options (meta, metaoption);
+
+      if (prev_was_parent) {
+	metaoption.pre_tree_traverse += ".pr";
+      }
+      else if (prev_was_child) {
+	metaoption.pre_tree_traverse += ".fc";
+      }
+
+      prev_was_parent = true;
+      prev_was_child  = false;
+    } 
+    else if (meta.size() > 6 
+	     && (substr (meta.begin(), meta.begin()+5) == "child")) {
+
+      // clear out sibling and parent (cmd and options)
+      metaoption.metacommand &= ~(mParent|mSibling);
+      metaoption.parentoptions.clear();
+      metaoption.siblingoptions.clear();
+
+      metaoption.metacommand |= mChild;
+      get_child_options (meta, metaoption);
+      metadata.insert("contains");
+
+      if (prev_was_parent) {
+	metaoption.pre_tree_traverse += ".pr";
+      }
+      else if (prev_was_child) {
+	metaoption.pre_tree_traverse += ".fc";
+      }
+
+      prev_was_child  = true;
+      prev_was_parent = false;
+    } 
+    else {
+      prev_was_child  = false;
+      prev_was_parent = false;
+      had_parent_or_child = false;
+    }
+  }
+
+  // parent/child can have sibling tacked on end also
   if (meta.size() > 8 && (substr (meta.begin(), meta.begin()+7) == "sibling")) {
     metaoption.metacommand |= mSibling;
@@ -928,4 +975,5 @@
   if (docinfo.metadata["contains"].values[0].size()==0) return ""; // no children
   
+  const text_t& pre_tree_trav = meta.pre_tree_traverse;
   const text_t& child_metaname = meta.metaname;
   const text_t& child_field = meta.childoptions;
@@ -937,6 +985,7 @@
     // just one child
     //get the information associated with the metadata for child doc
-    if (!get_info (docinfo.OID+child_field, collection, "", child_metadata, 
-		   false, collectproto, child_response, logout)) return ""; // invalid child number
+    if (!get_info (docinfo.OID+pre_tree_trav+child_field, collection, "", 
+		   child_metadata, false, collectproto, child_response, 
+		   logout)) return ""; // invalid child number
 
       if (child_response.docInfo.empty()) return false; // no info for the child
@@ -952,4 +1001,23 @@
     
   if (meta.mqualifier.child != cAll) return false; // invalid qualifier
+
+
+  if (!pre_tree_trav.empty()) {
+    // need to get relevant "contains" metadata for new (e.g. pre tree trav) node
+    FilterResponse_t trav_response;
+
+    text_tset trav_metadata;
+    trav_metadata.insert("contains"); 
+
+    if (!get_info (docinfo.OID+pre_tree_trav, collection, "", 
+		   trav_metadata, false, collectproto, trav_response, 
+		   logout)) return ""; // invalid pre_tree_trav
+
+    if (trav_response.docInfo.empty()) return false; // no info for the pre_tree_trav OID
+  
+    ResultDocInfo_t& trav_docinfo = trav_response.docInfo[0];
+    // use this for rest of routine
+    docinfo = trav_docinfo;
+  }
   
   // we need to get all children
@@ -965,5 +1033,4 @@
     here++;
     if (*(oid.begin()) == '"') translate_parent (oid, docinfo.OID);
-    
     
     //get the information associated with the metadata for child doc
