Index: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/ServiceRack.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/ServiceRack.java	(revision 36587)
+++ main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/ServiceRack.java	(revision 36592)
@@ -575,4 +575,5 @@
 	 * getTextString - retrieves a language specific text string for the given
 	 * key and locale, from the specified resource_bundle (dictionary)
+         * dictionary may be null, in which case it will use class names
 	 */
 	protected String getTextString(String key, String lang, String dictionary, String[] args)
@@ -584,14 +585,5 @@
 	protected String getMetadataNameText(String key, String lang)
 	{
-
-		String properties_name = "metadata_names";
-		Dictionary dict = new Dictionary(properties_name, lang);
-
-		String result = dict.get(key);
-		if (result == null)
-		{ // not found
-			return null;
-		}
-		return result;
+          return Dictionary.getTextString(key, lang, null, "metadata_names", null, null, this.class_loader);
 	}
 }
Index: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/Dictionary.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/Dictionary.java	(revision 36587)
+++ main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/Dictionary.java	(revision 36592)
@@ -32,5 +32,8 @@
     /** The default servlet dictionary */
     public static final String core_servlet_dictionary_name = "core_servlet_dictionary";
-    
+  /** Fallback language */
+  protected static final String fallback_language = "en";
+  /** THe string to mark a value as awaiting translator input */
+  public static final String PENDING_STR = "[PENDING]";
 	/** The locale of this dictionary. */
 	protected Locale locale = null;
@@ -39,5 +42,5 @@
 	protected String resource = null;
 
-	/**
+ 	/**
 	 * The ResourceBundle which contains the raw key-value mappings. Loaded from
 	 * a file named "resource_locale.properties
@@ -225,5 +228,4 @@
 			// with the resource as UTF-8, and so not conversion is needed
 			String initial = this.raw.getString(key);
-
 			// if we haven't been given any args, don't bother looking for them
 			if (args == null)
@@ -244,5 +246,4 @@
     public static String getTextString(String key, String lang, String[] args, String dictionary_name, Class class_obj, String stop_at_class, ClassLoader class_loader)
   {
-
       if (dictionary_name == null && class_obj == null) {
 	  // no dictionary or class was specified, just use the default
@@ -253,15 +254,6 @@
       if (dictionary_name != null)
       {
-	  // just try the one specified dictionary
-	  Dictionary dict = new Dictionary(dictionary_name, lang, class_loader);
-	  String result = dict.get(key, args);
-	  if (result == null)
-	  { // not found
-	      
-	      //logger.debug("couldn't find key in dict, "+dictionary_name+" "+key);
-	      //return "_" + key + "_"; // should we use this??
-	      return null;
-	  }
-	  return result;
+        // just try the one specified dictionary
+        return createDictionaryAndGetString(dictionary_name, class_loader, key, lang, args);
       }
 
@@ -269,6 +261,5 @@
       String original_class_name = class_obj.getName();
       original_class_name = original_class_name.substring(original_class_name.lastIndexOf('.') + 1);
-      Dictionary dict = new Dictionary(original_class_name, lang, class_loader);
-      String result = dict.get(key, args);
+      String result = createDictionaryAndGetString(original_class_name, class_loader, key, lang, args);
       if (result != null)
       {
@@ -288,6 +279,5 @@
 	      break;
 	  }
-	  dict = new Dictionary(class_name, lang, class_loader);
-	  result = dict.get(key, args);
+          result = createDictionaryAndGetString(class_name, class_loader, key, lang, args);
 	  if (result != null) {
 	      return result;
@@ -297,5 +287,4 @@
 
       // if we got here, class names were no help, try the default dictionary
-      dict = new Dictionary(core_servlet_dictionary_name, lang, class_loader);
 
       // First we try the key qualified with the original class name
@@ -303,7 +292,8 @@
       // default properties file)
       String full_key = original_class_name+"."+key;
-      result = dict.get(full_key, args);
+      result = createDictionaryAndGetString(core_servlet_dictionary_name, class_loader, full_key, lang, args);
       if (result == null) {
-	  result = dict.get(key, args);
+        // try the key by itself without class qualified prefix
+        result = createDictionaryAndGetString(core_servlet_dictionary_name, class_loader, key, lang, args);
       }
       return result;
@@ -311,3 +301,16 @@
   }
 
+  public static String createDictionaryAndGetString(String dictionary_name, ClassLoader class_loader, String key, String lang, String[] args) {
+    Dictionary dict = new Dictionary(dictionary_name, lang, class_loader);
+    String result = dict.get(key, args);
+    // if we have a pending flag, then try the base language
+    if (result != null && result.startsWith(PENDING_STR) && !lang.equals(fallback_language)) {
+      dict = new Dictionary(dictionary_name, fallback_language, class_loader);
+      result = dict.get(key, args);
+    }
+    return result;
+  }
+  
+
+ 
 }
Index: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/DisplayItemUtil.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/DisplayItemUtil.java	(revision 36587)
+++ main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/DisplayItemUtil.java	(revision 36592)
@@ -85,5 +85,5 @@
 	if (best_di != null) {
 	    // look up the dictionary
-	    String value = getTextString(best_di.getAttribute(GSXML.KEY_ATT), lang, best_di.getAttribute(GSXML.DICTIONARY_ATT), class_loader);
+          String value = Dictionary.createDictionaryAndGetString(best_di.getAttribute(GSXML.DICTIONARY_ATT), class_loader, best_di.getAttribute(GSXML.KEY_ATT), lang, null);
 	    if (value != null) {
 		// copy the node now. Don't want to be modifying the underlying list as can lead to concurrent access problems.
@@ -127,20 +127,4 @@
   }
 
-  protected static String getTextString(String key, String lang, String dictionary, ClassLoader class_loader) {
-    return getTextString(key, lang, dictionary, null, class_loader);
-  }
-
-  protected static String getTextString(String key, String lang, String dictionary, String[] args, ClassLoader class_loader)
-  {
-    Dictionary dict;
-    if (class_loader != null) {
-      dict = new Dictionary(dictionary, lang, class_loader);
-    } else {
-      dict = new Dictionary(dictionary, lang);
-    }
-    String result = dict.get(key, args);
-    return result;
-  }
-  
 
 }
Index: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GS2MacroResolver.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GS2MacroResolver.java	(revision 36587)
+++ main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GS2MacroResolver.java	(revision 36592)
@@ -113,6 +113,5 @@
 			  // if (m.text == null || new_lang)
 			  // {
-				  Dictionary dict = new Dictionary(m.bundle, lang, this.class_loader);
-				  m.text = dict.get(m.key, null);
+                              m.text = Dictionary.createDictionaryAndGetString(m.bundle, this.class_loader, m.key, lang, null);
 					//	}
 				// we assume that dictionary entries will contain no macros
Index: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XSLTUtil.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XSLTUtil.java	(revision 36587)
+++ main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XSLTUtil.java	(revision 36592)
@@ -257,6 +257,5 @@
 
 		// try the specified dictionary first
-		Dictionary dict = new Dictionary(dictionary_name, lang, my_loader);
-	 	String result = dict.get(key, args);
+                String result = Dictionary.createDictionaryAndGetString(dictionary_name, my_loader, key, lang, args);
 	 	if (result == null) {
 		  // fall back to a general interface text search
@@ -300,13 +299,10 @@
     // now we allow looking for files in the interface's resources folder
     CustomClassLoader my_loader = new CustomClassLoader(XSLTUtil.class.getClassLoader(), GSFile.interfaceResourceDir(GlobalProperties.getGSDL3Home(), interface_name));
-    Dictionary dict = new Dictionary("interface_" + interface_name, lang, my_loader);
-    
-    String result = dict.get(key, args);
+    String result = Dictionary.createDictionaryAndGetString("interface_"+interface_name, my_loader, key, lang, args);
     if (result == null)
       {  
 	//if not found, search a separate subdirectory named by the interface name. this is used for eg the flax interface. this could be replaced by new class loader option?
 	String sep_interface_dir = interface_name + File.separatorChar + lang + File.separatorChar + "interface";
-	dict = new Dictionary(sep_interface_dir, lang);
-	result = dict.get(key, args);
+        result = Dictionary.createDictionaryAndGetString(sep_interface_dir, my_loader, key, lang, args);
 	if (result != null)
 	  {
@@ -317,11 +313,11 @@
     if (result == null && !interface_name.startsWith("default")) {
       // not found, try the default interface
+      String dictionary_name;
       if (interface_name.endsWith("2")) { // hack for interface_xxx2.properties
-	dict = new Dictionary("interface_default2", lang);
+	dictionary_name = "interface_default2";
       } else {
-	dict = new Dictionary("interface_default", lang);
-	
+	dictionary_name = "interface_default";
       }
-      result = dict.get(key, args);
+      result = Dictionary.createDictionaryAndGetString(dictionary_name, my_loader, key, lang, args);
     }
 		
@@ -409,6 +405,5 @@
 
 			CustomClassLoader class_loader = new CustomClassLoader(XSLTUtil.class.getClassLoader(), GSFile.collectionResourceDir(GSFile.siteHome(GlobalProperties.getGSDL3Home(), site_name), collection));
-			Dictionary dict = new Dictionary("interface_custom", lang, class_loader);
-			String result = dict.get(key, args);
+			String result = Dictionary.createDictionaryAndGetString("interface_custom", class_loader, key, lang, args); 
 			if (result != null)
 			{
@@ -437,6 +432,5 @@
   public static String getGenericTextWithArgs(String dictionary_name, String lang, String key, String[] args)
   {
-    Dictionary dict = new Dictionary(dictionary_name, lang);
-    String result = dict.get(key, args);
+    String result = Dictionary.createDictionaryAndGetString(dictionary_name, null, key, lang, args);
     if (result == null) {
       return "_"+dictionary_name+"_"+key+"_";
