Speed up i18n generation by caching partial results.

Merged r5525-5527 from the 6/2 snapshot branch, modified with
review feedback.

Patch by: jat
Review by: fabbott


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5576 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/i18n/rebind/AnnotationsResource.java b/user/src/com/google/gwt/i18n/rebind/AnnotationsResource.java
index 7dd4cf4..b608adb 100644
--- a/user/src/com/google/gwt/i18n/rebind/AnnotationsResource.java
+++ b/user/src/com/google/gwt/i18n/rebind/AnnotationsResource.java
@@ -76,6 +76,7 @@
    * Class for argument information, used for export.
    */
   public static class ArgumentInfo {
+
     public String example;
     public boolean isPluralCount;
     public String name;
@@ -92,6 +93,10 @@
    */
   private static class MethodEntry {
 
+    // Strings used in toString for formatting.
+    private static final String DETAILS_PREFIX = " (";
+    private static final String DETAILS_SEPARATOR = ", ";
+
     public ArrayList<ArgumentInfo> arguments;
     public String description;
     public String meaning;
@@ -114,13 +119,36 @@
     public void addPluralText(String form, String pluralFormText) {
       pluralText.put(form, pluralFormText);
     }
+
+    @Override
+    public String toString() {
+      StringBuilder buf = new StringBuilder();
+      buf.append(text);
+      String prefix = DETAILS_PREFIX;
+      if (meaning != null) {
+        buf.append(prefix).append("meaning=").append(meaning);
+        prefix = DETAILS_SEPARATOR;
+      }
+      if (description != null) {
+        buf.append(prefix).append("desc=").append(description);
+        prefix = DETAILS_SEPARATOR;
+      }
+      if (DETAILS_SEPARATOR == prefix) {
+        buf.append(')');
+      }
+      return buf.toString();
+    }
   }
 
   /**
    * Returns the key for a given method.
-   * 
+   *
    * If null is returned, an error message has already been logged.
-   * 
+   *
+   * @param logger 
+   * @param keyGenerator 
+   * @param method 
+   * @param isConstants 
    * @return null if unable to get or compute the key for this method, otherwise
    *         the key is returned
    */
@@ -141,6 +169,10 @@
     if (meaning != null) {
       meaningString = meaning.value();
     }
+    if (keyGenerator == null) {
+      // Gracefully handle the case of an invalid KeyGenerator classname
+      return null;
+    }
     String keyStr = keyGenerator.generateKey(
         method.getEnclosingType().getQualifiedSourceName(), method.getName(),
         text, meaningString);
@@ -165,7 +197,9 @@
   /**
    * Returns a suitable key generator for the specified class.
    * 
-   * @throws AnnotationsError
+   * @param targetClass 
+   * @return KeyGenerator instance, guaranteed to not be null 
+   * @throws AnnotationsError if a specified KeyGenerator cannot be created
    */
   public static KeyGenerator getKeyGenerator(JClassType targetClass)
       throws AnnotationsError {
diff --git a/user/src/com/google/gwt/i18n/rebind/ResourceFactory.java b/user/src/com/google/gwt/i18n/rebind/ResourceFactory.java
index 3433a40..f95c0fa 100644
--- a/user/src/com/google/gwt/i18n/rebind/ResourceFactory.java
+++ b/user/src/com/google/gwt/i18n/rebind/ResourceFactory.java
@@ -15,18 +15,20 @@
  */
 package com.google.gwt.i18n.rebind;
 
+import static com.google.gwt.i18n.rebind.AnnotationUtil.getClassAnnotation;
+
 import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.dev.util.collect.IdentityHashSet;
 import com.google.gwt.i18n.client.LocalizableResource.DefaultLocale;
 import com.google.gwt.i18n.rebind.AbstractResource.ResourceList;
 import com.google.gwt.i18n.rebind.AnnotationsResource.AnnotationsError;
 import com.google.gwt.i18n.shared.GwtLocale;
+import com.google.gwt.i18n.shared.GwtLocaleFactory;
 
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -35,108 +37,63 @@
  * Creates resources.
  */
 public abstract class ResourceFactory {
-  static class SimplePathTree extends AbstractPathTree {
-    String path;
 
-    SimplePathTree(String path) {
-      this.path = path;
-    }
-
-    @Override
-    public AbstractPathTree getChild(int i) {
-      throw new UnsupportedOperationException(
-          "Simple paths have no children, therefore cannot get child: " + i);
-    }
-
-    @Override
-    public String getPath() {
-      return path;
-    }
-
-    @Override
-    public int numChildren() {
-      return 0;
-    }
-  }
-
-  private abstract static class AbstractPathTree {
-    abstract AbstractPathTree getChild(int i);
+  /**
+   * Pair of JClassType and GwtLocale.
+   */
+  private static class ClassLocale {
     
-    JClassType getJClassType(JClassType clazz) {
+    private final JClassType clazz;
+    private final GwtLocale locale;
+    
+    public ClassLocale(JClassType clazz, GwtLocale locale) {
+      assert clazz != null;
+      assert locale != null;
+      this.clazz = clazz;
+      this.locale = locale;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) {
+        return true;
+      }
+      if (obj == null || getClass() != obj.getClass()) {
+        return false;
+      }
+      ClassLocale other = (ClassLocale) obj;
+      return clazz.equals(other.clazz) && locale.equals(other.locale); 
+    }
+
+    public JClassType getJClass() {
       return clazz;
     }
 
-    abstract String getPath();
-
-    abstract int numChildren();
-  }
-
-  private static class ClassPathTree extends AbstractPathTree {
-    Class<?> javaInterface;
-
-    ClassPathTree(Class<?> javaInterface) {
-      this.javaInterface = javaInterface;
+    public GwtLocale getLocale() {
+      return locale;
     }
 
     @Override
-    AbstractPathTree getChild(int i) {
-      // we expect to do this at most once, so no caching is used.
-      return new ClassPathTree(javaInterface.getInterfaces()[i]);
-    }
-
-    @Override
-    String getPath() {
-      return javaInterface.getName();
-    }
-
-    @Override
-    int numChildren() {
-      return javaInterface.getInterfaces().length;
-    }
-  }
-
-  private static class JClassTypePathTree extends AbstractPathTree {
-    JClassType javaInterface;
-
-    JClassTypePathTree(JClassType javaInterface) {
-      this.javaInterface = javaInterface;
-    }
-
-    @Override
-    AbstractPathTree getChild(int i) {
-      // we expect to do this at most once, so no caching is used.
-      return new JClassTypePathTree(javaInterface.getImplementedInterfaces()[i]);
-    }
-
-    @Override
-    JClassType getJClassType(JClassType clazz) {
-      return javaInterface;
+    public int hashCode() {
+      return clazz.hashCode() + locale.hashCode() * 53;
     }
     
-    /**
-     * Path is equivalent to javaInterface.getQualifiedName() except for inner
-     * classes.
-     * 
-     * @see com.google.gwt.i18n.rebind.ResourceFactory.AbstractPathTree#getPath()
-     */
     @Override
-    String getPath() {
-      String name = getResourceName(javaInterface);
-      String packageName = javaInterface.getPackage().getName();
-      return packageName + "." + name;
-    }
-
-    @Override
-    int numChildren() {
-      return javaInterface.getImplementedInterfaces().length;
+    public String toString() {
+      return clazz.getQualifiedSourceName() + "/" + locale.toString();
     }
   }
 
+  /**
+   * Separator between class name and locale in resource files.  Should not
+   * appear in valid localizable class names.
+   */
   public static final char LOCALE_SEPARATOR = '_';
 
-  private static Map<String, ResourceList> cache = new HashMap<String, ResourceList>();
-
+  private static Map<ClassLocale, ResourceList> cache = new HashMap<
+      ClassLocale, ResourceList>();
   private static List<ResourceFactory> loaders = new ArrayList<ResourceFactory>();
+
   static {
     loaders.add(new LocalizedPropertiesResource.Factory());
   }
@@ -148,59 +105,56 @@
     cache.clear();
   }
 
-  public static ResourceList getBundle(Class<?> clazz, GwtLocale locale,
-      boolean isConstants) {
-    assert locale != null;
-    return getBundle(TreeLogger.NULL, clazz, locale, isConstants);
-  }
-
-  public static ResourceList getBundle(String path, GwtLocale locale,
-      boolean isConstants) {
-    assert locale != null;
-    return getBundle(TreeLogger.NULL, path, locale, isConstants);
-  }
-
   /**
-   * Gets the resource associated with the given interface.
    * 
-   * @param javaInterface interface
-   * @param locale locale name
-   * @return the resource
+   * @param logger
+   * @param topClass
+   * @param bundleLocale
+   * @param isConstants
+   * @return resource list
    */
-  public static ResourceList getBundle(TreeLogger logger, Class<?> javaInterface,
-      GwtLocale locale, boolean isConstants) {
-    if (javaInterface.isInterface() == false) {
-      throw new IllegalArgumentException(javaInterface
-          + " should be an interface.");
+  public static ResourceList getBundle(TreeLogger logger, JClassType topClass,
+      GwtLocale bundleLocale, boolean isConstants) {
+    List<GwtLocale> locales = bundleLocale.getCompleteSearchList();
+    List<JClassType> classes = new ArrayList<JClassType>();
+    Set<JClassType> seenClasses = new IdentityHashSet<JClassType>();
+    Map<ClassLocale, AnnotationsResource> annotations = new HashMap<ClassLocale,
+        AnnotationsResource>();
+    GwtLocaleFactory factory = LocaleUtils.getLocaleFactory();
+    GwtLocale defaultLocale = factory.getDefault();
+    walkInheritanceTree(logger, topClass, factory, defaultLocale, classes,
+        annotations, seenClasses, isConstants);
+    // TODO(jat): handle explicit subinterface with other locales -- ie:
+    //   public interface Foo_es_MX extends Foo { ... }
+    ResourceList allResources = new ResourceList();
+    for (GwtLocale locale : locales) {
+      for (JClassType clazz : classes) {
+        ClassLocale key = new ClassLocale(clazz, locale);
+        ResourceList resources;
+        if (cache.containsKey(key)) {
+          resources = cache.get(key);
+        } else {
+          cache.put(key, null);
+          resources = new ResourceList();
+          addFileResources(clazz, locale, resources);
+          AnnotationsResource annotationsResource = annotations.get(key);
+          if (annotationsResource != null) {
+            resources.add(annotationsResource);
+          }
+          cache.put(key, resources);
+        }
+        if (resources != null) {
+          allResources.addAll(resources);
+        }
+      }
     }
-    ClassPathTree path = new ClassPathTree(javaInterface);
-    return getBundleAux(logger, path, null, locale, true, isConstants);
-  }
-
-  /**
-   * Gets the resource associated with the given interface.
-   * 
-   * @param javaInterface interface
-   * @param locale locale name
-   * @return the resource
-   */
-  public static ResourceList getBundle(TreeLogger logger,
-      JClassType javaInterface, GwtLocale locale, boolean isConstants) {
-    return getBundleAux(logger, new JClassTypePathTree(javaInterface),
-        javaInterface, locale, true, isConstants);
-  }
-
-  /**
-   * Gets the resource associated with the given path.
-   * 
-   * @param path the path
-   * @param locale locale name
-   * @return the resource
-   */
-  public static ResourceList getBundle(TreeLogger logger, String path,
-      GwtLocale locale, boolean isConstants) {
-    return getBundleAux(logger, new SimplePathTree(path), null, locale, true,
-        isConstants);
+    String className = topClass.getQualifiedSourceName();
+    TreeLogger branch = logger.branch(TreeLogger.SPAM,
+        "Resource search order for " + className + ", locale " + bundleLocale);
+    for (AbstractResource resource : allResources) {
+      branch.log(TreeLogger.SPAM, resource.toString());
+    }
+    return allResources;
   }
 
   public static String getResourceName(JClassType targetClass) {
@@ -211,74 +165,17 @@
     return name;
   }
 
-  private static void addAlternativeParents(TreeLogger logger,
-      ResourceFactory.AbstractPathTree tree, JClassType clazz, GwtLocale locale,
-      boolean useAlternativeParents, boolean isConstants,
-      ResourceList resources, Set<String> seenPaths) {
-    if (tree != null) {
-      for (int i = 0; i < tree.numChildren(); i++) {
-        ResourceFactory.AbstractPathTree child = tree.getChild(i);
-        addResources(logger, child, child.getJClassType(clazz),
-            locale, useAlternativeParents, isConstants, resources, seenPaths);
-      }
-    }
-  }
-
-  private static void addPrimaryParent(TreeLogger logger,
-      ResourceFactory.AbstractPathTree tree, JClassType clazz, GwtLocale locale,
-      boolean isConstants, ResourceList resources, Set<String> seenPaths) {
-    for (GwtLocale search : locale.getCompleteSearchList()) {
-      // This relies on addResources exiting if it has seen a given path
-      // (derived from the locale) to avoid infinite loops, since the search
-      // list includes this locale as well as aliases which will refer back
-      // to this locale.
-      addResources(logger, tree, clazz, search, false, isConstants, resources,
-          seenPaths);
-    }
-  }
-
-  private static void addResources(TreeLogger logger,
-      ResourceFactory.AbstractPathTree tree, JClassType clazz, GwtLocale locale,
-      boolean useAlternateParents, boolean isConstants,
-      ResourceList resources, Set<String> seenPaths) {
-    String targetPath = tree.getPath();
+  private static void addFileResources(JClassType clazz, GwtLocale locale,
+      ResourceList resources) {
+    // TODO: handle classes in the default package?
+    String targetPath = clazz.getPackage().getName() + '.'
+        + getResourceName(clazz);
     String localizedPath = targetPath;
     if (!locale.isDefault()) {
       localizedPath = targetPath + LOCALE_SEPARATOR + locale.getAsString();
     }
-    if (seenPaths.contains(localizedPath)) {
-      return;
-    }
-    seenPaths.add(localizedPath);
-    ClassLoader loader = AbstractResource.class.getClassLoader();
-    Map<String, JClassType> matchingClasses = null;
-    if (clazz != null) {
-      try {
-        matchingClasses = LocalizableLinkageCreator.findDerivedClasses(logger,
-            clazz);
-        /* 
-         * In this case, we specifically want to be able to look at the interface
-         * instead of just implementations.
-         */
-        String defLocaleValue = DefaultLocale.DEFAULT_LOCALE;
-        DefaultLocale defLocale = clazz.getAnnotation(DefaultLocale.class);
-        if (defLocale != null) {
-          defLocaleValue = defLocale.value();
-          if (!GwtLocale.DEFAULT_LOCALE.equals(defLocaleValue)) {
-            matchingClasses.put(defLocaleValue, clazz);
-          }
-        }
-        matchingClasses.put(GwtLocale.DEFAULT_LOCALE, clazz);
-      } catch (UnableToCompleteException e) {
-        // ignore error, fall through
-      }
-    }
-    if (matchingClasses == null) {
-      // empty map
-      matchingClasses = new HashMap<String, JClassType>();
-    }
-
     // Check for file-based resources.
+    ClassLoader loader = ResourceFactory.class.getClassLoader();
     String partialPath = localizedPath.replace('.', '/');
     for (int i = 0; i < loaders.size(); i++) {
       ResourceFactory element = loaders.get(i);
@@ -297,56 +194,59 @@
         resources.add(found);
       }
     }
-
-    // Check for annotations
-    JClassType currentClass = matchingClasses.get(locale.toString());
-    if (currentClass != null) {
-      AnnotationsResource resource;
-      try {
-        resource = new AnnotationsResource(logger, currentClass, locale,
-            isConstants);
-        if (resource.notEmpty()) {
-          resource.setPath(currentClass.getQualifiedSourceName());
-          resources.add(resource);
-        }
-      } catch (AnnotationsError e) {
-        logger.log(TreeLogger.ERROR, e.getMessage(), e);
-      }
-    }
-    
-    // Add our parent, if any
-    addPrimaryParent(logger, tree, clazz, locale, isConstants, resources,
-        seenPaths);
-
-    // Add our alternate parents
-    if (useAlternateParents) {
-      addAlternativeParents(logger, tree, clazz, locale, useAlternateParents,
-          isConstants, resources, seenPaths);
-    }
   }
 
-  private static ResourceList getBundleAux(TreeLogger logger,
-      ResourceFactory.AbstractPathTree tree, JClassType clazz, GwtLocale locale,
-      boolean required, boolean isConstants) {
-    String cacheKey = tree.getPath() + "_" + locale.getAsString();
-    if (cache.containsKey(cacheKey)) {
-      return cache.get(cacheKey);
+  private static void walkInheritanceTree(TreeLogger logger, JClassType clazz,
+      GwtLocaleFactory factory, GwtLocale defaultLocale,
+      List<JClassType> classes,
+      Map<ClassLocale, AnnotationsResource> annotations,
+      Set<JClassType> seenClasses, boolean isConstants) {
+    if (seenClasses.contains(clazz)) {
+      return;
     }
-    Set<String> seenPaths = new HashSet<String>();
-    final ResourceList resources = new ResourceList();
-    addResources(logger, tree, clazz, locale, true, isConstants, resources,
-        seenPaths);
-    String className = tree.getPath();
-    if (clazz != null) {
-      className = clazz.getQualifiedSourceName();
+    seenClasses.add(clazz);
+    classes.add(clazz);
+    AnnotationsResource resource;
+    try {
+      resource = new AnnotationsResource(logger, clazz, defaultLocale,
+          isConstants);
+      if (resource.notEmpty()) {
+        resource.setPath(clazz.getQualifiedSourceName());
+        ClassLocale key = new ClassLocale(clazz, defaultLocale);
+        annotations.put(key, resource);
+        String defLocaleValue = null;
+        
+        // If the class has an embedded locale in it, use that for the default
+        String className = clazz.getSimpleSourceName();
+        int underscore = className.indexOf('_');
+        if (underscore >= 0) {
+          defLocaleValue = className.substring(underscore + 1);
+        }
+        
+        // If there is an annotation declaring the default locale, use that
+        DefaultLocale defLocaleAnnot = getClassAnnotation(clazz,
+            DefaultLocale.class);
+        if (defLocaleAnnot != null) {
+          defLocaleValue = defLocaleAnnot.value();
+        }
+        GwtLocale defLocale = LocaleUtils.getLocaleFactory().fromString(
+            defLocaleValue);
+        if (!defLocale.isDefault()) {
+          key = new ClassLocale(clazz, defLocale);
+          annotations.put(key, resource);
+        }
+      }
+    } catch (AnnotationsError e) {
+      logger.log(TreeLogger.ERROR, e.getMessage(), e);
     }
-    TreeLogger branch = logger.branch(TreeLogger.SPAM, "Resource search order for "
-        + className + ", locale " + locale);
-    for (AbstractResource resource : resources) {
-      branch.log(TreeLogger.SPAM, resource.toString());
+    if (clazz.getSuperclass() != null) {
+      walkInheritanceTree(logger, clazz.getSuperclass(), factory, defaultLocale,
+          classes, annotations, seenClasses, isConstants);
     }
-    cache.put(cacheKey, resources);
-    return resources;
+    for (JClassType intf : clazz.getImplementedInterfaces()) {
+      walkInheritanceTree(logger, intf, factory, defaultLocale, classes,
+          annotations, seenClasses, isConstants);
+    }   
   }
 
   abstract String getExt();
diff --git a/user/src/com/google/gwt/i18n/server/GwtLocaleImpl.java b/user/src/com/google/gwt/i18n/server/GwtLocaleImpl.java
index 01a89ca..ab35784 100644
--- a/user/src/com/google/gwt/i18n/server/GwtLocaleImpl.java
+++ b/user/src/com/google/gwt/i18n/server/GwtLocaleImpl.java
@@ -440,7 +440,9 @@
         }
         thisGroup = nextGroup;
       }
-      cachedSearchList.add(defLocale);
+      if (!isDefault()) {
+        cachedSearchList.add(defLocale);
+      }
     }
     return cachedSearchList;
   }
diff --git a/user/test/com/google/gwt/i18n/I18NSuite.java b/user/test/com/google/gwt/i18n/I18NSuite.java
index 9f4a44e..d98dc12 100644
--- a/user/test/com/google/gwt/i18n/I18NSuite.java
+++ b/user/test/com/google/gwt/i18n/I18NSuite.java
@@ -37,7 +37,6 @@
 import com.google.gwt.i18n.client.RuntimeLocalesTest;
 import com.google.gwt.i18n.client.TimeZoneInfoTest;
 import com.google.gwt.i18n.client.TimeZoneTest;
-import com.google.gwt.i18n.rebind.AbstractResourceTest;
 import com.google.gwt.i18n.rebind.MessageFormatParserTest;
 import com.google.gwt.i18n.server.GwtLocaleTest;
 import com.google.gwt.i18n.server.RegionInheritanceTest;
@@ -53,7 +52,6 @@
     GWTTestSuite suite = new GWTTestSuite("All I18N tests");
 
     // $JUnit-BEGIN$
-    suite.addTestSuite(AbstractResourceTest.class);
     suite.addTestSuite(ArabicPluralsTest.class);
     suite.addTestSuite(AnnotationsTest.class);
     suite.addTestSuite(ConstantMapTest.class);
diff --git a/user/test/com/google/gwt/i18n/client/I18NTest.java b/user/test/com/google/gwt/i18n/client/I18NTest.java
index c75631a..48d6f3a 100644
--- a/user/test/com/google/gwt/i18n/client/I18NTest.java
+++ b/user/test/com/google/gwt/i18n/client/I18NTest.java
@@ -148,6 +148,13 @@
     // No piglatin version exists for grey
     assertEquals("ĝréý", colors.grey());
     assertEquals("ackblay", colors.black());
+    assertEquals("ueblay", colors.blue());
+  }
+
+  public void testColorsAndShapes() {
+    ColorsAndShapes s = GWT.create(ColorsAndShapes.class);
+    assertEquals("ueblay", s.blue());
+    assertEquals("ĝréý", s.grey());
   }
 
   public void testConstantBooleans() {
@@ -561,6 +568,7 @@
     // test converge
     assertEquals("any primary color", s.shapeColor());
     assertEquals("trees", s.green());
+    assertEquals("Îñţérñåţîöñåļîžåţîöñ", s.internationalization());
   }
 
   public void testTestMessages() {
diff --git a/user/test/com/google/gwt/i18n/rebind/AbstractResourceTest.java b/user/test/com/google/gwt/i18n/rebind/AbstractResourceTest.java
deleted file mode 100644
index f3fea7e..0000000
--- a/user/test/com/google/gwt/i18n/rebind/AbstractResourceTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2008 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.i18n.rebind;
-
-import com.google.gwt.i18n.client.ColorsAndShapes;
-import com.google.gwt.i18n.client.ColorsAndShapesAndConcepts;
-import com.google.gwt.i18n.client.gen.Colors;
-import com.google.gwt.i18n.rebind.AbstractResource.ResourceList;
-import com.google.gwt.i18n.shared.GwtLocale;
-
-import junit.framework.TestCase;
-
-import java.io.ByteArrayOutputStream;
-import java.io.CharArrayWriter;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-
-/**
- * TODO: document me.
- */
-public class AbstractResourceTest extends TestCase {
-  public static final String UNICODE = "Îñţérñåţîöñåļîžåţîöñ";
-  private static final GwtLocale LOCALE_NAME_PIGLATIN = LocaleUtils.getLocaleFactory().fromString("piglatin");
-  private static final GwtLocale LOCALE_NAME_PIGLATIN_UK = LocaleUtils.getLocaleFactory().fromString("piglatin_UK");
-  private static final GwtLocale LOCALE_DEFAULT = LocaleUtils.getLocaleFactory().getDefault();
-
-  public void testBundle() {
-    // simple test
-    String s = Colors.class.getName();
-    ResourceList resourceList = ResourceFactory.getBundle(s, LOCALE_DEFAULT, true);
-    assertNotNull(resourceList);
-    ResourceList pigLatinResourceList =
-        ResourceFactory.getBundle(s, LOCALE_NAME_PIGLATIN, true);
-    assertNotNull(pigLatinResourceList);
-    assertEquals("ueblay", pigLatinResourceList.getString("blue"));
-    assertEquals("ĝréý", pigLatinResourceList.getString("grey"));
-  }
-
-  public void testInheritence() {
-    ResourceFactory.clearCache();
-    ResourceList resourceList = ResourceFactory.getBundle(
-      ColorsAndShapes.class, LOCALE_NAME_PIGLATIN, true);
-    assertEquals("ueblay", resourceList.getString("blue"));
-    assertEquals("ĝréý", resourceList.getString("grey"));
-  }
-
-  public void testByteStreamBehavior() throws UnsupportedEncodingException {
-    ByteArrayOutputStream s = new ByteArrayOutputStream();
-    OutputStreamWriter writer = new OutputStreamWriter(s, "UTF-8");
-    PrintWriter t = new PrintWriter(writer, true);
-    t.print("ĝréý");
-    t.close();
-    assertEquals("ĝréý", s.toString("UTF-8"));
-    assertEquals("ĝréý", (new String(s.toString("UTF-8").toCharArray())));
-  }
-
-  public void testDoubleInherits() {
-    ResourceList resourceList = ResourceFactory.getBundle(
-      ColorsAndShapesAndConcepts.class, LOCALE_NAME_PIGLATIN_UK, true);
-    String s = resourceList.getString("internationalization");
-    assertEquals("Îñţérñåţîöñåļîžåţîöñ", s);
-    assertTrue(resourceList.keySet().size() > 5);
-  }
-
-  public void testCharArrayBehavior() {
-    CharArrayWriter s = new CharArrayWriter();
-    PrintWriter t = new PrintWriter(s, true);
-    t.print(UNICODE);
-    t.close();
-    assertEquals(UNICODE, s.toString());
-  }
-}