FIX: LookupMethodCreator create too large method

Bug: #8611
Bug-Link: https://github.com/gwtproject/gwt/issues/8611
Change-Id: I6156581364a571621234b9c1d7fd597beaa27c7c
diff --git a/user/src/com/google/gwt/i18n/rebind/ConstantsWithLookupImplCreator.java b/user/src/com/google/gwt/i18n/rebind/ConstantsWithLookupImplCreator.java
index 89813c9..0a5de8b 100644
--- a/user/src/com/google/gwt/i18n/rebind/ConstantsWithLookupImplCreator.java
+++ b/user/src/com/google/gwt/i18n/rebind/ConstantsWithLookupImplCreator.java
@@ -25,17 +25,54 @@
 import com.google.gwt.core.ext.typeinfo.TypeOracleException;
 import com.google.gwt.i18n.rebind.AbstractResource.ResourceList;
 import com.google.gwt.i18n.shared.GwtLocale;
-import com.google.gwt.user.rebind.AbstractMethodCreator;
+import com.google.gwt.thirdparty.guava.common.collect.Lists;
 import com.google.gwt.user.rebind.SourceWriter;
 
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 class ConstantsWithLookupImplCreator extends ConstantsImplCreator {
+
+  /**
+   * Used partition size if no one is specified.
+   * 
+   * Used in constructor without a partition size.
+   */
+  private static final int DEFAULT_PARTITIONS_SIZE = 500;
+  
   final JMethod[] allInterfaceMethods;
 
-  private final Map<String, AbstractMethodCreator> namesToMethodCreators = new HashMap<String, AbstractMethodCreator>();
+  private final Map<String, LookupMethodCreator> namesToMethodCreators = new HashMap<>();
+  
+  private final Map<JMethod, List<List<JMethod>>> neededPartitionLookups = new HashMap<>();
 
+  private final int partitionsSize;
+
+  /**
+   * Constructor for <code>ConstantsWithLookupImplCreator</code>. The default partition size of
+   * {@value #DEFAULT_PARTITIONS_SIZE} is used.
+   * 
+   * @param logger logger to print errors
+   * @param writer <code>Writer</code> to print to
+   * @param localizableClass class/interface to conform to
+   * @param resourceList resource bundle used to generate the class
+   * @param oracle types
+   * @throws UnableToCompleteException
+   * 
+   * @see LookupMethodCreator#DEFAULT_PARTITIONS_SIZE
+   */
+  ConstantsWithLookupImplCreator(TreeLogger logger, SourceWriter writer,
+      JClassType localizableClass, ResourceList resourceList, TypeOracle oracle)
+      throws UnableToCompleteException {
+    this(logger, writer, localizableClass, resourceList, oracle, DEFAULT_PARTITIONS_SIZE);
+  }
+  
   /**
    * Constructor for <code>ConstantsWithLookupImplCreator</code>.
    * 
@@ -47,9 +84,10 @@
    * @throws UnableToCompleteException
    */
   ConstantsWithLookupImplCreator(TreeLogger logger, SourceWriter writer,
-      JClassType localizableClass, ResourceList resourceList, TypeOracle oracle)
-      throws UnableToCompleteException {
+      JClassType localizableClass, ResourceList resourceList, TypeOracle oracle, 
+      int partitionsSize) throws UnableToCompleteException {
     super(logger, writer, localizableClass, resourceList, oracle);
+    this.partitionsSize = partitionsSize;
     try {
 
       // Boolean
@@ -63,7 +101,9 @@
 
         @Override
         public String returnTemplate() {
-          return "boolean answer = {0}();\ncache.put(\"{0}\",new Boolean(answer));\nreturn answer;";
+          return "boolean answer = {0}();\n"
+              + "cache.put(\"{0}\",new Boolean(answer));\n"
+              + "return answer;";
         }
       };
       namesToMethodCreators.put("getBoolean", booleanMethod);
@@ -79,7 +119,9 @@
 
         @Override
         public String returnTemplate() {
-          return "double answer = {0}();\ncache.put(\"{0}\",new Double(answer));\nreturn answer;";
+          return "double answer = {0}();\n"
+              + "cache.put(\"{0}\",new Double(answer));\n"
+              + "return answer;";
         }
       };
       namesToMethodCreators.put("getDouble", doubleMethod);
@@ -94,7 +136,9 @@
 
         @Override
         public String returnTemplate() {
-          return "int answer = {0}();\ncache.put(\"{0}\",new Integer(answer));\nreturn answer;";
+          return "int answer = {0}();\n"
+              + "cache.put(\"{0}\",new Integer(answer));\n"
+              + "return answer;";
         }
       };
 
@@ -105,7 +149,9 @@
       LookupMethodCreator floatMethod = new LookupMethodCreator(this, floatType) {
         @Override
         public String returnTemplate() {
-          String val = "float answer = {0}();\ncache.put(\"{0}\", new Float(answer));\nreturn answer;";
+          String val = "float answer = {0}();\n"
+              + "cache.put(\"{0}\", new Float(answer));\n"
+              + "return answer;";
           return val;
         }
 
@@ -132,7 +178,9 @@
           stringType) {
         @Override
         public String returnTemplate() {
-          return "String answer = {0}();\ncache.put(\"{0}\",answer);\nreturn answer;";
+          return "String answer = {0}();\n"
+              + "cache.put(\"{0}\",answer);\n"
+              + "return answer;";
         }
       };
       namesToMethodCreators.put("getString", stringMethod);
@@ -149,6 +197,12 @@
     }
   }
 
+  @Override
+  protected void classEpilog() {
+    createNeededPartitionLookups();
+    super.classEpilog();
+  }
+
   /**
    * Create the method body associated with the given method. Arguments are
    * arg0...argN.
@@ -159,9 +213,9 @@
     checkMethod(logger, method);
     if (method.getParameters().length == 1) {
       String name = method.getName();
-      AbstractMethodCreator c = namesToMethodCreators.get(name);
+      LookupMethodCreator c = getLookupMethodCreator(name);
       if (c != null) {
-        c.createMethodFor(logger, method, name, null, locale);
+        createMethodWithPartitionCheckFor(c, method);
         return;
       }
     }
@@ -169,6 +223,68 @@
     super.emitMethodBody(logger, method, locale);
   }
 
+  void addNeededPartitionLookups(JMethod targetMethod,
+      List<List<JMethod>> methodToCreatePartitionLookups) {
+    neededPartitionLookups.put(targetMethod, methodToCreatePartitionLookups);
+  }
+
+  void createMethodWithPartitionCheckFor(LookupMethodCreator methodCreator, JMethod targetMethod) {
+    List<List<JMethod>> methodPartitions = findMethodsToCreateWithPartitionSize(targetMethod,
+        methodCreator.getReturnType());
+
+    String nextPartitionMethod = null;
+    final List<List<JMethod>> methodToCreatePartitionLookups;
+    final List<JMethod> methodsToCreate;
+    if (methodPartitions.size() > 1) {
+      nextPartitionMethod = createPartitionMethodName(targetMethod, 0);
+      methodsToCreate = methodPartitions.get(0);
+      methodToCreatePartitionLookups = methodPartitions.subList(1, methodPartitions.size());
+    } else {
+      methodsToCreate = methodPartitions.isEmpty() ? Collections.<JMethod> emptyList()
+          : methodPartitions.get(0);
+      methodToCreatePartitionLookups = Collections.emptyList();
+    }
+    addNeededPartitionLookups(targetMethod, methodToCreatePartitionLookups);
+    methodCreator.createCacheLookupFor();
+    methodCreator.createMethodFor(targetMethod, methodsToCreate, nextPartitionMethod);
+  }
+
+  String createPartitionMethodName(JMethod targetMethod, int partitionIndex) {
+    final String templatePartitionMethodName = "{0}FromPartition{1}";
+    return MessageFormat.format(templatePartitionMethodName, new Object[] {
+        targetMethod.getName(), partitionIndex});
+  }
+
+  List<JMethod> findAllMethodsToCreate(JMethod targetMethod, JType methodReturnType) {
+    JMethod[] allMethods = allInterfaceMethods;
+    JType erasedType = methodReturnType.getErasedType();
+    List<JMethod> methodsToCreate = new ArrayList<>();
+    for (JMethod methodToCheck : allMethods) {
+      if (methodToCheck.getReturnType().getErasedType().equals(erasedType)
+          && methodToCheck != targetMethod) {
+        methodsToCreate.add(methodToCheck);
+      }
+    }
+    return methodsToCreate;
+  }
+
+  List<List<JMethod>> findMethodsToCreateWithPartitionSize(JMethod targetMethod,
+      JType methodReturnType) {
+    List<JMethod> allMethodsToCreate = findAllMethodsToCreate(targetMethod, methodReturnType);
+    return Lists.partition(allMethodsToCreate, partitionsSize);
+  }
+
+  LookupMethodCreator getLookupMethodCreator(String name) {
+    return namesToMethodCreators.get(name);
+  }
+
+  /**
+   * Visible for testing only.
+   */
+  Map<JMethod, List<List<JMethod>>> getNeededPartitionLookups() {
+    return neededPartitionLookups;
+  }
+
   /**
    * Checks that the method has the right structure to implement
    * <code>Constant</code>.
@@ -177,7 +293,7 @@
    */
   private void checkMethod(TreeLogger logger, JMethod method)
       throws UnableToCompleteException {
-    if (namesToMethodCreators.get(method.getName()) != null) {
+    if (getLookupMethodCreator(method.getName()) != null) {
       JParameter[] params = method.getParameters();
       // user may have specified a method named getInt/etc with no parameters
       // this isn't a conflict, so treat them like any other Constant methods
@@ -195,4 +311,26 @@
       checkConstantMethod(logger, method);
     }
   }
+
+  private void createNeededPartitionLookups() {
+    for (Entry<JMethod, List<List<JMethod>>> neededPartitionLookup : 
+      neededPartitionLookups.entrySet()) {
+      JMethod targetMethod = neededPartitionLookup.getKey();
+      LookupMethodCreator lookupMethodCreator = getLookupMethodCreator(targetMethod.getName());
+      List<List<JMethod>> methodForPartitionLookups = neededPartitionLookup.getValue();
+      int partitionStartIndex = 0;
+      Iterator<List<JMethod>> neededPartitionIterator = methodForPartitionLookups.iterator();
+      while (neededPartitionIterator.hasNext()) {
+        String currentPartitionLookupMethodName = createPartitionMethodName(targetMethod,
+            partitionStartIndex++);
+        List<JMethod> methodsToCreate = neededPartitionIterator.next();
+        String nextPartitionMethod = null;
+        if (neededPartitionIterator.hasNext()) {
+          nextPartitionMethod = createPartitionMethodName(targetMethod, partitionStartIndex);
+        }
+        lookupMethodCreator.createPartitionLookup(currentPartitionLookupMethodName, targetMethod,
+            methodsToCreate, nextPartitionMethod);
+      }
+    }
+  }
 }
diff --git a/user/src/com/google/gwt/i18n/rebind/LookupMethodCreator.java b/user/src/com/google/gwt/i18n/rebind/LookupMethodCreator.java
index fed873c..6a4f29b 100644
--- a/user/src/com/google/gwt/i18n/rebind/LookupMethodCreator.java
+++ b/user/src/com/google/gwt/i18n/rebind/LookupMethodCreator.java
@@ -21,17 +21,18 @@
 import com.google.gwt.core.ext.typeinfo.JType;
 import com.google.gwt.i18n.rebind.AbstractResource.ResourceList;
 import com.google.gwt.i18n.shared.GwtLocale;
-import com.google.gwt.user.rebind.AbstractGeneratorClassCreator;
 import com.google.gwt.user.rebind.AbstractMethodCreator;
 import com.google.gwt.user.rebind.AbstractSourceCreator;
 
 import java.text.MessageFormat;
+import java.util.List;
 
 /**
  * Method creator to call the correct Map for the given Dictionary.
  */
 class LookupMethodCreator extends AbstractMethodCreator {
-  private JType returnType;
+
+  private final JType returnType;
 
   /**
    * Constructor for <code>LookupMethodCreator</code>.
@@ -39,18 +40,17 @@
    * @param classCreator parent class creator
    * @param returnType associated return type
    */
-  public LookupMethodCreator(AbstractGeneratorClassCreator classCreator,
-      JType returnType) {
+  public LookupMethodCreator(ConstantsWithLookupImplCreator classCreator, JType returnType) {
     super(classCreator);
     this.returnType = returnType;
   }
 
   @Override
-  public void createMethodFor(TreeLogger logger, JMethod targetMethod,
-      String key, ResourceList resourceList, GwtLocale locale) {
-    createMethodFor(targetMethod);
+  public void createMethodFor(TreeLogger logger, JMethod targetMethod, String key,
+      ResourceList resourceList, GwtLocale locale) {
+    getConstantsWithLookupCreator().createMethodWithPartitionCheckFor(this, targetMethod);
   }
-
+  
   /**
    * Returns a {@code String} containing the return type name.
    */
@@ -65,7 +65,7 @@
     return type;
   }
 
-  void createMethodFor(JMethod targetMethod) {
+  void createCacheLookupFor() {
     String template = "{0} target = ({0}) cache.get(arg0);";
     String returnTypeName = getReturnTypeName();
     String lookup = MessageFormat.format(template, new Object[] {returnTypeName});
@@ -75,27 +75,64 @@
     printReturnTarget();
     outdent();
     println("}");
-    JMethod[] methods = ((ConstantsWithLookupImplCreator) currentCreator).allInterfaceMethods;
-    JType erasedType = returnType.getErasedType();
-    for (int i = 0; i < methods.length; i++) {
-      if (methods[i].getReturnType().getErasedType().equals(erasedType)
-          && methods[i] != targetMethod) {
-        String methodName = methods[i].getName();
-        String body = "if(arg0.equals(" + wrap(methodName) + ")) {";
-        println(body);
-        indent();
-        printFound(methodName);
-        outdent();
-        println("}");
-      }
+  }
+
+  /**
+   * 
+   * @param targetMethod the method to create the lookups for
+   * @param methodsToCreate the looked up methods
+   * @param nextPartitionMethod the name of next method is called or null if end this generated
+   *          method with throwing an exception
+   */
+  void createMethodFor(JMethod targetMethod, List<JMethod> methodsToCreate,
+      String nextPartitionMethod) {
+    createMethodLookups(methodsToCreate);
+    final String result;
+    boolean isLastPartition = nextPartitionMethod == null;
+    if (isLastPartition) {
+      result = createThrowMissingResourceException();
+    } else {
+      String callPartitionMethodTemplate = "return {0}(arg0);";
+      result = MessageFormat.format(callPartitionMethodTemplate, new Object[] {
+          nextPartitionMethod});
     }
-    String format = "throw new java.util.MissingResourceException(\"Cannot find constant ''\" +"
-        + "{0} + \"''; expecting a method name\", \"{1}\", {0});";
-    String result = MessageFormat.format(format, "arg0",
-        this.currentCreator.getTarget().getQualifiedSourceName());
     println(result);
   }
 
+  void createMethodLookups(List<JMethod> methodsToCreate) {
+    for (JMethod methodToCreate : methodsToCreate) {
+      String methodName = methodToCreate.getName();
+      String body = "if (arg0.equals(" + wrap(methodName) + ")) {";
+      println(body);
+      indent();
+      printFound(methodName);
+      outdent();
+      println("}");
+    }
+  }
+
+  void createPartitionLookup(String partitionMethodName, JMethod targetMethod,
+      List<JMethod> methodsToCreate, String nextPartitionMethod) {
+    println("");
+    final String templatePartitionMethodName = "private {0} {1}({2} arg0) '{";
+    final String argument0Type = targetMethod.getParameterTypes()[0].getQualifiedSourceName();
+    String partitionMethodSignature = MessageFormat.format(templatePartitionMethodName,
+        new Object[] {getReturnTypeName(), partitionMethodName, argument0Type});
+    println(partitionMethodSignature);
+    indent();
+    createMethodFor(targetMethod, methodsToCreate, nextPartitionMethod);
+    outdent();
+    println("}");
+  }
+  
+  ConstantsWithLookupImplCreator getConstantsWithLookupCreator() {
+    return ((ConstantsWithLookupImplCreator) currentCreator);
+  }
+
+  JType getReturnType() {
+    return returnType;
+  }
+
   void printFound(String methodName) {
     println(MessageFormat.format(returnTemplate(), new Object[] {methodName}));
   }
@@ -107,4 +144,13 @@
   String returnTemplate() {
     return "return {0}();";
   }
+
+  private String createThrowMissingResourceException() {
+    final String result;
+    String format = "throw new java.util.MissingResourceException(\"Cannot find constant ''\" +"
+        + "{0} + \"''; expecting a method name\", \"{1}\", {0});";
+    result = MessageFormat.format(format, "arg0", this.currentCreator.getTarget()
+        .getQualifiedSourceName());
+    return result;
+  }
 }
diff --git a/user/src/com/google/gwt/user/rebind/AbstractGeneratorClassCreator.java b/user/src/com/google/gwt/user/rebind/AbstractGeneratorClassCreator.java
index a77c502..fe18ed4 100644
--- a/user/src/com/google/gwt/user/rebind/AbstractGeneratorClassCreator.java
+++ b/user/src/com/google/gwt/user/rebind/AbstractGeneratorClassCreator.java
@@ -45,7 +45,7 @@
    * @return interface methods.
    */
   public static JMethod[] getAllInterfaceMethods(JClassType type) {
-    Map<String, JMethod> methods = new LinkedHashMap<String, JMethod>();
+    Map<String, JMethod> methods = new LinkedHashMap<>();
     getAllInterfaceMethodsAux(type, methods);
     return methods.values().toArray(new JMethod[methods.size()]);
   }
diff --git a/user/src/com/google/gwt/user/rebind/AbstractSourceCreator.java b/user/src/com/google/gwt/user/rebind/AbstractSourceCreator.java
index 5f5e31f..6939704 100644
--- a/user/src/com/google/gwt/user/rebind/AbstractSourceCreator.java
+++ b/user/src/com/google/gwt/user/rebind/AbstractSourceCreator.java
@@ -82,6 +82,8 @@
   protected static String getJavaObjectTypeFor(JPrimitiveType type) {
     if (type == JPrimitiveType.INT) {
       return "Integer";
+    } else if (type == JPrimitiveType.CHAR) {
+      return "Character";
     } else {
       String s = type.getSimpleSourceName();
       return s.substring(0, 1).toUpperCase(Locale.ROOT) + s.substring(1);
diff --git a/user/test/com/google/gwt/i18n/I18NJreSuite.java b/user/test/com/google/gwt/i18n/I18NJreSuite.java
index cf5d875..970373c 100644
--- a/user/test/com/google/gwt/i18n/I18NJreSuite.java
+++ b/user/test/com/google/gwt/i18n/I18NJreSuite.java
@@ -15,8 +15,10 @@
  */
 package com.google.gwt.i18n;
 
+import com.google.gwt.i18n.rebind.ConstantsWithLookupImplCreatorTest;
 import com.google.gwt.i18n.rebind.LocaleUtilsTest;
 import com.google.gwt.i18n.rebind.LocalizableGeneratorTest;
+import com.google.gwt.i18n.rebind.LookupMethodCreatorTest;
 import com.google.gwt.i18n.server.GwtLocaleTest;
 import com.google.gwt.i18n.server.MessageFormatParserTest;
 import com.google.gwt.i18n.server.PropertyCatalogFactoryTest;
@@ -59,6 +61,8 @@
      */
     // suite.addTestSuite(TypeOracleMessageTest.class);
     suite.addTestSuite(WordCountDirectionEstimatorTest.class);
+    suite.addTestSuite(LookupMethodCreatorTest.class);
+    suite.addTestSuite(ConstantsWithLookupImplCreatorTest.class);
     // $JUnit-END$
 
     return suite;
diff --git a/user/test/com/google/gwt/i18n/rebind/ConstantsWithLookupImplCreatorTest.java b/user/test/com/google/gwt/i18n/rebind/ConstantsWithLookupImplCreatorTest.java
new file mode 100644
index 0000000..c1e8d03
--- /dev/null
+++ b/user/test/com/google/gwt/i18n/rebind/ConstantsWithLookupImplCreatorTest.java
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2017 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.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JMethod;
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.core.ext.typeinfo.TypeOracleException;
+import com.google.gwt.dev.javac.TypeOracleTestingUtils;
+import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
+import com.google.gwt.dev.shell.FailErrorLogger;
+import com.google.gwt.i18n.rebind.AbstractResource.ResourceList;
+import com.google.gwt.i18n.server.GwtLocaleFactoryImpl;
+import com.google.gwt.i18n.shared.GwtLocale;
+import com.google.gwt.i18n.shared.GwtLocaleFactory;
+import com.google.gwt.user.rebind.SourceWriter;
+import com.google.gwt.user.rebind.StringSourceWriter;
+
+import junit.framework.TestCase;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Tests for {@link ConstantsWithLookupImplCreator}.
+ */
+public class ConstantsWithLookupImplCreatorTest extends TestCase {
+
+  private static final int TEST_PARTITION_SIZE = 3;
+
+  private static final MockJavaResource SINGLE_ENTRY_MESSAGES = new MockJavaResource(
+      "foo.SingleEntryMessage") {
+    @Override
+    public CharSequence getContent() {
+      StringBuffer code = new StringBuffer();
+      code.append("package foo;\n");
+      code.append("public interface SingleEntryMessage extends foo.Lookup {\n");
+      code.append(" String stringEntry();\n");
+      code.append(" int intEntry();\n");
+      code.append("}");
+      return code;
+    }
+  };
+
+  private static final MockJavaResource FOUR_ENTRY_MESSAGES = new MockJavaResource(
+      "foo.FourEntryMessage") {
+    @Override
+    public CharSequence getContent() {
+      StringBuffer code = new StringBuffer();
+      code.append("package foo;\n");
+      code.append("public interface FourEntryMessage extends foo.Lookup {\n");
+      code.append(" String first();\n");
+      code.append(" String second();\n");
+      code.append(" String third();\n");
+      code.append(" String fourth();\n");
+      code.append("}");
+      return code;
+    }
+  };
+  private static final MockJavaResource PARTITION_SIZE_ENTRY_MESSAGES = new MockJavaResource(
+      "foo.PartitionSizeEntryMessage") {
+    @Override
+    public CharSequence getContent() {
+      StringBuffer code = new StringBuffer();
+      code.append("package foo;\n");
+      code.append("public interface PartitionSizeEntryMessage extends foo.Lookup {\n");
+      for (int i = 1; i <= TEST_PARTITION_SIZE; i++) {
+        code.append(" String lookupMethod");
+        code.append(i);
+        code.append("();\n");
+      }
+      code.append("}");
+      return code;
+    }
+  };
+
+  private static final MockJavaResource LOOKUP = new MockJavaResource("foo.Lookup") {
+    @Override
+    public CharSequence getContent() {
+      StringBuffer code = new StringBuffer();
+      code.append("package foo;\n");
+      code.append("public interface Lookup {\n");
+      code.append(" String getString(String arg0);\n");
+      code.append(" int getInt(String arg0);\n");
+      code.append("}");
+      return code;
+    }
+  };
+
+  private TreeLogger logger = new FailErrorLogger();
+
+  private GwtLocale locale;
+
+  private ConstantsWithLookupImplCreator constantsWithLookupImplCreator;
+
+  private SourceWriter sw = new StringSourceWriter();
+
+  private TypeOracle oracle;
+
+  private JMethod stringMethod;
+
+  private JMethod intMethod;
+
+  @Override
+  public void setUp() throws TypeOracleException, UnableToCompleteException {
+    GwtLocaleFactory factory = new GwtLocaleFactoryImpl();
+    locale = factory.fromString("en");
+    oracle = TypeOracleTestingUtils.buildStandardTypeOracleWith(logger, SINGLE_ENTRY_MESSAGES,
+        FOUR_ENTRY_MESSAGES, LOOKUP, PARTITION_SIZE_ENTRY_MESSAGES);
+    initLookupMethodCreator(SINGLE_ENTRY_MESSAGES);
+  }
+
+  public void testClassEpilogCallCreatesNeededPartitonLookups() {
+    List<JMethod> missingPartition0 = Arrays.asList(stringMethod, intMethod);
+    List<List<JMethod>> methodToCreatePartitionLookups = new ArrayList<>();
+    methodToCreatePartitionLookups.add(missingPartition0);
+    constantsWithLookupImplCreator.addNeededPartitionLookups(stringMethod,
+        methodToCreatePartitionLookups);
+
+    constantsWithLookupImplCreator.classEpilog();
+
+    String actual = sw.toString().trim();
+
+    assertTrue("Missing partition lookup method (getStringFromPartition0).", actual.contains(
+        "java.lang.String getStringFromPartition0(java.lang.String arg0) {"));
+  }
+
+  public void testCodeForIntIsGeneratedSameAsWithoutPartitions() throws TypeOracleException,
+      UnableToCompleteException {
+    initLookupMethodCreator(SINGLE_ENTRY_MESSAGES);
+    constantsWithLookupImplCreator.emitMethodBody(logger, intMethod, locale);
+
+    // Same generated code as in version 2.8.1
+    SourceWriter expected = new StringSourceWriter();
+    expected.println("Integer target = (Integer) cache.get(arg0);");
+    expected.println("if (target != null) {");
+    expected.indent();
+    expected.println("return target.intValue();");
+    expected.outdent();
+    expected.println("}");
+
+    expected.println("if(arg0.equals(\"intEntry\")) {");
+    expected.indent();
+    expected.println("int answer = intEntry();");
+    // Needed because the return template use '\n'
+    expected.outdent();
+    expected.println("cache.put(\"intEntry\",new Integer(answer));");
+    expected.println("return answer;");
+    expected.outdent();
+    expected.println("}");
+
+    expected.println("throw new java.util.MissingResourceException("
+        + "\"Cannot find constant '\" +arg0 + \"'; expecting a method name\", \"foo.SingleEntryMessage\", arg0);");
+    expected.outdent();
+
+    String actual = sw.toString();
+    assertEquals("Wrong source Lookup created.", expected.toString(), actual);
+  }
+
+  public void testCodeIsGeneratedSameAsWithoutPartitions() throws TypeOracleException,
+      UnableToCompleteException {
+    initLookupMethodCreator(PARTITION_SIZE_ENTRY_MESSAGES);
+    constantsWithLookupImplCreator.emitMethodBody(logger, stringMethod, locale);
+
+    // Same generated code as in version 2.8.1
+    SourceWriter expected = new StringSourceWriter();
+    expected.println("java.lang.String target = (java.lang.String) cache.get(arg0);");
+    expected.println("if (target != null) {");
+    expected.indent();
+    expected.println("return target;");
+    expected.outdent();
+    expected.println("}");
+
+    expected.println("if(arg0.equals(\"lookupMethod1\")) {");
+    expected.indent();
+    expected.print("String answer = lookupMethod1();");
+    expected.print("\n");
+    expected.print("cache.put(\"lookupMethod1\",answer);");
+    expected.print("\n");
+    expected.println("return answer;");
+    expected.outdent();
+    expected.println("}");
+
+    expected.println("if(arg0.equals(\"lookupMethod2\")) {");
+    expected.indent();
+    expected.print("String answer = lookupMethod2();");
+    expected.print("\n");
+    expected.print("cache.put(\"lookupMethod2\",answer);");
+    expected.print("\n");
+    expected.println("return answer;");
+    expected.outdent();
+    expected.println("}");
+
+    expected.println("if(arg0.equals(\"lookupMethod3\")) {");
+    expected.indent();
+    expected.print("String answer = lookupMethod3();");
+    expected.print("\n");
+    expected.print("cache.put(\"lookupMethod3\",answer);");
+    expected.print("\n");
+    expected.println("return answer;");
+    expected.outdent();
+    expected.println("}");
+
+    expected.println("throw new java.util.MissingResourceException("
+        + "\"Cannot find constant '\" +arg0 + \"'; expecting a method name\", \"foo.PartitionSizeEntryMessage\", arg0);");
+    expected.outdent();
+
+    String actual = sw.toString();
+    assertEquals("Wrong source Lookup created.", expected.toString(), actual);
+  }
+
+  public void testCreateMethodForJMethodForSingleEntry() throws UnableToCompleteException {
+    constantsWithLookupImplCreator.emitMethodBody(logger, stringMethod, locale);
+
+    assertFalse("No partition lookup should created.", sw.toString().contains(
+        "java.lang.String getString0(java.lang.String arg0) {"));
+  }
+
+  public void testCreateMethodForJMethodForSingleIntEntry() throws UnableToCompleteException {
+    constantsWithLookupImplCreator.emitMethodBody(logger, intMethod, locale);
+
+    String createdSource = sw.toString();
+    assertTrue("Lookup for intMethod not created.", createdSource.contains(
+        "int answer = intEntry();"));
+  }
+
+  public void testCreateMethodForPartitionSizeEntriesNoPartitionNeeded() throws TypeOracleException,
+      UnableToCompleteException {
+    initLookupMethodCreator(PARTITION_SIZE_ENTRY_MESSAGES);
+    constantsWithLookupImplCreator.emitMethodBody(logger, stringMethod, locale);
+
+    String actual = sw.toString();
+
+    assertFalse("Missing partition lookup method (getStringFromPartitionN).", actual.contains(
+        "getStringFromPartition"));
+  }
+
+  public void testCreatePartitionMethodName() {
+    String partitionMethodName = constantsWithLookupImplCreator.createPartitionMethodName(
+        stringMethod, 1);
+    String expectedPartitionMethodName = "getStringFromPartition1";
+    assertEquals(expectedPartitionMethodName, partitionMethodName);
+  }
+
+  public void testEmitClassWithMultiMessageEntryCreateOneAdditionalPartition()
+      throws TypeOracleException, UnableToCompleteException {
+    initLookupMethodCreator(FOUR_ENTRY_MESSAGES);
+    constantsWithLookupImplCreator.emitClass(logger, locale);
+
+    String actual = sw.toString().trim();
+
+    assertTrue("Missing partition lookup method (getStringFromPartition0).", actual.contains(
+        "java.lang.String getStringFromPartition0(java.lang.String arg0) {"));
+  }
+
+  public void testEmitMethodBodyForJMethodForMultiMessageEntryNeedOneAdditionalPartition()
+      throws TypeOracleException, UnableToCompleteException {
+    initLookupMethodCreator(FOUR_ENTRY_MESSAGES);
+    constantsWithLookupImplCreator.emitMethodBody(logger, stringMethod, locale);
+
+    String actual = sw.toString().trim();
+
+    assertTrue("Method should end with call partition lookup method.", actual.endsWith(
+        "return getStringFromPartition0(arg0);"));
+    assertFalse("Partition method should not be created", actual.contains(
+        "java.lang.String getStringFromPartition0(java.lang.String arg0) {"));
+
+    assertEquals(1, constantsWithLookupImplCreator.getNeededPartitionLookups().size());
+  }
+
+  public void testFindMethodsToCreate() throws TypeOracleException {
+    initLookupMethodCreator(SINGLE_ENTRY_MESSAGES);
+
+    JType intType = oracle.parse(int.class.getName());
+    List<JMethod> intMethods = constantsWithLookupImplCreator.findAllMethodsToCreate(intMethod,
+        intType);
+
+    JMethod expectedIntMethod = oracle.findType(SINGLE_ENTRY_MESSAGES.getTypeName()).findMethod(
+        "intEntry", new JType[0]);
+
+    assertEquals(1, intMethods.size());
+    assertEquals(expectedIntMethod, intMethods.get(0));
+  }
+
+  public void testFindMethodsToCreateWithDifferentTargetMethod() throws TypeOracleException {
+    initLookupMethodCreator(SINGLE_ENTRY_MESSAGES);
+
+    JType intType = oracle.parse(int.class.getName());
+    List<JMethod> foundMethods = constantsWithLookupImplCreator.findAllMethodsToCreate(stringMethod,
+        intType);
+
+    JMethod expectedIntMethod = oracle.findType(SINGLE_ENTRY_MESSAGES.getTypeName()).findMethod(
+        "intEntry", new JType[0]);
+
+    assertEquals(2, foundMethods.size());
+    assertTrue(foundMethods.contains(intMethod));
+    assertTrue(foundMethods.contains(expectedIntMethod));
+  }
+
+  public void testGetReturnTypeNameForPrimitveTypes() {
+    for (JPrimitiveType primitiveType : JPrimitiveType.values()) {
+      LookupMethodCreator primitiveMethodCreator = new LookupMethodCreator(null, primitiveType);
+      String returnType = primitiveMethodCreator.getReturnTypeName();
+      String expectedType = primitiveType.getQualifiedBoxedSourceName().substring("java.lang."
+          .length());
+      assertEquals("Wrong Return Type for primitve type", expectedType, returnType);
+    }
+  }
+
+  private void initLookupMethodCreator(MockJavaResource resource) throws TypeOracleException {
+    initLookupMethodCreator(resource, TEST_PARTITION_SIZE);
+  }
+
+  private void initLookupMethodCreator(MockJavaResource resource, int partitionsSize)
+      throws TypeOracleException {
+    JClassType clazz = oracle.findType(resource.getTypeName());
+    try {
+      ResourceList resourceList = mock(ResourceList.class);
+      when(resourceList.getRequiredStringExt(anyString(), anyString())).thenReturn(
+          "Required value");
+      constantsWithLookupImplCreator = new ConstantsWithLookupImplCreator(logger, sw, clazz,
+          resourceList, oracle, partitionsSize);
+
+      JType stringType = oracle.parse(String.class.getName());
+      stringMethod = oracle.findType(LOOKUP.getTypeName()).findMethod("getString", new JType[] {
+          stringType});
+      intMethod = oracle.findType(LOOKUP.getTypeName()).findMethod("getInt", new JType[] {
+          stringType});
+    } catch (UnableToCompleteException e) {
+      fail(e.getMessage());
+    }
+  }
+
+}
diff --git a/user/test/com/google/gwt/i18n/rebind/LookupMethodCreatorTest.java b/user/test/com/google/gwt/i18n/rebind/LookupMethodCreatorTest.java
new file mode 100644
index 0000000..3fb045b
--- /dev/null
+++ b/user/test/com/google/gwt/i18n/rebind/LookupMethodCreatorTest.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2017 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.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JMethod;
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
+import com.google.gwt.core.ext.typeinfo.JType;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.core.ext.typeinfo.TypeOracleException;
+import com.google.gwt.dev.javac.TypeOracleTestingUtils;
+import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
+import com.google.gwt.dev.shell.FailErrorLogger;
+import com.google.gwt.i18n.rebind.AbstractResource.ResourceList;
+import com.google.gwt.i18n.server.GwtLocaleFactoryImpl;
+import com.google.gwt.i18n.shared.GwtLocale;
+import com.google.gwt.i18n.shared.GwtLocaleFactory;
+import com.google.gwt.user.rebind.SourceWriter;
+import com.google.gwt.user.rebind.StringSourceWriter;
+
+import junit.framework.TestCase;
+
+import static org.mockito.Mockito.mock;
+
+import java.util.List;
+
+/**
+ * Tests for {@link LookupMethodCreator}.
+ */
+public class LookupMethodCreatorTest extends TestCase {
+
+  private static final int TEST_PARTITION_SIZE = 3;
+
+  private static final MockJavaResource SINGLE_ENTRY_MESSAGES = new MockJavaResource(
+      "foo.SingleEntryMessage") {
+    @Override
+    public CharSequence getContent() {
+      StringBuffer code = new StringBuffer();
+      code.append("package foo;\n");
+      code.append("public interface SingleEntryMessage extends foo.Lookup {\n");
+      code.append(" String stringEntry();\n");
+      code.append(" int intEntry();\n");
+      code.append("}");
+      return code;
+    }
+  };
+  private static final MockJavaResource PARTITION_SIZE_ENTRY_MESSAGES = new MockJavaResource(
+      "foo.PartitionSizeEntryMessage") {
+    @Override
+    public CharSequence getContent() {
+      StringBuffer code = new StringBuffer();
+      code.append("package foo;\n");
+      code.append("public interface PartitionSizeEntryMessage extends foo.Lookup {\n");
+      for (int i = 1; i <= TEST_PARTITION_SIZE; i++) {
+        code.append(" String lookupMethod");
+        code.append(i);
+        code.append("();\n");
+      }
+      code.append("}");
+      return code;
+    }
+  };
+
+  private static final MockJavaResource LOOKUP = new MockJavaResource("foo.Lookup") {
+    @Override
+    public CharSequence getContent() {
+      StringBuffer code = new StringBuffer();
+      code.append("package foo;\n");
+      code.append("public interface Lookup {\n");
+      code.append(" String getString(String arg0);\n");
+      code.append(" int getInt(String arg0);\n");
+      code.append("}");
+      return code;
+    }
+  };
+
+  private TreeLogger logger = new FailErrorLogger();
+
+  private LookupMethodCreator stringCreator;
+  private LookupMethodCreator intCreator;
+
+  private SourceWriter sw = new StringSourceWriter();
+
+  private TypeOracle oracle;
+
+  private JMethod stringMethod;
+
+  private JMethod intMethod;
+
+  private GwtLocale locale;
+
+  @Override
+  public void setUp() throws TypeOracleException, UnableToCompleteException {
+    GwtLocaleFactory factory = new GwtLocaleFactoryImpl();
+    locale = factory.fromString("en");
+    oracle = TypeOracleTestingUtils.buildStandardTypeOracleWith(logger, SINGLE_ENTRY_MESSAGES,
+        LOOKUP, PARTITION_SIZE_ENTRY_MESSAGES);
+    initLookupMethodCreator(SINGLE_ENTRY_MESSAGES);
+  }
+
+  public void testCodeForIntIsGeneratedSameAsWithoutPartitions() throws TypeOracleException {
+    initLookupMethodCreator(SINGLE_ENTRY_MESSAGES);
+    intCreator.createMethodFor(logger, intMethod, intMethod.getName(), null, locale);
+
+    // Same generated code as in version 2.8.1
+    SourceWriter expected = new StringSourceWriter();
+    expected.println("Integer target = (Integer) cache.get(arg0);");
+    expected.println("if (target != null) {");
+    expected.indent();
+    expected.println("return target.intValue();");
+    expected.outdent();
+    expected.println("}");
+
+    expected.println("if (arg0.equals(\"intEntry\")) {");
+    expected.indent();
+    expected.println("int answer = intEntry();");
+    // Needed because the return template use '\n'
+    expected.outdent();
+    expected.println("cache.put(\"intEntry\",new Integer(answer));");
+    expected.println("return answer;");
+    expected.outdent();
+    expected.println("}");
+
+    expected.println("throw new java.util.MissingResourceException("
+        + "\"Cannot find constant '\" +arg0 + \"'; expecting a method name\", \"foo.SingleEntryMessage\", arg0);");
+    expected.outdent();
+
+    String actual = sw.toString();
+    assertEquals("Wrong source Lookup created.", expected.toString(), actual);
+  }
+
+  public void testCodeIsGeneratedSameAsWithoutPartitions() throws TypeOracleException {
+    initLookupMethodCreator(PARTITION_SIZE_ENTRY_MESSAGES);
+    stringCreator.createMethodFor(logger, stringMethod, stringMethod.getName(), null, locale);
+
+    // Same generated code as in version 2.8.1
+    SourceWriter expected = new StringSourceWriter();
+    expected.println("java.lang.String target = (java.lang.String) cache.get(arg0);");
+    expected.println("if (target != null) {");
+    expected.indent();
+    expected.println("return target;");
+    expected.outdent();
+    expected.println("}");
+
+    expected.println("if (arg0.equals(\"lookupMethod1\")) {");
+    expected.indent();
+    expected.println("return lookupMethod1();");
+    expected.outdent();
+    expected.println("}");
+
+    expected.println("if (arg0.equals(\"lookupMethod2\")) {");
+    expected.indent();
+    expected.println("return lookupMethod2();");
+    expected.outdent();
+    expected.println("}");
+
+    expected.println("if (arg0.equals(\"lookupMethod3\")) {");
+    expected.indent();
+    expected.println("return lookupMethod3();");
+    expected.outdent();
+    expected.println("}");
+
+    expected.println("throw new java.util.MissingResourceException("
+        + "\"Cannot find constant '\" +arg0 + \"'; expecting a method name\", \"foo.PartitionSizeEntryMessage\", arg0);");
+    expected.outdent();
+
+    String actual = sw.toString();
+    assertEquals("Wrong source Lookup created.", expected.toString(), actual);
+  }
+
+  public void testCreateMethodForJMethodForSingleEntry() throws TypeOracleException {
+    JType stringType = oracle.parse(String.class.getName());
+    List<JMethod> methodsToCreate = stringCreator.getConstantsWithLookupCreator()
+        .findAllMethodsToCreate(stringMethod, stringType);
+    stringCreator.createMethodFor(stringMethod, methodsToCreate, null);
+
+    assertFalse("No partition lookup should created.", sw.toString().contains(
+        "java.lang.String getString0(java.lang.String arg0) {"));
+  }
+
+  public void testCreateMethodForJMethodForSingleIntEntry() throws TypeOracleException {
+    JType intType = oracle.parse(int.class.getName());
+    List<JMethod> methodsToCreate = intCreator.getConstantsWithLookupCreator()
+        .findAllMethodsToCreate(intMethod, intType);
+    intCreator.createMethodFor(intMethod, methodsToCreate, null);
+
+    String createdSource = sw.toString();
+    assertTrue("Lookup for intMethod not created.", createdSource.contains(
+        "int answer = intEntry();"));
+  }
+
+  public void testGetReturnTypeName() {
+    String returnType = stringCreator.getReturnTypeName();
+    assertEquals("java.lang.String", returnType);
+  }
+
+  public void testGetReturnTypeNameForPrimitveTypes() {
+    for (JPrimitiveType primitiveType : JPrimitiveType.values()) {
+      LookupMethodCreator primitiveMethodCreator = new LookupMethodCreator(null, primitiveType);
+      String returnType = primitiveMethodCreator.getReturnTypeName();
+      String expectedType = primitiveType.getQualifiedBoxedSourceName().substring("java.lang."
+          .length());
+      assertEquals("Wrong Return Type for primitve type", expectedType, returnType);
+    }
+  }
+
+  public void testPrintFound() {
+    stringCreator.printFound("callTest");
+
+    String returnStatement = sw.toString();
+    assertEquals("return callTest();\n", returnStatement);
+  }
+
+  private void initLookupMethodCreator(MockJavaResource resource) throws TypeOracleException {
+    initLookupMethodCreator(resource, TEST_PARTITION_SIZE);
+  }
+
+  private void initLookupMethodCreator(MockJavaResource resource, int partitionsSize)
+      throws TypeOracleException {
+    JClassType clazz = oracle.findType(resource.getTypeName());
+    ConstantsWithLookupImplCreator mockCreator;
+    try {
+      mockCreator = new ConstantsWithLookupImplCreator(logger, sw, clazz, mock(ResourceList.class),
+          oracle, partitionsSize);
+
+      JType stringType = oracle.parse(String.class.getName());
+      stringMethod = oracle.findType(LOOKUP.getTypeName()).findMethod("getString", new JType[] {
+          stringType});
+      JType intType = oracle.parse(int.class.getName());
+      intMethod = oracle.findType(LOOKUP.getTypeName()).findMethod("getInt", new JType[] {
+          stringType});
+
+      stringCreator = new LookupMethodCreator(mockCreator, stringType);
+      intCreator = new LookupMethodCreator(mockCreator, intType) {
+        @Override
+        public void printReturnTarget() {
+          println("return target.intValue();");
+        }
+
+        @Override
+        public String returnTemplate() {
+          return "int answer = {0}();\ncache.put(\"{0}\",new Integer(answer));\nreturn answer;";
+        }
+      };
+    } catch (UnableToCompleteException e) {
+      fail(e.getMessage());
+    }
+  }
+
+}
diff --git a/user/test/com/google/gwt/user/UserJreSuite.java b/user/test/com/google/gwt/user/UserJreSuite.java
new file mode 100644
index 0000000..43c2b97
--- /dev/null
+++ b/user/test/com/google/gwt/user/UserJreSuite.java
@@ -0,0 +1,37 @@
+/*
+ * 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.user;
+
+import com.google.gwt.user.rebind.AbstractSourceCreatorTest;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * User tests running as a regular JRE test.
+ */
+public class UserJreSuite {
+  public static Test suite() {
+    TestSuite suite = new TestSuite("Non-browser tests for com.google.gwt.user");
+
+    // $JUnit-BEGIN$
+    suite.addTestSuite(AbstractSourceCreatorTest.class);
+    // $JUnit-END$
+
+    return suite;
+  }
+
+}
diff --git a/user/test/com/google/gwt/user/rebind/AbstractSourceCreatorTest.java b/user/test/com/google/gwt/user/rebind/AbstractSourceCreatorTest.java
new file mode 100644
index 0000000..95dff8d
--- /dev/null
+++ b/user/test/com/google/gwt/user/rebind/AbstractSourceCreatorTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2017 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.user.rebind;
+
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
+
+import junit.framework.TestCase;
+
+/**
+ * Used to test the {@link AbstractSourceCreator}.
+ */
+public class AbstractSourceCreatorTest extends TestCase {
+
+  public void testGetJavaObjectTypeForPrimitveTypes() {
+    for (JPrimitiveType primitiveType : JPrimitiveType.values()) {
+      String returnType = AbstractSourceCreator.getJavaObjectTypeFor(primitiveType);
+      String expectedType = primitiveType.getQualifiedBoxedSourceName().substring("java.lang."
+          .length());
+      assertEquals("Wrong Return Type for primitve type", expectedType, returnType);
+    }
+  }
+
+}