Index: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractGS2DocumentRetrieve.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractGS2DocumentRetrieve.java	(revision 22309)
+++ main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractGS2DocumentRetrieve.java	(revision 22319)
@@ -123,5 +123,5 @@
     /** if id ends in .fc, .pc etc, then translate it to the correct id */
     protected String translateId(String node_id) {
-	return this.coll_db.translateOID(node_id);
+	return OID.translateOID(this.coll_db, node_id); //return this.coll_db.translateOID(node_id);
     }
     
Index: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/FedoraServiceProxy.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/FedoraServiceProxy.java	(revision 22309)
+++ main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/FedoraServiceProxy.java	(revision 22319)
@@ -53,5 +53,5 @@
  */
 public class FedoraServiceProxy
-    extends ServiceRack
+    extends ServiceRack implements OID.OIDTranslatable
 {
 
@@ -417,7 +417,8 @@
     protected String translateId(String id) {
 	if (OID.needsTranslating(id)) {
-	    return translateOID(id);
-	}
-	return id;}
+	    return OID.translateOID(this, id); //return translateOID(id);
+	}
+	return id;
+    }
     
     /** if an id is not a greenstone id (an external id) then translate 
@@ -434,84 +435,6 @@
    * a suffix is expected to be present so test before using 
    */
-  public String translateOID(String oid) {      
-    int p = oid.lastIndexOf('.');
-    if (p != oid.length()-3) {
-      logger.info("translateoid error: '.' is not the third to last char!!");
-      return oid;
-    }
-	
-    String top = oid.substring(0, p);
-    String suff = oid.substring(p+1);
-
-    // just in case we have multiple extensions, we must translate
-    // we process inner ones first
-    if (OID.needsTranslating(top)) {
-      top = translateOID(top);
-    }
-    if (suff.equals("pr")) {
-      return OID.getParent(top);
-    } 
-    if (suff.equals("rt")) {
-      return OID.getTop(top);
-    } 
-    if (suff.equals("np")) {
-      // try first child
-
-      String node_id = translateOID(top+".fc");
-      if (!node_id.equals(top)) {
-	  return node_id;
-      }
-
-      // try next sibling
-      node_id = translateOID(top+".ns");
-      if (!node_id.equals(top)) {
-	  return node_id;
-      }
-      // otherwise we keep trying parents sibling
-      String child_id = top;
-      String parent_id = OID.getParent(child_id);
-      while(!parent_id.equals(child_id)) {
-	node_id = translateOID(parent_id+".ns");
-	if (!node_id.equals(parent_id)) {
-	  return node_id;
-	}
-	child_id = parent_id;
-	parent_id = OID.getParent(child_id);
-      }
-      return top; // we couldn't get a next page, so just return the original
-    } 
-    if (suff.equals("pp")) {
-      String prev_sib = translateOID(top+".ps");
-      if (prev_sib.equals(top)) {
-	// no previous sibling, so return the parent
-	return OID.getParent(top);
-      }
-      // there is a previous sibling, so its either this section, or the last child of the last child
-      String last_child = translateOID(prev_sib+".lc");
-      while (!last_child.equals(prev_sib)) {
-	prev_sib = last_child;
-	last_child = translateOID(prev_sib+".lc");
-      }
-      return last_child;
-    } 
-	
-    int sibling_num = 0;
-    if (suff.equals("ss")) {
-      // we have to remove the sib num before we get top
-      p = top.lastIndexOf('.');
-      sibling_num = Integer.parseInt(top.substring(p+1));
-      top = top.substring(0, p);
-    }
-	
-    // need to get info out of Fedora
-    String doc_id = top;
-    if (suff.endsWith("s")) {
-      doc_id = OID.getParent(top);
-      if (doc_id.equals(top)) {
-	// i.e. we are already at the top
-	return top;
-      }
-    }
-    
+    public String processOID(String doc_id, String top, String suff, int sibling_num) {
+
     // send off request to get sibling etc. information from Fedora
     Element response = null;
Index: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/GS2Browse.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/GS2Browse.java	(revision 22309)
+++ main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/GS2Browse.java	(revision 22319)
@@ -107,5 +107,5 @@
     /** if id ends in .fc, .pc etc, then translate it to the correct id */
     protected String translateId(String node_id) {
-	return this.coll_db.translateOID(node_id);
+	return OID.translateOID(this.coll_db, node_id); //return this.coll_db.translateOID(node_id);
     }
 
Index: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/OID.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/OID.java	(revision 22309)
+++ main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/OID.java	(revision 22319)
@@ -19,4 +19,6 @@
 package org.greenstone.gsdl3.util;
 
+import org.apache.log4j.*;
+
 /** utility class to handle greenstone OIDs
  *
@@ -24,4 +26,10 @@
  */
 public class OID {
+
+    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.OID.class.getName());
+
+    public interface OIDTranslatable {
+	public String processOID(String doc_id, String top, String suffix, int sibling_num);
+    }
     
     /** returns everything up to the first dot 
@@ -102,3 +110,96 @@
       return child.startsWith(parent);
     }
+
+    
+  /** translates relative oids into proper oids:
+   * .pr (parent), .rt (root) .fc (first child), .lc (last child),
+   * .ns (next sibling), .ps (previous sibling) 
+   * .np (next page), .pp (previous page) : links sections in the order that you'd read the document
+   * a suffix is expected to be present so test before using
+   * Other classes can implement the method processOID of interface OIDTranslatable
+   * to process the oid further to handle siblings.
+   */
+    public static String translateOID(OIDTranslatable translator, String oid) {
+    int p = oid.lastIndexOf('.');
+    if (p != oid.length()-3) {
+      logger.info("translateoid error: '.' is not the third to last char!!");
+      return oid;
+    }
+	
+    String top = oid.substring(0, p);
+    String suff = oid.substring(p+1);
+
+    // just in case we have multiple extensions, we must translate
+    // we process inner ones first
+    if (OID.needsTranslating(top)) {
+	top = OID.translateOID(translator, top);
+    }
+    if (suff.equals("pr")) {
+      return OID.getParent(top);
+    } 
+    if (suff.equals("rt")) {
+      return OID.getTop(top);
+    } 
+    if (suff.equals("np")) {
+      // try first child
+
+      String node_id = OID.translateOID(translator, top+".fc");
+      if (!node_id.equals(top)) {
+	  return node_id;
+      }
+
+      // try next sibling
+      node_id = OID.translateOID(translator, top+".ns");
+      if (!node_id.equals(top)) {
+	  return node_id;
+      }
+      // otherwise we keep trying parents sibling
+      String child_id = top;
+      String parent_id = OID.getParent(child_id);
+      while(!parent_id.equals(child_id)) {
+	node_id = OID.translateOID(translator, parent_id+".ns");
+	if (!node_id.equals(parent_id)) {
+	  return node_id;
+	}
+	child_id = parent_id;
+	parent_id = OID.getParent(child_id);
+      }
+      return top; // we couldn't get a next page, so just return the original
+    } 
+    if (suff.equals("pp")) {
+      String prev_sib = OID.translateOID(translator, top+".ps");
+      if (prev_sib.equals(top)) {
+	// no previous sibling, so return the parent
+	return OID.getParent(top);
+      }
+      // there is a previous sibling, so it's either this section, or the last child of the last child
+      String last_child = OID.translateOID(translator, prev_sib+".lc");
+      while (!last_child.equals(prev_sib)) {
+	prev_sib = last_child;
+	last_child = OID.translateOID(translator, prev_sib+".lc");
+      }
+      return last_child;
+    } 
+	
+    int sibling_num = 0;
+    if (suff.equals("ss")) {
+      // we have to remove the sib num before we get top
+      p = top.lastIndexOf('.');
+      sibling_num = Integer.parseInt(top.substring(p+1));
+      top = top.substring(0, p);
+    }
+	
+    // need to get info out of Fedora
+    String doc_id = top;
+    if (suff.endsWith("s")) {
+      doc_id = OID.getParent(top);
+      if (doc_id.equals(top)) {
+	// i.e. we are already at the top
+	return top;
+      }
+    }
+    
+    return translator.processOID(doc_id, top, suff, sibling_num);
+
+  }
 }
Index: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/SimpleCollectionDatabase.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/SimpleCollectionDatabase.java	(revision 22309)
+++ main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/SimpleCollectionDatabase.java	(revision 22319)
@@ -21,5 +21,5 @@
 import org.apache.log4j.*;
 
-public class SimpleCollectionDatabase {
+public class SimpleCollectionDatabase implements OID.OIDTranslatable {
   
   static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.SimpleCollectionDatabase.class.getName());
@@ -136,6 +136,7 @@
     return null;
   }
-  
-  /** translates relative oids into proper oids:
+
+  /** After OID.translateOID() is through, this method processes OID further 
+   * to translate relative oids into proper oids:
    * .pr (parent), .rt (root) .fc (first child), .lc (last child),
    * .ns (next sibling), .ps (previous sibling) 
@@ -143,82 +144,6 @@
    * a suffix is expected to be present so test before using 
    */
-  public String translateOID(String oid) {
-
-    int p = oid.lastIndexOf('.');
-    if (p != oid.length()-3) {
-      logger.info("translateoid error: '.' is not the third to last char!!");
-      return oid;
-    }
-	
-    String top = oid.substring(0, p);
-    String suff = oid.substring(p+1);
-    // just in case we have multiple extensions, we must translate
-    // we process inner ones first
-    if (OID.needsTranslating(top)) {
-      top = translateOID(top);
-    }
-    if (suff.equals("pr")) {
-      return OID.getParent(top);
-    } 
-    if (suff.equals("rt")) {
-      return OID.getTop(top);
-    } 
-    if (suff.equals("np")) {
-      // try first child
-      String node_id = translateOID(top+".fc");
-      if (!node_id.equals(top)) {
-	return node_id;
-      }
-      // try next sibling
-      node_id = translateOID(top+".ns");
-      if (!node_id.equals(top)) {
-	return node_id;
-      }
-      // otherwise we keep trying parents sibling
-      String child_id = top;
-      String parent_id = OID.getParent(child_id);
-      while(!parent_id.equals(child_id)) {
-	node_id = translateOID(parent_id+".ns");
-	if (!node_id.equals(parent_id)) {
-	  return node_id;
-	}
-	child_id = parent_id;
-	parent_id = OID.getParent(child_id);
-      }
-      return top; // we couldn't get a next page, so just return the original
-    } 
-    if (suff.equals("pp")) {
-      String prev_sib = translateOID(top+".ps");
-      if (prev_sib.equals(top)) {
-	// no previous sibling, so return the parent
-	return OID.getParent(top);
-      }
-      // there is a previous sibling, so its either this section, or the last child of the last child..
-      String last_child = translateOID(prev_sib+".lc");
-      while (!last_child.equals(prev_sib)) {
-	prev_sib = last_child;
-	last_child = translateOID(prev_sib+".lc");
-      }
-      return last_child;
-    } 
-	
-    int sibling_num = 0;
-    if (suff.equals("ss")) {
-      // we have to remove the sib num before we get top
-      p = top.lastIndexOf('.');
-      sibling_num = Integer.parseInt(top.substring(p+1));
-      top = top.substring(0, p);
-    }
-	
-    // need to get info out of collection db -
-    String doc_id = top;
-    if (suff.endsWith("s")) {
-      doc_id = OID.getParent(top);
-      if (doc_id.equals(top)) {
-	// i.e. we are already at the top
-	return top;
-      }
-    }
-    DBInfo info = getInfo(doc_id);
+    public String processOID(String doc_id, String top, String suff, int sibling_num) {
+	DBInfo info = getInfo(doc_id);
     if (info==null) {
       logger.info("info is null!!");
@@ -264,4 +189,4 @@
 	
     return top;
-  }
+    }  
 }
