/**
 * Copyright (c) 2002-2007 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 * 
 * Contributors: 
 *   IBM - Initial API and implementation
 */
package org.eclipse.emf.codegen.jet;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.osgi.framework.Bundle;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.emf.codegen.CodeGenPlugin;
import org.eclipse.emf.codegen.util.CodeGenUtil;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.Monitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.UniqueEList;


/**
 * A convenience class for compiling and invoking a template dynamically.
 */
public class JETEmitter
{
  protected String projectName = ".JETEmitters";
  protected Method method;
  protected Object object;
  protected String [] templateURIPath;
  protected String templateURI;
  protected ClassLoader classLoader;
  protected String encoding;
  protected List<IClasspathEntry> classpathEntries = new ArrayList<IClasspathEntry>();
  protected Map<String, String> javaOptions = new HashMap<String, String>();

  /**
   * Creates an instance with the specified template URI.
   * @param templateURI the URI of a JET template.
   */
  public JETEmitter(String templateURI)
  {
    this.templateURI = templateURI;
    this.classLoader = JETEmitter.this.getClass().getClassLoader();
  }

  /**
   * Creates an instance with the specified template URI path and relative template URI.
   * The relative URI will be resolved against each path URI until a JET template is found.
   * @param templateURIPath a sequence of URIs that will be searched.
   * @param relativeTemplateURI the relative URI of a JET template.
   */
  public JETEmitter(String [] templateURIPath, String relativeTemplateURI)
  {
    this.templateURIPath = templateURIPath;
    this.templateURI = relativeTemplateURI;
    this.classLoader = JETEmitter.this.getClass().getClassLoader();
  }

  /**
   * Creates an instance with the specified template URI and class loader.
   * @param templateURI the URI of a JET template.
   * @param classLoader the class loader used to load classes when compiling the template.
   */
  public JETEmitter(String templateURI, ClassLoader classLoader)
  {
    this.templateURI = templateURI;
    this.classLoader = classLoader;
  }

  /**
   * Creates an instance with the specified template URI path, relative template URI, and class loader.
   * The relative URI will be resolved against each path URI until a JET template is found.
   * @param templateURIPath a sequence of URIs that will be searched.
   * @param relativeTemplateURI the relative URI of a JET template.
   * @param classLoader the class loader used to load classes when compiling the template.
   */
  public JETEmitter(String [] templateURIPath, String relativeTemplateURI, ClassLoader classLoader)
  {
    this.templateURIPath = templateURIPath;
    this.templateURI = relativeTemplateURI;
    this.classLoader = classLoader;
  }

  /**
   * Creates an instance with the specified template URI path, relative template URI, class loader, and encoding.
   * The relative URI will be resolved against each path URI until a JET template is found.
   * @param templateURIPath a sequence of URIs that will be searched.
   * @param relativeTemplateURI the relative URI of a JET template.
   * @param classLoader the class loader used to load classes when compiling the template.
   * @param encoding the encoding that will be used to read the templates.
   */
  public JETEmitter(String [] templateURIPath, String relativeTemplateURI, ClassLoader classLoader, String encoding)
  {
    this.templateURIPath = templateURIPath;
    this.templateURI = relativeTemplateURI;
    this.classLoader = classLoader;
    this.encoding = encoding;
  }

  /**
   * Returns the name of the project where JET templates will be compiled.
   * @return the name of the project where JET templates will be compiled.
   */
  public String getProjectName()
  {
    return projectName;
  }

  /**
   * Sets the name of the project where JET templates will be compiled.
   * @param projectName the name of the project.
   */
  public void setProjectName(String projectName)
  {
    this.projectName = projectName;
  }

  /**
   * Returns a list of classpath entries that will be added to the classpath of the internal {@link #getProjectName project}
   * where emitted JET templates are compiled.
   * <p>
   * This method must be called <b>before</b>
   * {@link #initialize(Monitor) initialize} or {@link #generate(Monitor, Object[]) generate}
   * are called.
   * @return a list of classpath entries.
   */
  public List<IClasspathEntry> getClasspathEntries()
  {
    return classpathEntries;
  }

  /**
   * Returns options that will be {@link IJavaProject#setOption(String, String) applied} to the Java project the first time it's created.
   * @return the Java options.
   */
  public Map<String, String> getJavaOptions()
  {
    return javaOptions;
  }

  /**
   * Returns the object used as the target for the template.
   * @return the object used as target for the template.
   */
  public Object getObject()
  {
    return object;
  }

  /**
   * Returns the object used as the target for the template;
   * it ensures that the returned object is using the given lineDelimiter 
   * and creates a new one if necessary.
   * @return the object used as target for the template.
   * @since 2.3
   */
  public Object getObject(String lineDelimiter)
  {
    if (lineDelimiter != null)
    {
      if (object != null)
      {
        Class<?> javaClass = object.getClass();
        try
        {
          Field field = javaClass.getField("NL");
          Object nl = field.get(object);
          if (lineDelimiter.equals(nl))
          {
            return object;
          }
          else
          {
            object = null;
          }
        }
        catch (Throwable exception)
        {
          CodeGenPlugin.INSTANCE.log(exception);
        }
      }
      
      if (object == null && method != null)
      {
        Class<?> javaClass = method.getDeclaringClass();
        try
        {
          Method method = javaClass.getMethod("create", String.class);
          object = method.invoke(null, lineDelimiter);
        }
        catch (Throwable exception)
        {
          CodeGenPlugin.INSTANCE.log(exception);
        }
      }
    }
    return object;
  }

  /**
   * Sets the object used as the target of the template.
   * @param object the object used as target of the template.
   */
  public void setObject(Object object)
  {
    this.object = object;
  }

  /**
   * Returns the method that will be invoked when {@link #generate(Monitor, Object[]) generate} called.
   * @return the generator method.
   */
  public Method getMethod()
  {
    return method;
  }

  /**
   * Set the method that will be invoked when {@link #generate(Monitor, Object[]) generate} called.
   * @param method the generator method.
   */
  public void setMethod(Method method)
  {
    this.method = method;
    if ((method.getModifiers() & Modifier.STATIC) == 0 && object == null)
    {
      try
      {
        object = method.getDeclaringClass().getDeclaredConstructor().newInstance();
      }
      catch (RuntimeException exception)
      {
        CodeGenPlugin.INSTANCE.log(exception);
      }
      catch (InstantiationException exception)
      {
        CodeGenPlugin.INSTANCE.log(exception);
      }
      catch (IllegalAccessException exception)
      {
        CodeGenPlugin.INSTANCE.log(exception);
      }
      catch (InvocationTargetException exception)
      {
        CodeGenPlugin.INSTANCE.log(exception);
      }
      catch (NoSuchMethodException exception)
      {
        CodeGenPlugin.INSTANCE.log(exception);
      }
    }
  }

  protected static class MyBaseJETCompiler extends JETCompiler
  {
    protected ClassLoader classLoader;

    public MyBaseJETCompiler(String templateURI, ClassLoader classLoader) throws JETException
    {
      super(templateURI);
      this.classLoader = classLoader;
    }

    public MyBaseJETCompiler(String templateURI, String encoding, ClassLoader classLoader) throws JETException
    {
      super(templateURI, encoding);
      this.classLoader = classLoader;
    }

    public MyBaseJETCompiler(String [] templateURIPath, String relativeTemplateURI, ClassLoader classLoader) throws JETException
    {
      super(templateURIPath, relativeTemplateURI);
      this.classLoader = classLoader;
    }

    public MyBaseJETCompiler(String [] templateURIPath, String relativeTemplateURI, String encoding, ClassLoader classLoader) throws JETException
    {
      super(templateURIPath, relativeTemplateURI, encoding);
      this.classLoader = classLoader;
    }

    @Override
    protected void handleNewSkeleton()
    {
      String packageName = skeleton.getPackageName();
      String skeletonClassName = skeleton.getClassName();
      String qualifiedSkeletonClassName = (packageName.length() == 0 ? "" : packageName + ".") + skeletonClassName;

      if (classLoader != null)
      {
        try
        {
          Class<?> theClass = classLoader.loadClass(qualifiedSkeletonClassName);
          if (theClass != null)
          {
            skeleton.setClassName(skeletonClassName += "_");
          }
        }
        catch (Exception exception)
        {
          // Ignore
        }
      }
    }
  }
  
  protected class MyJETCompiler extends MyBaseJETCompiler
  {
    public MyJETCompiler(String templateURI) throws JETException
    {
      super(templateURI, JETEmitter.this.classLoader);
    }

    public MyJETCompiler(String templateURI, String encoding) throws JETException
    {
      super(templateURI, encoding, JETEmitter.this.classLoader);
    }

    public MyJETCompiler(String [] templateURIPath, String relativeTemplateURI) throws JETException
    {
      super(templateURIPath, relativeTemplateURI, JETEmitter.this.classLoader);
    }

    public MyJETCompiler(String [] templateURIPath, String relativeTemplateURI, String encoding) throws JETException
    {
      super(templateURIPath, relativeTemplateURI, encoding, JETEmitter.this.classLoader);
    }
  }

  /**
   * Compiles the template to {@link #setMethod set} the method will be invoked to generate template results.
   * @param progressMonitor the progress monitor for tracking progress.
   */
  public void initialize(IProgressMonitor progressMonitor) throws JETException
  {
    initialize(BasicMonitor.toMonitor(progressMonitor));
  }
  
  /**
   * Compiles the template to {@link #setMethod set} the method will be invoked to generate template results.
   * @param progressMonitor the progress monitor for tracking progress.
   */
  public void initialize(Monitor progressMonitor) throws JETException
  {
    if (EMFPlugin.IS_ECLIPSE_RUNNING)
    {
      EclipseHelper.initialize(progressMonitor, this);
    }
  }
  
  /**
   * Registers the specified classpath variable in the workspace  
   * and adds a classpath entry to the {@link #getClasspathEntries() classpath entry list}.
   * The variable is bound to the first runtime library JAR file in the list
   * of runtime libraries of the specified plugin.
   * When {@link #generate(Monitor, Object[]) generate} is called 
   * and it needs to generate the {@link #getMethod method} to invoke,
   * it will call {@link #initialize(Monitor) initialize} 
   * which will add the classpath entries to the {@link #getProjectName project} created to hold and compile the emitted template.
   * <p>
   * This method must be called <b>before</b>
   * {@link #initialize(Monitor) initialize} or {@link #generate(Monitor, Object[]) generate}
   * are called.
   * <p>
   * The specified plugin ID must be the ID of an existing plugin.
   * The referenced plugin must have at least one 
   * runtime library JAR file in its plugin descriptor.
   * If the plugin descriptor's list of runtime libraries contains more than one JAR file, 
   * the classpath variable will be bound to the <b>first</b>
   * library in the list.
   * @param variableName name of the classpath variable
   * @param pluginID the ID of an existing plugin 
   */
  public void addVariable(String variableName, String pluginID) throws JETException
  {
    if (EMFPlugin.IS_ECLIPSE_RUNNING && method == null)
    {
      EclipseHelper.addVariable(this, variableName, pluginID);
    }
  }

  /**
   * Invokes the emitter method on the compiled template and returns the result.
   * @return the template result.
   */
  public String generate(IProgressMonitor progressMonitor, Object [] arguments) throws JETException
  {
    return generate(BasicMonitor.toMonitor(progressMonitor), arguments);
  }
  
  /**
   * Invokes the emitter method on the compiled template and returns the result.
   * @return the template result.
   */
  public String generate(Monitor progressMonitor, Object [] arguments) throws JETException
  {
    return generate(progressMonitor, arguments, null);
  }

  /**
   * Invokes the emitter method on the compiled template and returns the result.
   * @return the template result.
   * @since 2.3
   */
  public String generate(Monitor progressMonitor, Object [] arguments, String lineDelimiter) throws JETException
  {
    if (method == null)
    {
      initialize(progressMonitor);
    }

    String result = "";
    if (method != null)
    {
      try
      {
        result = (String)method.invoke(getObject(lineDelimiter), arguments);
      }
      catch (IllegalAccessException exception)
      {
        throw new JETException(exception);
      }
      catch (InvocationTargetException exception)
      {
        throw new JETException(exception);
      }
    }
    return result;
  }

  private static class EclipseHelper
  {
    public static void initialize(Monitor monitor, final JETEmitter jetEmitter) throws JETException
    {
      IProgressMonitor progressMonitor = BasicMonitor.toIProgressMonitor(monitor);
      progressMonitor.beginTask("", 10);
      progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_GeneratingJETEmitterFor_message", new Object [] { jetEmitter.templateURI }));

      final IWorkspace workspace = ResourcesPlugin.getWorkspace();
      IJavaModel javaModel = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
  
      try
      {
        final JETCompiler jetCompiler = 
          jetEmitter.templateURIPath == null ? 
            new MyBaseJETCompiler(jetEmitter.templateURI, jetEmitter.encoding, jetEmitter.classLoader) :
            new MyBaseJETCompiler(jetEmitter.templateURIPath, jetEmitter.templateURI, jetEmitter.encoding, jetEmitter.classLoader);
  
        progressMonitor.subTask
          (CodeGenPlugin.getPlugin().getString("_UI_JETParsing_message", new Object [] { jetCompiler.getResolvedTemplateURI() }));
        jetCompiler.parse();
        progressMonitor.worked(1);

        String packageName = jetCompiler.getSkeleton().getPackageName();

        if (jetEmitter.templateURIPath != null)
        {
          URI templateURI = URI.createURI(jetEmitter.templateURIPath[0]);
          URLClassLoader theClassLoader = null;
          if (templateURI.isPlatformResource())
          {
            // If the template path points at a project with a JET Nature, 
            // then we will assume that the templates we want to use are already compiled in this plugin Java project.
            // 
            IProject project = workspace.getRoot().getProject(templateURI.segment(1));
            if (JETNature.getRuntime(project) != null)
            {
                List<URL> urls = new ArrayList<URL>();
                
                // Compute the URL for where the classes for this project will be located.
                //
                IJavaProject javaProject = JavaCore.create(project);
                urls.add(new File(project.getLocation() + "/" + javaProject.getOutputLocation().removeFirstSegments(1) + "/").toURI().toURL());
                
                // Compute the URLs for all the output folder of all the project dependencies.
                //
                for (IClasspathEntry classpathEntry :  javaProject.getResolvedClasspath(true))
                {
                  if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_PROJECT)
                  {
                    IPath projectPath = classpathEntry.getPath();
                    IProject otherProject = workspace.getRoot().getProject(projectPath.segment(0));
                    IJavaProject otherJavaProject = JavaCore.create(otherProject);
                    urls.add(new File(otherProject.getLocation() + "/" + otherJavaProject.getOutputLocation().removeFirstSegments(1) + "/").toURI().toURL());
                  }
                }
  
              // Define a class loader that will look in the URLs first, 
              // and if it doesn't find the class there, uses the emitter's loader.
              //
              theClassLoader = 
                new URLClassLoader(urls.toArray(new URL [0]))
                {
                  @Override
                  public Class<?> loadClass(String className) throws ClassNotFoundException
                  {
                    try
                    {
                      return super.loadClass(className);
                    }
                    catch (ClassNotFoundException classNotFoundException)
                    {
                      return jetEmitter.classLoader.loadClass(className);
                    }
                  }
                };
            }
          }
          else if (templateURI.isPlatformPlugin())
          {
            final Bundle bundle = Platform.getBundle(templateURI.segment(1));
            if (bundle != null)
            {
              // Define a class loader that will look up the class in the bundle,
              // and if it doesn't find it there, will look in the parent.
              //
              theClassLoader = 
                new URLClassLoader(new URL [0], jetEmitter.classLoader)
                {
                  @Override
                  public Class<?> loadClass(String className) throws ClassNotFoundException
                  {
                    try
                    {
                      return bundle.loadClass(className);
                    }
                    catch (ClassNotFoundException classNotFoundException)
                    {
                      return super.loadClass(className);
                    }
                  }
                };
            }
          }

          if (theClassLoader != null)
          {
            // Strip off the trailing "_" and load that class.
            //
            String className = (packageName.length() == 0 ? "" : packageName + ".") + jetCompiler.getSkeleton().getClassName();
            if (className.endsWith("_"))
            {
              className = className.substring(0, className.length() - 1);
            }

            try
            {
              Class<?> theClass = theClassLoader.loadClass(className);

              // Check that the class is actually different from the one that's directly visible to the JETEmitter.
              //
              Class<?> theOtherClass = null;
              try
              {
                 theOtherClass = jetEmitter.classLoader.loadClass(className);
              }
              catch (ClassNotFoundException exception)
              {
                // Ignore.
              }
              if (theClass != theOtherClass)
              {
                String methodName = jetCompiler.getSkeleton().getMethodName();
                Method [] methods = theClass.getDeclaredMethods();
                for (int i = 0; i < methods.length; ++i)
                {
                  if (methods[i].getName().equals(methodName))
                  {
                    jetEmitter.setMethod(methods[i]);
                    break;
                  }
                }
  
                // Don't do any of the other normally dynamic JETEmitter project processing.
                //
                return;
              }
            }
            catch (ClassNotFoundException exception)
            {
              // Continue processing dynamically as normal.
            }
          }
        }

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        jetCompiler.generate(outputStream);
        final InputStream contents = new ByteArrayInputStream(outputStream.toByteArray());
  
        if (!javaModel.isOpen())
        {
          javaModel.open(BasicMonitor.subProgress(progressMonitor, 1));
        }
        else
        {
          progressMonitor.worked(1);
        }
  
        final IProject project = workspace.getRoot().getProject(jetEmitter.getProjectName());
        progressMonitor.subTask
          (CodeGenPlugin.getPlugin().getString("_UI_JETPreparingProject_message", new Object [] { project.getName() }));
  
        IJavaProject javaProject;
        if (!project.exists())
        {
          progressMonitor.subTask("JET creating project " + project.getName());
          project.create(BasicMonitor.subProgress(progressMonitor, 1));
          progressMonitor.subTask
            (CodeGenPlugin.getPlugin().getString("_UI_JETCreatingProject_message", new Object [] { project.getName() }));
          IProjectDescription description = workspace.newProjectDescription(project.getName());
          description.setNatureIds(new String [] { JavaCore.NATURE_ID });
          description.setLocation(null);
          project.open(BasicMonitor.subProgress(progressMonitor, 1));
          project.setDescription(description, BasicMonitor.subProgress(progressMonitor, 1));
          javaProject = JavaCore.create(project);

          for (Map.Entry<String, String> option : jetEmitter.getJavaOptions().entrySet())
          {
            javaProject.setOption(option.getKey(), option.getValue());
          }
        }
        else
        {
          project.open(BasicMonitor.subProgress(progressMonitor, 5));
          IProjectDescription description = project.getDescription();
          description.setNatureIds(new String [] { JavaCore.NATURE_ID });
          project.setDescription(description, BasicMonitor.subProgress(progressMonitor, 1));
          javaProject = JavaCore.create(project);
        }

        // Get the existing classpath and remove the project root if necessary.
        // Any new non-duplicate entries will be added to this.
        //
        List<IClasspathEntry> classpath = new UniqueEList<IClasspathEntry>(Arrays.asList(javaProject.getRawClasspath()));
        for (int i = 0, len = classpath.size(); i < len; i++)
        {
          IClasspathEntry entry = classpath.get(i);
          if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE && ("/" + project.getName()).equals(entry.getPath().toString()))
          {
            classpath.remove(i);
          }
        }

        // Add the new entries, including source, JRE container, and added variables and classpath containers. 
        //
        progressMonitor.subTask
          (CodeGenPlugin.getPlugin().getString("_UI_JETInitializingProject_message", new Object [] { project.getName() }));
        IClasspathEntry classpathEntry = 
          JavaCore.newSourceEntry(new Path("/" + project.getName() + "/src"));

        IClasspathEntry jreClasspathEntry = JavaCore.newContainerEntry(new Path("org.eclipse.jdt.launching.JRE_CONTAINER"));

        classpath.add(classpathEntry);
        classpath.add(jreClasspathEntry);
        classpath.addAll(jetEmitter.classpathEntries);
  
        IFolder sourceFolder = project.getFolder(new Path("src"));
        if (!sourceFolder.exists())
        {
          sourceFolder.create(false, true, BasicMonitor.subProgress(progressMonitor, 1));
        }
        IFolder runtimeFolder = project.getFolder(new Path("bin"));
        if (!runtimeFolder.exists())
        {
          runtimeFolder.create(false, true, BasicMonitor.subProgress(progressMonitor, 1));
        }
  
        javaProject.setRawClasspath(classpath.toArray(new IClasspathEntry[classpath.size()]), BasicMonitor.subProgress(progressMonitor, 1));
  
        javaProject.setOutputLocation(new Path("/" + project.getName() + "/bin"), BasicMonitor.subProgress(progressMonitor, 1));
  
        javaProject.close();
  
        progressMonitor.subTask
          (CodeGenPlugin.getPlugin().getString("_UI_JETOpeningJavaProject_message", new Object [] { project.getName() }));
        javaProject.open(BasicMonitor.subProgress(progressMonitor, 1));
  
        IPackageFragmentRoot [] packageFragmentRoots = javaProject.getPackageFragmentRoots();
        IPackageFragmentRoot sourcePackageFragmentRoot = null;
        for (int j = 0; j < packageFragmentRoots.length; ++j)
        {
          IPackageFragmentRoot packageFragmentRoot = packageFragmentRoots[j];
          if (packageFragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE)
          {
            sourcePackageFragmentRoot = packageFragmentRoot;
            break;
          }
        }
  
        StringTokenizer stringTokenizer = new StringTokenizer(packageName, ".");
        IProgressMonitor subProgressMonitor = BasicMonitor.subProgress(progressMonitor, 1);
        subProgressMonitor.beginTask("", stringTokenizer.countTokens() + 4);
        subProgressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_CreateTargetFile_message"));
        IContainer sourceContainer = sourcePackageFragmentRoot == null ? project : (IContainer)sourcePackageFragmentRoot.getCorrespondingResource();
        while (stringTokenizer.hasMoreElements())
        {
          String folderName = stringTokenizer.nextToken();
          sourceContainer = sourceContainer.getFolder(new Path(folderName));
          if (!sourceContainer.exists())
          {
            ((IFolder)sourceContainer).create(false, true, BasicMonitor.subProgress(subProgressMonitor, 1));
          }
        }
        IFile targetFile = sourceContainer.getFile(new Path(jetCompiler.getSkeleton().getClassName() + ".java"));
        if (!targetFile.exists())
        {
          subProgressMonitor.subTask
            (CodeGenPlugin.getPlugin().getString("_UI_JETCreating_message", new Object [] { targetFile.getFullPath() }));
          targetFile.create(contents, true, BasicMonitor.subProgress(subProgressMonitor, 1));
        }
        else
        {
          subProgressMonitor.subTask
            (CodeGenPlugin.getPlugin().getString("_UI_JETUpdating_message", new Object [] { targetFile.getFullPath() }));
          targetFile.setContents(contents, true, true, BasicMonitor.subProgress(subProgressMonitor, 1));
        }

        subProgressMonitor.subTask
          (CodeGenPlugin.getPlugin().getString("_UI_JETBuilding_message", new Object [] { project.getName() }));
        project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, BasicMonitor.subProgress(subProgressMonitor, 1));
  
        IMarker [] markers = targetFile.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
        boolean errors = false;
        for (int i = 0; i < markers.length; ++i)
        {
          IMarker marker = markers[i];
          if (marker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO) == IMarker.SEVERITY_ERROR)
          {
            errors = true;
            subProgressMonitor.subTask
              (marker.getAttribute(IMarker.MESSAGE) + " : " + 
                 (CodeGenPlugin.getPlugin().getString
                   ("jet.mark.file.line", 
                    new Object []
                    {
                      targetFile.getLocation(), 
                      marker.getAttribute(IMarker.LINE_NUMBER)
                    })));
          }
        }
  
        if (!errors)
        {
          subProgressMonitor.subTask
            (CodeGenPlugin.getPlugin().getString
               ("_UI_JETLoadingClass_message", new Object [] { jetCompiler.getSkeleton().getClassName() + ".class" }));
  
          // Construct a proper URL for relative lookup.
          //
          List<URL> urls = new ArrayList<URL>();
          urls.add(new File(project.getLocation() + "/" + javaProject.getOutputLocation().removeFirstSegments(1) + "/").toURI().toURL());
          
          // Determine all the bundles that this project depends on.
          //
          final Set<Bundle> bundles = new HashSet<Bundle>();
          LOOP:
          for (IClasspathEntry jetEmitterClasspathEntry :  jetEmitter.getClasspathEntries())
          {
            IClasspathAttribute [] classpathAttributes = jetEmitterClasspathEntry.getExtraAttributes();
            if (classpathAttributes != null)
            {
              for (IClasspathAttribute classpathAttribute : classpathAttributes)
              {
                if (classpathAttribute.getName().equals(CodeGenUtil.EclipseUtil.PLUGIN_ID_CLASSPATH_ATTRIBUTE_NAME))
                {
                  Bundle bundle = Platform.getBundle(classpathAttribute.getValue());
                  if (bundle != null)
                  {
                    bundles.add(bundle);
                    continue LOOP;
                  }
                }
              }
            }
            // For any entry that doesn't correspond to a plugin in the running JVM, compute a URL for the classes.
            //
            urls.add(new URL("platform:/resource" + jetEmitterClasspathEntry.getPath() + "/"));
          }
          
          // Define a class loader that looks up classes using the URLs or the parent class loader,
          // and failing those, tries to look up the class in each bundle in the running JVM.
          //
          @SuppressWarnings("all")
          URLClassLoader theClassLoader = 
            new URLClassLoader(urls.toArray(new URL [0]), jetEmitter.classLoader)
            {
              @Override
              public Class<?> loadClass(String className) throws ClassNotFoundException
              {
                try
                {
                  return super.loadClass(className);
                }
                catch (ClassNotFoundException exception)
                {
                  for (Bundle bundle : bundles)
                  {
                    try
                    {
                      return bundle.loadClass(className);
                    }
                    catch (ClassNotFoundException exception2)
                    {
                      // Ignore because we'll rethrow the original exception eventually.
                    }
                  }
                  throw exception;
                }
              }
            };
          Class<?> theClass = 
            theClassLoader.loadClass
              ((packageName.length() == 0 ? "" : packageName + ".") + jetCompiler.getSkeleton().getClassName());
          String methodName = jetCompiler.getSkeleton().getMethodName();
          Method [] methods = theClass.getDeclaredMethods();
          for (int i = 0; i < methods.length; ++i)
          {
            if (methods[i].getName().equals(methodName))
            {
              jetEmitter.setMethod(methods[i]);
              break;
            }
          }
        }
  
        subProgressMonitor.done();
      }
      catch (CoreException exception)
      {
        throw new JETException(exception);
      }
      catch (Exception exception)
      {
        throw new JETException(exception);
      }
      finally
      {
        progressMonitor.done();
      }
    }
    
    public static void addVariable(JETEmitter jetEmitter, String variableName, String pluginID) throws JETException
    {
      Bundle bundle = Platform.getBundle(pluginID);
      URL classpathURL = bundle != null && Platform.inDevelopmentMode() ? bundle.getEntry(".classpath") : null;

      // If it doesn't correspond to a bundle, then try to process it as a project in the workspace.
      //
      if (bundle == null)
      {
        try
        {
          IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(pluginID);
          if (project != null)
          {
            classpathURL = new File(project.getLocation()+ "/.classpath").toURI().toURL();
          }
        }
        catch (MalformedURLException exception)
        {
          throw new JETException(exception);
        }
      }
      boolean addClasspathEntries = true;
      if (classpathURL != null)
      {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        documentBuilderFactory.setNamespaceAware(true);
        documentBuilderFactory.setValidating(false);
        try
        {
          DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
          Document document = documentBuilder.parse(new InputSource(classpathURL.toString()));
          for (Node child = document.getDocumentElement().getFirstChild(); child != null; child = child.getNextSibling())
          {
            if (child.getNodeType() == Node.ELEMENT_NODE)
            {
              Element classpathEntryElement = (Element)child;
              if ("classpathentry".equals(classpathEntryElement.getNodeName()) &&
                  "output".equals(classpathEntryElement.getAttribute("kind")))
              {
                URI uri = URI.createURI(classpathEntryElement.getAttribute("path")).resolve(URI.createURI(classpathURL.toString()));
                IWorkspace workspace = ResourcesPlugin.getWorkspace();
                IProject project = workspace.getRoot().getProject(jetEmitter.getProjectName());
                if (!project.exists())
                {
                  project.create(new NullProgressMonitor());
                }
                if (!project.isOpen())
                {
                  project.open(new NullProgressMonitor());
                }
                IFolder folder = project.getFolder("." + pluginID);
                if (!folder.exists())
                {
                  folder.createLink
                    (new Path(CommonPlugin.asLocalURI(uri).toFileString()).removeTrailingSeparator(),
                     IResource.ALLOW_MISSING_LOCAL, 
                     new NullProgressMonitor());
                }
                folder.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
                IPath path = folder.getFullPath();
                IClasspathEntry newLibraryEntry = 
                  JavaCore.newLibraryEntry
                    (path, 
                     null, 
                     null, 
                     null, 
                     bundle == null ? 
                        new IClasspathAttribute[0] : 
                        new IClasspathAttribute[] { JavaCore.newClasspathAttribute(CodeGenUtil.EclipseUtil.PLUGIN_ID_CLASSPATH_ATTRIBUTE_NAME, pluginID) }, 
                     true);
                jetEmitter.getClasspathEntries().add(newLibraryEntry);
                addClasspathEntries = false;
                break;
              }
            }
          }
        }
        catch (Exception exception)
        {
          CodeGenPlugin.INSTANCE.log(exception);
        }
      }
      if (addClasspathEntries)
      {
        CodeGenUtil.EclipseUtil.addClasspathEntries(jetEmitter.getClasspathEntries(), variableName, pluginID);
      }
    }
  }
}
