/*
 * 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.resources.rebind.context;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.ext.BadPropertyValueException;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.GeneratorContextExt;
import com.google.gwt.core.ext.GeneratorExt;
import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.SelectionProperty;
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.JGenericType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JParameterizedType;
import com.google.gwt.core.ext.typeinfo.JRealClassType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.generator.NameFactory;
import com.google.gwt.dev.javac.rebind.CachedClientDataMap;
import com.google.gwt.dev.javac.rebind.CachedPropertyInformation;
import com.google.gwt.dev.javac.rebind.CachedRebindResult;
import com.google.gwt.dev.javac.rebind.RebindResult;
import com.google.gwt.dev.javac.rebind.RebindStatus;
import com.google.gwt.dev.util.Util;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ClientBundleWithLookup;
import com.google.gwt.resources.client.ResourcePrototype;
import com.google.gwt.resources.ext.ClientBundleFields;
import com.google.gwt.resources.ext.ClientBundleRequirements;
import com.google.gwt.resources.ext.ResourceContext;
import com.google.gwt.resources.ext.ResourceGenerator;
import com.google.gwt.resources.ext.ResourceGeneratorType;
import com.google.gwt.resources.ext.ResourceGeneratorUtil;
import com.google.gwt.resources.ext.SupportsGeneratorResultCaching;
import com.google.gwt.resources.rg.BundleResourceGenerator;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.JarURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * The base class for creating new ClientBundle implementations.
 * <p>
 * The general structure of the generated class is as follows:
 * 
 * <pre>
 * private void resourceInitializer() {
 *   resource = new Resource();
 * }
 * private static class cellTreeClosedItemInitializer {
 *   // Using a static initializer so the compiler can optimize clinit calls.
 *   // Refers back to an instance method. See comment below.
 *   static {
 *     _instance0.resourceInitializer();
 *   }
 *   static ResourceType get() {
 *     return resource;
 *   }
 * }
 * public ResourceType resource() {
 *   return cellTreeClosedItemInitializer.get();
 * }
 * // Other ResourceGenerator-defined fields
 * private static ResourceType resource;
 * private static HashMap&lt;String, ResourcePrototype&gt; resourceMap;
 * public ResourcePrototype[] getResources() {
 *   return new ResourcePrototype[] { resource() };
 * }
 * public ResourcePrototype getResource(String name) {
 *   if (GWT.isScript()) {
 *     return getResourceNative(name);
 *   } else {
 *     if (resourceMap == null) {
 *       resourceMap = new HashMap<String, ResourcePrototype>();
 *       resourceMap.put("resource", resource());
 *     }
 *     return resourceMap.get(name);
 *   }
 * }
 * private native ResourcePrototype getResourceNative(String name) /-{
 *   switch (name) {
 *     case 'resource': return this.@...::resource()();
 *   }
 *   return null;
 * }-/
 * </pre>
 * The instantiation of the individual ResourcePrototypes is done in the content
 * of an instance of the ClientBundle type so that resources can refer to one
 * another by simply emitting a call to <code>resource()</code>.
 */
public abstract class AbstractClientBundleGenerator extends GeneratorExt {

  private static final String FILE_PROTOCOL = "file";
  private static final String JAR_PROTOCOL = "jar";
  private static final String CACHED_PROPERTY_INFORMATION = "cached-property-info";
  private static final String CACHED_RESOURCE_INFORMATION = "cached-resource-info";
  private static final String CACHED_TYPE_INFORMATION = "cached-type-info";
  private static final String INSTANCE_NAME = "_instance0";

  /**
   * An implementation of ClientBundleFields.
   */
  protected static class FieldsImpl implements ClientBundleFields {
    private final NameFactory factory = new NameFactory();
    /**
     * It is necessary to maintain order in case one field refers to another.
     */
    private final Map<String, String> fieldsToDeclarations = new LinkedHashMap<String, String>();
    private final Map<String, String> fieldsToInitializers = new HashMap<String, String>();

    public String define(JType type, String name) {
      return define(type, name, null, true, false);
    }

    public String define(JType type, String name, String initializer,
        boolean isStatic, boolean isFinal) {

      assert Util.isValidJavaIdent(name) : name
          + " is not a valid Java identifier";

      String ident = factory.createName(name);

      StringBuilder sb = new StringBuilder();
      sb.append("private ");

      if (isStatic) {
        sb.append("static ");
      }

      if (isFinal) {
        sb.append("final ");
      }

      sb.append(type.getParameterizedQualifiedSourceName());
      sb.append(" ");
      sb.append(ident);

      fieldsToDeclarations.put(ident, sb.toString());

      if (initializer != null) {
        fieldsToInitializers.put(ident, initializer);
      }

      return ident;
    }

    /**
     * This can be called to reset the initializer expression on an
     * already-defined field.
     * 
     * @param ident an identifier previously returned by {@link #define}
     * @param initializer a Java expression that will be used to initialize the
     *          field
     */
    public void setInitializer(String ident, String initializer) {
      assert fieldsToDeclarations.containsKey(ident) : ident + " not defined";
      fieldsToInitializers.put(ident, initializer);
    }

    private String getCode() {
      StringBuilder sb = new StringBuilder();
      for (Map.Entry<String, String> entry : fieldsToDeclarations.entrySet()) {
        String ident = entry.getKey();
        sb.append(entry.getValue());

        String initializer = fieldsToInitializers.get(ident);
        if (initializer != null) {
          sb.append(" = ").append(initializer);
        }
        sb.append(";\n");
      }
      return sb.toString();
    }
  }

  private static class RequirementsImpl implements ClientBundleRequirements {
    private final Set<String> axes;
    private boolean axesLocked = false;
    private final boolean canBeCacheable;
    private final Set<String> configProps;
    private final PropertyOracle propertyOracle;
    private final Map<String, URL> resolvedResources;
    private final Set<JClassType> types;

    public RequirementsImpl(PropertyOracle propertyOracle, boolean canBeCacheable) {
      this.propertyOracle = propertyOracle;
      this.canBeCacheable = canBeCacheable;
      
      // always need to track permuationAxes
      axes = new HashSet<String>();
      
      // only need to track these if generator caching is a possibility
      if (canBeCacheable) {
        configProps = new HashSet<String>();
        types = new HashSet<JClassType>();
        resolvedResources = new HashMap<String, URL>();
      } else {
        configProps = null;
        types = null;
        resolvedResources = null;
      }
    }

    public void addConfigurationProperty(String propertyName) 
        throws BadPropertyValueException {
      
      if (!canBeCacheable) {
        return;
      }
      // Ensure the property exists
      propertyOracle.getConfigurationProperty(propertyName).getValues();
      configProps.add(propertyName);
    }

    public void addPermutationAxis(String propertyName)
        throws BadPropertyValueException {

      if (axes.contains(propertyName)) {
        return;
      }

      // Ensure adding of permutationAxes has not been locked
      if (axesLocked) {
        throw new IllegalStateException(
            "addPermutationAxis failed, axes have been locked");
      }

      // Ensure the property exists and add a permutation axis if the
      // property is a deferred binding property.
      try {
        propertyOracle.getSelectionProperty(
            TreeLogger.NULL, propertyName).getCurrentValue();
        axes.add(propertyName);
      } catch (BadPropertyValueException e) {
        addConfigurationProperty(propertyName);
      }
    }

    public void addResolvedResource(String partialPath, URL resolvedResourceUrl) {
      if (!canBeCacheable) {
        return;
      }
      resolvedResources.put(partialPath, resolvedResourceUrl);
    }

    public void addTypeHierarchy(JClassType type) {
      if (!canBeCacheable) {
        return;
      }
      if (!types.add(type)) {
        return;
      }
      Set<? extends JClassType> superTypes = type.getFlattenedSupertypeHierarchy();
      types.addAll(superTypes);
    }

    public Collection<String> getConfigurationPropertyNames() {
      if (!canBeCacheable) {
        return null;
      }
      return configProps;
    }

    public Collection<String> getPermutationAxes() {
      return axes;
    }

    public Map<String, URL> getResolvedResources() {
      if (!canBeCacheable) {
        return null;
      }
      return resolvedResources;
    }

    public Map<String, Long> getTypeLastModifiedTimes() {
      if (!canBeCacheable) {
        return null;
      }
      Map<String, Long> typeLastModifiedTimeMap = new HashMap<String, Long>();
      for (JClassType type : types) {
        String typeName = type.getQualifiedSourceName();
        assert type instanceof JRealClassType;
        JRealClassType sourceRealType = (JRealClassType) type;
        typeLastModifiedTimeMap.put(typeName, sourceRealType.getLastModifiedTime());
      }
      return typeLastModifiedTimeMap;
    }

    /*
     * No further permutation axes can be added after this is called
     */
    public void lockPermutationAxes() {
      axesLocked = true;
    }
  }

  @Override
  public RebindResult generateIncrementally(TreeLogger logger,
      GeneratorContextExt generatorContext, String typeName)
      throws UnableToCompleteException {

    /*
     * Do a series of checks to see if we can use a previously cached result,
     * and if so, we can skip further execution and return immediately.
     */
    boolean useCache = false;
    if (checkPropertyCacheability(logger, generatorContext)
        && checkSourceTypeCacheability(logger, generatorContext)
        && checkDependentResourceCacheability(logger, generatorContext, null)) {
      useCache = true;
    }
    
    if (logger.isLoggable(TreeLogger.TRACE)) { 
      if (generatorContext.isGeneratorResultCachingEnabled()) {
        String msg;
        if (useCache) {
          msg = "Reusing cached client bundle for " + typeName;
        } else {
          msg = "Can't use cached client bundle for " + typeName;
        }
        logger.log(TreeLogger.TRACE, msg);
      }
    }
      
    if (useCache) {
      return new RebindResult(RebindStatus.USE_ALL_CACHED, typeName);
    }
      
    // The TypeOracle knows about all types in the type system
    TypeOracle typeOracle = generatorContext.getTypeOracle();

    // Get a reference to the type that the generator should implement
    JClassType sourceType = typeOracle.findType(typeName);

    // Ensure that the requested type exists
    if (sourceType == null) {
      logger.log(TreeLogger.ERROR, "Could not find requested typeName");
      throw new UnableToCompleteException();
    } else if (sourceType.isInterface() == null) {
      // The incoming type wasn't a plain interface, we don't support
      // abstract base classes
      logger.log(TreeLogger.ERROR, sourceType.getQualifiedSourceName()
          + " is not an interface.", null);
      throw new UnableToCompleteException();
    }

    /*
     * This associates the methods to implement with the ResourceGenerator class
     * that will generate the implementations of those methods.
     */
    Map<Class<? extends ResourceGenerator>, List<JMethod>> taskList = createTaskList(
        logger, typeOracle, sourceType);

    /*
     * Check the resource generators associated with our taskList, and see if
     * they all support generator result caching.
     */
    boolean canBeCacheable = checkResourceGeneratorCacheability(
        generatorContext, taskList);

    /*
     * Additional objects that hold state during the generation process.
     */
    AbstractResourceContext resourceContext = createResourceContext(logger,
        generatorContext, sourceType);
    FieldsImpl fields = new FieldsImpl();
    RequirementsImpl requirements = new RequirementsImpl(
        generatorContext.getPropertyOracle(), canBeCacheable);
    resourceContext.setRequirements(requirements);
    doAddFieldsAndRequirements(logger, generatorContext, fields, requirements);

    /*
     * Add our source type (and it's supertypes) as a requirement.  Note further
     * types may be added during the processing of the taskList.
     */
    requirements.addTypeHierarchy(sourceType);

    /*
     * Initialize the ResourceGenerators and prepare them for subsequent code
     * generation.
     */
    Map<ResourceGenerator, List<JMethod>> generators = initAndPrepare(logger,
        taskList, resourceContext, requirements);

    /*
     * Now that the ResourceGenerators have been initialized and prepared, we
     * can compute the actual name of the implementation class in order to
     * ensure that we use a distinct name between permutations.
     */
    String generatedSimpleSourceName = generateSimpleSourceName(logger,
        resourceContext, requirements);
    String packageName = sourceType.getPackage().getName();
    String createdClassName = packageName + "." + generatedSimpleSourceName;

    PrintWriter out = generatorContext.tryCreate(logger, packageName,
        generatedSimpleSourceName);

    // If an implementation already exists, we don't need to do any work
    if (out != null) {
      // There is actual work to do
      doCreateBundleForPermutation(logger, generatorContext, fields,
          generatedSimpleSourceName);
      // Begin writing the generated source.
      ClassSourceFileComposerFactory f = new ClassSourceFileComposerFactory(
          packageName, generatedSimpleSourceName);

      // The generated class needs to be able to determine the module base URL
      f.addImport(GWT.class.getName());

      // Used by the map methods
      f.addImport(ResourcePrototype.class.getName());

      // The whole point of this exercise
      f.addImplementedInterface(sourceType.getQualifiedSourceName());

      // All source gets written through this Writer
      SourceWriter sw = f.createSourceWriter(generatorContext, out);

      // Set the now-calculated simple source name
      resourceContext.setSimpleSourceName(generatedSimpleSourceName);

      JParameterizedType hashMapStringResource = getHashMapStringResource(typeOracle);
      String resourceMapField = fields.define(hashMapStringResource, "resourceMap");

      // Write a static instance for use by the static initializers.
      sw.print("private static " + generatedSimpleSourceName + " ");
      sw.println(INSTANCE_NAME + " = new " + generatedSimpleSourceName + "();");

      // Write the generated code to disk
      createFieldsAndAssignments(logger, sw, generators, resourceContext,
          fields);

      // Print the accumulated field definitions
      sw.println(fields.getCode());

      /*
       * The map-accessor methods use JSNI and need a fully-qualified class
       * name, but should not include any sub-bundles.
       */
      taskList.remove(BundleResourceGenerator.class);
      writeMapMethods(sw, taskList, hashMapStringResource, resourceMapField);

      sw.commit(logger);
    }

    finish(logger, resourceContext, generators.keySet());
    doFinish(logger);

    if (canBeCacheable) {
      // remember the current set of required properties, and their values
      CachedPropertyInformation cpi = new CachedPropertyInformation(logger, 
          generatorContext.getPropertyOracle(), 
          requirements.getPermutationAxes(), 
          requirements.getConfigurationPropertyNames());

      // remember the last modified times for required source types
      Map<String, Long> cti = requirements.getTypeLastModifiedTimes();

      // remember the required resources
      Map<String, URL> cri = requirements.getResolvedResources();

      // create data map to be returned the next time the generator is run
      CachedClientDataMap data = new CachedClientDataMap();
      data.put(CACHED_PROPERTY_INFORMATION, cpi);
      data.put(CACHED_RESOURCE_INFORMATION, cri);
      data.put(CACHED_TYPE_INFORMATION, cti);

      // Return a new cacheable result
      return new RebindResult(RebindStatus.USE_ALL_NEW, createdClassName, data);
    } else {
      // If we can't be cacheable, don't return a cacheable result
      return new RebindResult(RebindStatus.USE_ALL_NEW_WITH_NO_CACHING,
          createdClassName);
    }
  }

  /**
   * Create the ResourceContext object that will be used by
   * {@link ResourceGenerator} subclasses. This is the primary way to implement
   * custom logic in the resource generation pass.
   */
  protected abstract AbstractResourceContext createResourceContext(
      TreeLogger logger, GeneratorContext context, JClassType resourceBundleType)
      throws UnableToCompleteException;

  /**
   * Provides a hook for subtypes to add additional fields or requirements to
   * the bundle.
   * 
   * @param logger a TreeLogger
   * @param context the GeneratorContext
   * @param fields ClentBundle fields
   * @param requirements ClientBundleRequirements
   * 
   * @throws UnableToCompleteException if an error occurs.
   */
  protected void doAddFieldsAndRequirements(TreeLogger logger,
      GeneratorContext context, FieldsImpl fields,
      ClientBundleRequirements requirements) throws UnableToCompleteException {
  }

  /**
   * This method is called after the ClientBundleRequirements have been
   * evaluated and a new ClientBundle implementation is being created.
   * 
   * @param logger a TreeLogger
   * @param generatorContext the GeneratoContext
   * @param fields ClientBundle fields
   * @param generatedSimpleSourceName a String
   * 
   * @throws UnableToCompleteException if an error occurs.
   */
  protected void doCreateBundleForPermutation(TreeLogger logger,
      GeneratorContext generatorContext, FieldsImpl fields,
      String generatedSimpleSourceName) throws UnableToCompleteException {
  }

  /**
   * Provides a hook for finalizing generated resources.
   * 
   * @param logger a TreeLogger
   * 
   * @throws UnableToCompleteException if an error occurs.
   */
  protected void doFinish(TreeLogger logger) throws UnableToCompleteException {
  }

  /**
   * Check that the cached last modified times match those from the current
   * typeOracle.
   */
  private boolean checkCachedTypeLastModifiedTimes(TreeLogger logger,
      GeneratorContextExt generatorContext, Map<String, Long> typeLastModifiedTimes) {
    
    TypeOracle oracle = generatorContext.getTypeOracle();
    
    for (String sourceTypeName : typeLastModifiedTimes.keySet()) {
      JClassType sourceType = oracle.findType(sourceTypeName);
      if (sourceType == null) {
        logger.log(TreeLogger.TRACE, 
            "Found previously dependent type that's no longer present: " + sourceTypeName);
        return false;
      }
      assert sourceType instanceof JRealClassType;
      JRealClassType sourceRealType = (JRealClassType) sourceType;
      
      if (sourceRealType.getLastModifiedTime() != typeLastModifiedTimes.get(sourceTypeName)) {
        logger.log(TreeLogger.TRACE, "Found dependent type that has changed: " + sourceTypeName);
        return false;
      }
    }
    
    return true;
  }

  /**
   * Check dependent resources for cacheability.
   */
  private boolean checkDependentResourceCacheability(TreeLogger logger,
      GeneratorContextExt genContext, ResourceContext resourceContext) {

    CachedRebindResult lastRebindResult = genContext.getCachedGeneratorResult();

    if (lastRebindResult == null 
        || !genContext.isGeneratorResultCachingEnabled()) {
      return false;
    }
    long lastTimeGenerated = lastRebindResult.getTimeGenerated();

    // check that resource URL's haven't moved, and haven't been modified
    @SuppressWarnings("unchecked")
    Map<String, URL> cachedResolvedResources = (Map<String, URL>)
      lastRebindResult.getClientData(CACHED_RESOURCE_INFORMATION);
    
    if (cachedResolvedResources == null) {
      return false;
    }
    
    for (Entry<String, URL> entry : cachedResolvedResources.entrySet()) {
      String resourceName = entry.getKey();
      URL resolvedUrl = entry.getValue();
      URL currentUrl = ResourceGeneratorUtil.tryFindResource(logger, genContext,
          resourceContext, resourceName);
      if (currentUrl == null || resolvedUrl == null
          || !resolvedUrl.toExternalForm().equals(currentUrl.toExternalForm())) {
        logger.log(TreeLogger.TRACE,
            "Found dependent resource that has moved or no longer exists: " + resourceName);
        return false;
      }
      
      if (!checkDependentResourceUpToDate(lastTimeGenerated, resolvedUrl)) {
        logger.log(TreeLogger.TRACE, "Found dependent resource that has changed: " + resourceName);
        return false;
      }
    }

    return true;
  }

  /**
   * Checks whether a dependent resource referenced by the provided URL is
   * up to date, based on the provided referenceTime.
   */
  private boolean checkDependentResourceUpToDate(long referenceTime, URL url) {
    try {
      if (url.getProtocol().equals(JAR_PROTOCOL)) {
        /*
         * If this resource is contained inside a jar file, such as can
         * happen if it's bundled in a 3rd-party library, we use the jar 
         * file itself to test whether it's up to date.  We don't want
         * to call JarURLConnection.getLastModified(), as this is much
         * slower than using the jar File resource directly.
         */
        JarURLConnection jarConn = (JarURLConnection) url.openConnection();
        url = jarConn.getJarFileURL();
      }

      long lastModified;
      if (url.getProtocol().equals(FILE_PROTOCOL)) {
        /*
         * Need to handle possibly wonky syntax in a file URL resource.
         * Modeled after suggestion in this blog entry:
         * http://weblogs.java.net/blog/2007/04/25/how-convert-javaneturl-javaiofile
         */
        File file;
        try {
          file = new File(url.toURI());
        } catch (URISyntaxException uriEx) {
          file = new File(url.getPath());
        }
        lastModified = file.lastModified();
      } else {
        /*
         * Don't attempt to handle any other protocol
         */
        return false;
      }
      if (lastModified == 0L ||
          lastModified > referenceTime) {
        return false;
      }
    } catch (IOException ioEx) {
      return false;
    } catch (RuntimeException ruEx) {
      /*
       * Return false for any RuntimeException (e.g. a SecurityException), and 
       * allow the cacheability check to fail, since we don't want to change the 
       * behavior that would be encountered if no cache is available.  Force 
       * resource generators to utilize their own exception handling.
       */
      return false;
    }
    return true;
  }

  /*
   * Check properties for cacheability
   */
  private boolean checkPropertyCacheability(TreeLogger logger,
      GeneratorContextExt genContext) {

    CachedRebindResult lastRebindResult = genContext.getCachedGeneratorResult();

    if (lastRebindResult == null 
        || !genContext.isGeneratorResultCachingEnabled()) {
      return false;
    }

    /*
     * Do a check of deferred-binding and configuration properties, comparing
     * the cached values saved previously with the current properties.
     */
    CachedPropertyInformation cpi = (CachedPropertyInformation) 
        lastRebindResult.getClientData(CACHED_PROPERTY_INFORMATION);
      
    return cpi != null && cpi.checkPropertiesWithPropertyOracle(logger, 
        genContext.getPropertyOracle());
  }
  
  /**
   * Check cacheability for resource generators in taskList.
   */
  private boolean checkResourceGeneratorCacheability(
      GeneratorContextExt genContext,
      Map<Class<? extends ResourceGenerator>, List<JMethod>> taskList) {
    
    if (!genContext.isGeneratorResultCachingEnabled()) {
      return false;
    }

    /*
     * Loop through each of our ResouceGenerator classes, and check those that
     * implement the SupportsGeneratorResultCaching interface.
     */
    for (Class<? extends ResourceGenerator> rgClass : taskList.keySet()) {
      if (!SupportsGeneratorResultCaching.class.isAssignableFrom(rgClass)) {
        return false;
      }
    } 
    return true;
  }

  /*
   * Check source types for cacheability
   */
  private boolean checkSourceTypeCacheability(TreeLogger logger, GeneratorContextExt genContext) {

    CachedRebindResult lastRebindResult = genContext.getCachedGeneratorResult();

    if (lastRebindResult == null 
        || !genContext.isGeneratorResultCachingEnabled()) {
      return false;
    }

    /*
     * Do a check over the cached list of types that were previously flagged as
     * required.  Check that none of these types has undergone a version change
     * since the previous cached result was generated.
     */
    @SuppressWarnings("unchecked")
    Map<String, Long> cachedTypeLastModifiedTimes = (Map<String, Long>)
      lastRebindResult.getClientData(CACHED_TYPE_INFORMATION);

    return cachedTypeLastModifiedTimes != null 
      && checkCachedTypeLastModifiedTimes(logger, genContext, cachedTypeLastModifiedTimes);
  }

  /**
   * Create fields and assignments for a single ResourceGenerator.
   */
  private boolean createFieldsAndAssignments(TreeLogger logger,
      AbstractResourceContext resourceContext, ResourceGenerator rg,
      List<JMethod> generatorMethods, SourceWriter sw,
      ClientBundleFields fields) {

    // Defer failure until this phase has ended
    boolean fail = false;

    resourceContext.setCurrentResourceGenerator(rg);

    // Write all field values
    try {
      rg.createFields(logger.branch(TreeLogger.DEBUG, "Creating fields"),
          resourceContext, fields);
    } catch (UnableToCompleteException e) {
      return false;
    }

    // Create the instance variables in the IRB subclass by calling
    // writeAssignment() on the ResourceGenerator
    for (JMethod m : generatorMethods) {
      String rhs;

      try {
        rhs = rg.createAssignment(logger.branch(TreeLogger.DEBUG,
            "Creating assignment for " + m.getName() + "()"), resourceContext,
            m);
      } catch (UnableToCompleteException e) {
        fail = true;
        continue;
      }

      // Define a field that will hold the ResourcePrototype
      String ident = fields.define(m.getReturnType().isClassOrInterface(),
          m.getName(), null, true, false);

      /*
       * Create an initializer method in the context of an instance so that
       * resources can refer to one another by simply emitting a call to
       * <code>resource()</code>.
       */
      String initializerName = m.getName() + "Initializer";
      sw.println("private void " + initializerName + "() {");
      sw.indentln(ident + " = " + rhs + ";");
      sw.println("}");
      
      /*
       * Create a static Initializer class to lazily initialize the field on
       * first access. The compiler can efficiently optimize this static class
       * using clinits.
       */
      sw.println("private static class " + initializerName + " {");

      sw.indent();
      sw.println("static {");
      sw.indentln(INSTANCE_NAME + "." + initializerName + "();");
      sw.println("}");

      sw.print("static ");
      sw.print(m.getReturnType().getParameterizedQualifiedSourceName());
      sw.println(" get() {");
      sw.indentln("return " + ident + ";");
      sw.println("}");

      sw.outdent();
      sw.println("}");
      
      // Strip off all but the access modifiers
      sw.print(m.getReadableDeclaration(false, true, true, true, true));
      sw.println(" {");
      sw.indentln("return " + initializerName + ".get();");
      sw.println("}");
    }

    if (fail) {
      return false;
    }

    return true;
  }

  /**
   * Create fields and assignments for multiple ResourceGenerators.
   */
  private void createFieldsAndAssignments(TreeLogger logger, SourceWriter sw,
      Map<ResourceGenerator, List<JMethod>> generators,
      AbstractResourceContext resourceContext, ClientBundleFields fields)
      throws UnableToCompleteException {
    // Try to provide as many errors as possible before failing.
    boolean success = true;

    // Run the ResourceGenerators to generate implementations of the methods
    for (Map.Entry<ResourceGenerator, List<JMethod>> entry : generators.entrySet()) {
      success &= createFieldsAndAssignments(logger, resourceContext,
          entry.getKey(), entry.getValue(), sw, fields);
    }

    if (!success) {
      throw new UnableToCompleteException();
    }
  }

  /**
   * Given a ClientBundle subtype, compute which ResourceGenerators should
   * implement which methods. The data returned from this method should be
   * stable across identical modules.
   */
  private Map<Class<? extends ResourceGenerator>, List<JMethod>> createTaskList(
      TreeLogger logger, TypeOracle typeOracle, JClassType sourceType)
      throws UnableToCompleteException {

    Map<Class<? extends ResourceGenerator>, List<JMethod>> toReturn = new LinkedHashMap<Class<? extends ResourceGenerator>, List<JMethod>>();

    JClassType bundleType = typeOracle.findType(ClientBundle.class.getName());
    assert bundleType != null;

    JClassType bundleWithLookupType = typeOracle.findType(ClientBundleWithLookup.class.getName());
    assert bundleWithLookupType != null;

    JClassType resourcePrototypeType = typeOracle.findType(ResourcePrototype.class.getName());
    assert resourcePrototypeType != null;

    // Accumulate as many errors as possible before failing
    boolean throwException = false;

    // Using overridable methods allows composition of interface types
    for (JMethod m : sourceType.getOverridableMethods()) {
      JClassType returnType = m.getReturnType().isClassOrInterface();

      if (m.getEnclosingType().equals(bundleType)
          || m.getEnclosingType().equals(bundleWithLookupType)) {
        // Methods that we must generate, but that are not resources
        continue;

      } else if (!m.isAbstract()) {
        // Covers the case of an abstract class base type
        continue;

      } else if (returnType == null
          || !(returnType.isAssignableTo(resourcePrototypeType) || returnType.isAssignableTo(bundleType))) {
        // Primitives and random other abstract methods
        logger.log(TreeLogger.ERROR, "Unable to implement " + m.getName()
            + " because it does not derive from "
            + resourcePrototypeType.getQualifiedSourceName() + " or "
            + bundleType.getQualifiedSourceName());
        throwException = true;
        continue;
      }

      try {
        Class<? extends ResourceGenerator> clazz = findResourceGenerator(
            logger, m);
        List<JMethod> generatorMethods;
        if (toReturn.containsKey(clazz)) {
          generatorMethods = toReturn.get(clazz);
        } else {
          generatorMethods = new ArrayList<JMethod>();
          toReturn.put(clazz, generatorMethods);
        }

        generatorMethods.add(m);
      } catch (UnableToCompleteException e) {
        throwException = true;
      }
    }

    if (throwException) {
      throw new UnableToCompleteException();
    }

    return toReturn;
  }

  /**
   * Given a JMethod, find the a ResourceGenerator class that will be able to
   * provide an implementation of the method.
   */
  private Class<? extends ResourceGenerator> findResourceGenerator(
      TreeLogger logger, JMethod method) throws UnableToCompleteException {
    JClassType resourceType = method.getReturnType().isClassOrInterface();
    assert resourceType != null;

    ResourceGeneratorType annotation = resourceType.findAnnotationInTypeHierarchy(ResourceGeneratorType.class);
    if (annotation == null) {
      logger.log(TreeLogger.ERROR, "No @"
          + ResourceGeneratorType.class.getName() + " was specifed for type "
          + resourceType.getQualifiedSourceName() + " or its supertypes");
      throw new UnableToCompleteException();
    }

    return annotation.value();
  }

  /**
   * Call finish() on several ResourceGenerators.
   */
  private void finish(TreeLogger logger, AbstractResourceContext context,
      Collection<ResourceGenerator> generators)
      throws UnableToCompleteException {
    boolean fail = false;
    // Finalize the ResourceGenerator
    for (ResourceGenerator rg : generators) {
      context.setCurrentResourceGenerator(rg);
      try {
        rg.finish(
            logger.branch(TreeLogger.DEBUG, "Finishing ResourceGenerator"),
            context);
      } catch (UnableToCompleteException e) {
        fail = true;
      }
    }
    if (fail) {
      throw new UnableToCompleteException();
    }
  }

  /**
   * Given a user-defined type name, determine the type name for the generated
   * class based on accumulated requirements.
   */
  private String generateSimpleSourceName(TreeLogger logger,
      ResourceContext context, RequirementsImpl requirements) {
    StringBuilder toReturn = new StringBuilder(
        context.getClientBundleType().getName().replaceAll("[.$]", "_"));

    try {
      // always add the locale property
      requirements.addPermutationAxis("locale");
    } catch (BadPropertyValueException e) {
    }

    try {
      // no further additions to the permutation axes allowed after this point
      requirements.lockPermutationAxes();
      
      PropertyOracle oracle = context.getGeneratorContext().getPropertyOracle();
      for (String property : requirements.getPermutationAxes()) {
        SelectionProperty prop = oracle.getSelectionProperty(logger, property);
        String value = prop.getCurrentValue();
        toReturn.append("_" + value);
      }
    } catch (BadPropertyValueException e) {
    }

    toReturn.append("_" + getClass().getSimpleName());

    return toReturn.toString();
  }

  /**
   * Returns HashMap&lt;String, ResourcePrototype&gt;.
   */
  private JParameterizedType getHashMapStringResource(TypeOracle typeOracle) {
    JGenericType hashMap = (JGenericType) typeOracle.findType(HashMap.class.getName());
    assert hashMap != null;
    JClassType string = typeOracle.findType(String.class.getName());
    assert string != null;
    JClassType resourcePrototype = typeOracle.findType(ResourcePrototype.class.getName());
    assert resourcePrototype != null;
    JParameterizedType mapStringRes = typeOracle.getParameterizedType(hashMap,
        new JClassType[]{string, resourcePrototype});
    return mapStringRes;
  }

  private boolean initAndPrepare(TreeLogger logger,
      AbstractResourceContext resourceContext, ResourceGenerator rg,
      List<JMethod> generatorMethods, ClientBundleRequirements requirements) {
    try {
      resourceContext.setCurrentResourceGenerator(rg);
      rg.init(
          logger.branch(TreeLogger.DEBUG, "Initializing ResourceGenerator"),
          resourceContext);
    } catch (UnableToCompleteException e) {
      return false;
    }

    boolean fail = false;

    // Prepare the ResourceGenerator by telling it all methods that it is
    // expected to produce.
    for (JMethod m : generatorMethods) {
      try {
        rg.prepare(logger.branch(TreeLogger.DEBUG, "Preparing method "
            + m.getName()), resourceContext, requirements, m);
      } catch (UnableToCompleteException e) {
        fail = true;
      }
    }

    return !fail;
  }

  private Map<ResourceGenerator, List<JMethod>> initAndPrepare(
      TreeLogger logger,
      Map<Class<? extends ResourceGenerator>, List<JMethod>> taskList,
      AbstractResourceContext resourceContext,
      ClientBundleRequirements requirements) throws UnableToCompleteException {
    // Try to provide as many errors as possible before failing.
    boolean success = true;
    Map<ResourceGenerator, List<JMethod>> toReturn = new LinkedHashMap<ResourceGenerator, List<JMethod>>();

    // Run the ResourceGenerators to generate implementations of the methods
    for (Map.Entry<Class<? extends ResourceGenerator>, List<JMethod>> entry : taskList.entrySet()) {

      ResourceGenerator rg = instantiateResourceGenerator(logger,
          entry.getKey());
      toReturn.put(rg, entry.getValue());

      success &= initAndPrepare(logger, resourceContext, rg, entry.getValue(),
          requirements);
    }

    if (!success) {
      throw new UnableToCompleteException();
    }

    return toReturn;
  }

  /**
   * Utility method to construct a ResourceGenerator that logs errors.
   */
  private <T extends ResourceGenerator> T instantiateResourceGenerator(
      TreeLogger logger, Class<T> generatorClass)
      throws UnableToCompleteException {
    try {
      return generatorClass.newInstance();
    } catch (InstantiationException e) {
      logger.log(TreeLogger.ERROR, "Unable to initialize ResourceGenerator", e);
    } catch (IllegalAccessException e) {
      logger.log(TreeLogger.ERROR, "Unable to instantiate ResourceGenerator. "
          + "Does it have a public default constructor?", e);
    }
    throw new UnableToCompleteException();
  }

  /**
   * Emits getResources() and getResourceMap() implementations.
   * 
   * @param sw the output writer
   * @param taskList the list of methods to map by name
   * @param resourceMapField field containing the Java String to Resource map
   */
  private void writeMapMethods(SourceWriter sw,
      Map<Class<? extends ResourceGenerator>, List<JMethod>> taskList,
      JParameterizedType resourceMapType, String resourceMapField) {

    // Complete the IRB contract
    sw.println("public ResourcePrototype[] getResources() {");
    sw.indent();
    sw.println("return new ResourcePrototype[] {");
    sw.indent();
    for (List<JMethod> methods : taskList.values()) {
      for (JMethod m : methods) {
        sw.println(m.getName() + "(), ");
      }
    }
    sw.outdent();
    sw.println("};");
    sw.outdent();
    sw.println("}");

    // Map implementation for dev mode.
    sw.println("public ResourcePrototype getResource(String name) {");
    sw.indent();
    sw.println("if (GWT.isScript()) {");
    sw.indent();
    sw.println("return getResourceNative(name);");
    sw.outdent();
    sw.println("} else {");
    sw.indent();
    sw.println("if (" + resourceMapField + " == null) {");
    sw.indent();
    sw.println(resourceMapField + " = new "
        + resourceMapType.getParameterizedQualifiedSourceName() + "();");
    for (List<JMethod> list : taskList.values()) {
      for (JMethod m : list) {
        sw.println(resourceMapField + ".put(\"" + m.getName() + "\", "
            + m.getName() + "());");
      }
    }
    sw.outdent();
    sw.println("}");
    sw.println("return resourceMap.get(name);");
    sw.outdent();
    sw.println("}");
    sw.outdent();
    sw.println("}");

    // Use a switch statement as a fast map for script mode.
    sw.println("private native ResourcePrototype "
        + "getResourceNative(String name) /*-{");
    sw.indent();
    sw.println("switch (name) {");
    sw.indent();
    for (List<JMethod> list : taskList.values()) {
      for (JMethod m : list) {
        sw.println("case '" + m.getName() + "': return this."
            + m.getJsniSignature() + "();");
      }
    }
    sw.outdent();
    sw.println("}");
    sw.println("return null;");
    sw.outdent();
    sw.println("}-*/;");
  }
}
