/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * IBM Corporation. - initial API and implementation
 * 20070523   158230 kathy@ca.ibm.com - Kathy Chan
 * 20071219   213356 kathy@ca.ibm.com - Kathy Chan
 * 20080325   222473 makandre@ca.ibm.com - Andrew Mak, Create EAR version based on the version of modules to be added
 * 20080429   213730 trungha@ca.ibm.com - Trung Ha
 * 20080507   229532 kathy@ca.ibm.com - Kathy Chan
 *******************************************************************************/

package org.eclipse.jst.ws.internal.consumption.common;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jst.j2ee.internal.common.J2EEVersionUtil;
import org.eclipse.jst.j2ee.internal.ejb.project.operations.EjbFacetInstallDataModelProvider;
import org.eclipse.jst.j2ee.internal.ejb.project.operations.IEjbFacetInstallDataModelProperties;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.j2ee.project.facet.AppClientFacetInstallDataModelProvider;
import org.eclipse.jst.j2ee.project.facet.IAppClientFacetInstallDataModelProperties;
import org.eclipse.jst.j2ee.project.facet.IUtilityFacetInstallDataModelProperties;
import org.eclipse.jst.j2ee.project.facet.UtilityFacetInstallDataModelProvider;
import org.eclipse.jst.j2ee.web.project.facet.IWebFacetInstallDataModelProperties;
import org.eclipse.jst.j2ee.web.project.facet.WebFacetInstallDataModelProvider;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.consumption.ConsumptionMessages;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IFacetedProjectTemplate;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.VersionFormatException;
import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action.Type;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
import org.eclipse.wst.common.project.facet.core.runtime.RuntimeManager;
import org.osgi.framework.Bundle;

import com.ibm.icu.util.StringTokenizer;

/**
 * FacetUtils contains utility methods related to facets and templates.
 * <br/><br/>
 * Terminology used in the Javadoc in this class
 * <ul>
 * <li><b>facet</b>: An {@link IProjectFacet}</li>
 * <li><b>facet version</b>: An {@link IProjectFacetVersion} </li>
 * <li><b>facet runtime</b>: An {@link IRuntime}</li>
 * <li><b>faceted project</b>: An {@link IFacetedProject}. A faceted project may be obtained
 * from an IProject (@see ProjectFacetsManager#create)</li>
 * <li><b>template</b>: An {@link IFacetedProjectTemplate}. Conceptually this is similar to a project type.</li>
 * <li><b>required facet version</b>: A {@link RequiredFacetVersion}. Used by serviceRuntimes and clientRuntimes
 * to identify what they require in terms of facet versions.</li>
 * </ul>
 */
public class FacetUtils
{

  /**
   * Returns an array of valid projects. Valid projects include projects with the facets nature or
   * projects with the Java nature.
   * @return IProject[] an array of valid projects
   */
  public static IProject[] getAllProjects()
  {
    //Return all projects in the workspace that have the project facet nature or that do not have the project
    //facet nature but have the Java nature.
    IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
    ArrayList validProjects = new ArrayList();
    for (int i = 0; i < projects.length; i++)
    {
      try
      {
        IFacetedProject facProject = ProjectFacetsManager.create(projects[i]);
        if (facProject != null)
        {
          //Add it to the list
          validProjects.add(projects[i]);
        }
        else
        {
        	if (ResourceUtils.isJavaProject(projects[i]))
        	{
              validProjects.add(projects[i]);
        	}
        }
      }
      catch (CoreException ce)
      {        
      }      
    }
    return (IProject[])validProjects.toArray(new IProject[]{});
  }
  
  /**
   * Returns the facet versions on the given project.
   * @param projectName name of an existing project.
   * @returns Set containing elements of type {@link IProjectFacetVersion}. 
   * These are the facet versions currently installed on this project. If the project
   * is a Java project, facets are inferred from the Java project. Returns null 
   * <ul>
   * <li>if the project is not a faceted project or a Java project or</li>
   * <li>if the project does not exist or</li>
   * <li>if the project is null</li>
   * </ul>  
   */
  public static Set getFacetsForProject(String projectName)
  {
    Set facetVersions = null;
    IProject project = ProjectUtilities.getProject(projectName);
    if (project!=null && project.exists())
    {
      try
      {
        IFacetedProject fproject = ProjectFacetsManager.create(project);
        if (fproject != null)
        {
          facetVersions = fproject.getProjectFacets();
        } else
        {
          //If this is not a faceted project, it may still be okay if it is a Java project
          //and the client runtime supports a Java project.
          IJavaProject javaProject = null;              
          if (ResourceUtils.isJavaProject(project))
          {
        	javaProject = JavaCore.create(project);
            facetVersions = FacetUtils.getFacetsForJavaProject(javaProject);
          }
        }
      } catch (CoreException ce)
      {
    	  //Leaving the catch block empty. This method will return null if there
    	  //were any blow-ups in the facet API being called.
      }      
    }
    
    return facetVersions;
    
  }

  /**
   * Returns the facet runtime the given project is bound to.
   * @param projectName name of an existing project
   * @return {@link IRuntime} the project is bound to. Returns null
   * <ul>
   * <li>if the project is not bound to a facet runtime</li> 
   * <li>if the project does not exist</li>
   * <li>if the project is null</li>
   * </ul>
   */
  public static IRuntime getFacetRuntimeForProject(String projectName)
  {
    IProject project = ProjectUtilities.getProject(projectName);
    if (project!=null && project.exists())
    {
      try
      {
        IFacetedProject fproject = ProjectFacetsManager.create(project);
        if (fproject != null)
        {
          return fproject.getPrimaryRuntime();
        }
      } catch (CoreException ce)
      {
    	  //Leaving the catch block empty. This method will return null if there
    	  //were any blow-ups in the facet API being called.
      }
    }
    
    return null;    
  }
  
  
  /**
   * Returns a set of combinations of facet versions derived from the facet versions
   * in the provided arrayOfProjectFacetVersionArrays. For example, if 
   * arrayOfProjectFacetVersionArrays is a two dimenstional array of facet versions that has
   * a structure like this:<br/>
   * {{FacetA_version1, FacetA_version2},<br/>
   *  {FacetB_version1},<br/>
   *  {FacetC_version1, FacetC_version2}}<br/>
   * the following array of Sets will be returned:<br/>
   * {Set1, Set2, Set3, Set4}, where<br/>
   * Set1 = [FacetA_version1, FacetB_version1, FacetC_version1]<br/>
   * Set2 = [FacetA_version2, FacetB_version1, FacetC_version1]<br/>
   * Set3 = [FacetA_version1, FacetB_version1, FacetC_version2]<br/>
   * Set4 = [FacetA_version2, FacetB_version1, FacetC_version2]<br/>
   * <br/>
   * @param arrayOfProjectFacetVersionArrays a two dimensional array containing elements 
   * of type {@link IProjectFacetVersion}
   * @param returnValidOnly false if all combinations of facet versions are to be returned. 
   * true if only valid combinations of facet versions are to be returned.  
   * @return Set[] an array of Sets, where each Set contains elements of type {@link IProjectFacetVersion}. 
   */
  public static Set[] getFacetCombinations(IProjectFacetVersion[][] arrayOfProjectFacetVersionArrays, boolean returnValidOnly)  
  {
    ArrayList allCombinations = new ArrayList();
    //maxCount contains the number of versions in each array of IProjectFacetVersions.
    //initialize counter, which will be used to navigate arrayOfProjectFacetVersionArrays.
    int n = arrayOfProjectFacetVersionArrays.length;
    int[] maxCount = new int[n];
    int[] counter = new int[n];
    for (int i=0; i<n; i++)
    {
      maxCount[i] = arrayOfProjectFacetVersionArrays[i].length - 1;
      counter[i] = 0;
    }      
    
    //Navigate arrayOfProjectFacetVersionArrays to create all possible combinations.
    boolean done = false;
    while (!done)
    {
      //Create a combination of size n using current values in counter.
      //Add it to the list of all combinations, checking first for validity if returnValidOnly is true.
      Set combination = new HashSet();
      for (int j=0; j<n; j++)
      {
        IProjectFacetVersion pfv = arrayOfProjectFacetVersionArrays[j][counter[j]];
        combination.add(pfv);
      }
      
      //Check if valid.
      if (returnValidOnly)
      {
        Set actions = getInstallActions(combination);
		try {
			if( ProjectFacetsManager.check( new HashSet(), actions ).getSeverity() == IStatus.OK )        
	        {
	          allCombinations.add((combination));
	        }
		} catch (Throwable e) {
			// Do nothing if ProjectFacetsManager.check() throws exception.
			// TODO This try/catch will be unneccesary once WTP bug 137551 is fixed so that an OK Status 
			// 		would not be returned when an exception is thrown.
		}     
      }
      else
      {
        allCombinations.add((combination));
      }
      
      //Update the counters.
      for (int p=0; p<n; p++)
      {
        if ( (counter[p] + 1) <= maxCount[p])
        {
          (counter[p])++;
          break;
        }
        else
        {
          counter[p] = 0;
          if (p == n-1)
          {
            done = true;
          }
        }
      }
    }
    
    Set[] allCombinationsArray = (Set[])allCombinations.toArray(new Set[0]);    
    return allCombinationsArray;    
  }
  
  /**
   * Returns a set of facet versions given a template. The highest facet version of every fixed 
   * facet in the template is returned, with the exception of the jst.java facet, where the 1.4 
   * facet version is returned.
   * 
   * @param templateId id of a {@link IFacetedProjectTemplate}
   * @return Set containing elements of type {@link IProjectFacetVersion}
   */
  public static Set getInitialFacetVersionsFromTemplate(String templateId)
  {
    IFacetedProjectTemplate template = ProjectFacetsManager.getTemplate(templateId);
    Set fixedFacets = template.getFixedProjectFacets(); 
    HashSet initial = new HashSet(); 
    for (Iterator itr2 = fixedFacets.iterator(); itr2.hasNext(); ) 
    { 
      IProjectFacet facet = (IProjectFacet) itr2.next(); 
      IProjectFacetVersion highestFacetVersion = null;
      try {
    	  if (isJavaFacet(facet)) //special case the java facet because 1.4 is a better default than 5.0 for now.
    	  {
    		  highestFacetVersion = facet.getVersion("1.4");
    	  } else {
    		  highestFacetVersion = facet.getLatestVersion();
    	  }
      } catch (VersionFormatException e) {
      } catch (CoreException e) {
      }
      initial.add(highestFacetVersion); 
    }             
    
    return initial;
  }
  
  /**
   * Returns a set of facet versions given a template. The default facet version of every fixed 
   * facet in the template is returned.  If unable to get default versions, an empty set will be returned.
   * 
   * @param templateId id of a {@link IFacetedProjectTemplate}
   * @return Set containing elements of type {@link IProjectFacetVersion}
   */
  public static Set getDefaultFacetVersionsFromTemplate(String templateId)
  {
	  HashSet defaultSet = new HashSet(); 
	  try {
		  IFacetedProjectTemplate template = ProjectFacetsManager.getTemplate(templateId);
		  Set fixedFacets = template.getFixedProjectFacets(); 
		  for (Iterator itr2 = fixedFacets.iterator(); itr2.hasNext(); ) 
		  { 
			  IProjectFacet facet = (IProjectFacet) itr2.next(); 
			  IProjectFacetVersion defaultFacetVersion = null;
			  defaultFacetVersion = facet.getDefaultVersion();
			  defaultSet.add(defaultFacetVersion); 
		  }             
		  return defaultSet;
	  } catch (IllegalArgumentException e) {
		  return defaultSet;
	  } catch (VersionFormatException e) {
		  return defaultSet;
	  } 
	  
  }
  
  /**
   * Returns the template lables corresponding to the provided templateIds.
   * @param templateIds array of valid template ids. Each id must correspond to a {@link IFacetedProjectTemplate}.
   * @return String[] array of template labels.
   */
  public static String[] getTemplateLabels(String[] templateIds)
  {
    String[] labels = new String[templateIds.length];
    for (int i=0; i<templateIds.length; i++)
    {
      IFacetedProjectTemplate template = ProjectFacetsManager.getTemplate(templateIds[i]);      
      labels[i] = template.getLabel();
    }
    return labels;
    
  }
  
  /**
   * Returns the id of a template given its label. 
   * 
   * @param templateLabel label of a template
   * @return template id or empty String if no {@link IFacetedProjectTemplate} with the
   * given templateLabel could be found.
   */
  public static String getTemplateIdByLabel(String templateLabel)
  {
    for( Iterator itr = ProjectFacetsManager.getTemplates().iterator(); itr.hasNext(); )
    {
        final IFacetedProjectTemplate template = (IFacetedProjectTemplate) itr.next();
        if (template.getLabel().equals(templateLabel))
        {
          return template.getId();

        }
    }
    
    return "";
  }
  
  /**
   * Returns the label of a template given its id 
   * 
   * @param templateId id of a {@link IFacetedProjectTemplate}
   * @return template label
   */  
  public static String getTemplateLabelById(String templateId)
  {
    IFacetedProjectTemplate template = ProjectFacetsManager.getTemplate(templateId);
    return template.getLabel();
  }
  
  /**
   * Returns a set of install actions for the provided facet version
   * 
   * @param projectFacetVersions Set containing elements of type {@link IProjectFacetVersion}
   * @return Set containing elements of type {@link Action} with the type attribute set to Type.INSTALL
   * The set contains one Action for each {@link IProjectFacetVersion} in projectFacetVersions.
   */
  public static Set getInstallActions(Set projectFacetVersions)
  {
    HashSet actions = new HashSet();
    
    Iterator facets = projectFacetVersions.iterator();
    
    while(facets.hasNext())
    {
    	IProjectFacetVersion fv = (IProjectFacetVersion)facets.next();
    	if (fv != null) {
    		IProjectFacet pf = fv.getProjectFacet();
    		Action action = new Action(Type.INSTALL, fv, getConfigObject(pf));
    		actions.add(action);
    	}
    }
    
    return actions;
  }
  
  /**
   * Returns the data model config object for the given project facet
   * For J2EE facets, set Add_TO_EAR properties of the data model to false, 
   * for other facets, just return null
   * @param facetID
   * @return data model config object
   */
  public static Object getConfigObject(IProjectFacet projectFacet)
  {
	  
	  IDataModel dm = null;
	  if (projectFacet != null) {
		  String facetId = projectFacet.getId();
		  if (facetId != null) {
			  // set Add to EAR to false
			  if (facetId.equals(IModuleConstants.JST_WEB_MODULE)) { 
				  dm = DataModelFactory.createDataModel(new WebFacetInstallDataModelProvider());
				  dm.setBooleanProperty(IWebFacetInstallDataModelProperties.ADD_TO_EAR, false);
			  } else if (facetId.equals(IModuleConstants.JST_EJB_MODULE)) {
				  dm = DataModelFactory.createDataModel(new EjbFacetInstallDataModelProvider());
				  dm.setBooleanProperty(IEjbFacetInstallDataModelProperties.ADD_TO_EAR, false);
			  } else if (facetId.equals(IModuleConstants.JST_APPCLIENT_MODULE)) {
				  dm = DataModelFactory.createDataModel(new AppClientFacetInstallDataModelProvider());
				  dm.setBooleanProperty(IAppClientFacetInstallDataModelProperties.ADD_TO_EAR, false);
			  } else if (facetId.equals(IModuleConstants.JST_UTILITY_MODULE)) {
				  dm = DataModelFactory.createDataModel(new UtilityFacetInstallDataModelProvider());
				  dm.setBooleanProperty(IUtilityFacetInstallDataModelProperties.ADD_TO_EAR, false);
			  }
		  }
	  }
	  return dm;
  }
  /**
   * Returns the {@link FacetMatcher} calculated when checking the required facet versions 
   * against the facet versions.
   * 
   * @param requiredFacetVersions array of required facet versions
   * @param projectFacetVersions facet versions to check against. Set containing elements of type 
   * {@link IProjectFacetVersion}
   * @return FacetMatcher with the following characteristics:
   * <ul>
   * <li><b>isMatch</b>: returns true if the required facet versions already exist in the facet versions
   * or can be added to the facet versions. isMatch will return false otherwise.</li>
   * <li><b>getFacetsTested</b>: returns the same set of facet versions as the input parameter, projectFacetVersions</li>
   * <li><b>getFacetsThatMatched</b>: if isMatch returns false, getFacetsThatMatched returns null. If isMatch returns true, 
   * getFacetsThatMatched returns the subset of facet versions in the input parameter, projectFacetVersions, 
   * that matched one of the required facet versions. This may be an empty set.</li>
   * <li><b>getFacetsToAdd</b>: if isMatch returns false, getFacetsToAdd returns null. If isMatch returns true, 
   * getFacetsToAdd returns the subset of facet versions that would need to be added to the facet versions in
   * projectFacetVersions in order to satisfy the requirements of the required facet versions. This may be
   * an empty set.</li>
   * </ul>
   */
  public static FacetMatcher match(RequiredFacetVersion[] requiredFacetVersions, Set projectFacetVersions)
  {
    FacetMatcher fm = new FacetMatcher();
    fm.setFacetsTested(projectFacetVersions);
    HashSet facetsToAdd = new HashSet();
    HashSet requiredFacetVersionsToAdd = new HashSet();
    HashSet facetsThatMatched = new HashSet();
    for (int i=0; i<requiredFacetVersions.length; i++)
    {
      RequiredFacetVersion rfv = requiredFacetVersions[i];
      IProjectFacetVersion rpfv = rfv.getProjectFacetVersion();
      String rid = rpfv.getProjectFacet().getId();
      String rv = rpfv.getVersionString();
      boolean facetPresent = false;

      //Is the project facet present? or a later version of applicable.
      Iterator itr = projectFacetVersions.iterator();
      while(itr.hasNext())
      {
        IProjectFacetVersion pfv = (IProjectFacetVersion)itr.next();
        String id = pfv.getProjectFacet().getId();
        String version = pfv.getVersionString();
        if (rid.equals(id))
        {
          if (rv.equals(version))
          {
            //found an exact match
            facetPresent = true;
            facetsThatMatched.add(pfv);
          }
          else
          {
            if (rfv.getAllowNewer())
            {
              if (greaterThan(version, rv))
              {
                //found a match
                facetPresent = true;
                facetsThatMatched.add(pfv);
              }
            }
          }
          //No need to keep iterating since we hit a facet with the same id;
          break;
        }
      }
      
      //if not present, put it in the list to check if it can be added.
      if (!facetPresent)
      {
        facetsToAdd.add(rpfv);
        requiredFacetVersionsToAdd.add(rfv);
      }
      
    }
    
    //Check if the facetsToAdd can be added
    if (requiredFacetVersionsToAdd.size() > 0)
    {
      //Test all possible combinations of the facets that need to be added
      //Create an array of arrays. Each element of the array will contain the array
      //of the permitted IProjectFacetVersions for each required facet.
      boolean facetsCanBeAdded = false;
      Iterator itr = requiredFacetVersionsToAdd.iterator();
      ArrayList projectFacetVersionArrays = new ArrayList();      

      while (itr.hasNext())
      {
        RequiredFacetVersion reqFacetVersion = (RequiredFacetVersion) itr.next();
        IProjectFacetVersion[] versions = reqFacetVersion.getAllowedProjectFacetVersions();
        if (versions != null && versions.length > 0)
        {          
          //Add the array of versions to the list of arrays.
          projectFacetVersionArrays.add(versions);
        }
      }
      
      IProjectFacetVersion[][] arrayOfProjectFacetVersionArrays = (IProjectFacetVersion[][])projectFacetVersionArrays.toArray(new IProjectFacetVersion[0][0]);
      Set[] combinations = getFacetCombinations(arrayOfProjectFacetVersionArrays, false);
      for (int i=0; i<combinations.length; i++)
      {
        //Check if the set can be added. If so, this is a match. Update the facet matcher and break.
        Set actions = getInstallActions(combinations[i]);
        try {
			if( ProjectFacetsManager.check( projectFacetVersions, actions ).getSeverity() == IStatus.OK )
			{
			  //Facets can be added so there is a match
			  facetsCanBeAdded=true;
			  fm.setMatch(true);
			  fm.setFacetsThatMatched(facetsThatMatched);
			  fm.setFacetsToAdd(combinations[i]);
			  break;
			}
		} catch (Throwable e) {
			// Do nothing if ProjectFacetsManager.check() throws exception.
			// TODO This try/catch will be unneccesary once WTP bug 137551 is fixed so that an OK Status 
			// 		would not be returned when an exception is thrown.
		}                
      }
      
      
      if (!facetsCanBeAdded)
      {
        fm.setMatch(false);
      }      
    }
    else
    {
      //There are no facets to add.
      fm.setMatch(true);
      fm.setFacetsThatMatched(facetsThatMatched);
      fm.setFacetsToAdd(facetsToAdd);
    }
    
    return fm;
  }
    
  /**
   * Adds facet versions to the provided project if required based on checking provided 
   * required facet versions against the facet versions already installed on project.
   * 
   * @param project IProject which exists in the workspace
   * @param rfvs array of required facet versions.
   * @param monitor progress monitor
   * @return IStatus with severity IStatus.ERROR
   * <ul>
   * <li>if the project does not exist or</li>
   * <li>if the project is not open or</li>
   * <li>an attempt to add facet versions to the project resulted in an error.</li>
   * </ul> 
   * Otherwise, returns an IStatus with severity IStatus.OK    
   */
  public static IStatus addRequiredFacetsToProject(IProject project, RequiredFacetVersion[] rfvs, IProgressMonitor monitor)
  {
    IStatus status = Status.OK_STATUS;
    
    Set missingFacets = null;
    Set facetsToAdd = new HashSet();
    try
    {
      IFacetedProject fProject = ProjectFacetsManager.create(project);
      if (fProject != null)
      {
        Set projectFacetVersions = fProject.getProjectFacets();
        FacetMatcher projectFacetMatcher = FacetUtils.match(rfvs, projectFacetVersions);
        if (projectFacetMatcher.isMatch())
        {
          missingFacets = projectFacetMatcher.getFacetsToAdd();
          if (missingFacets.size() > 0)
          {
            IRuntime fRuntime = null;
            fRuntime = FacetUtils.getFacetRuntimeForProject(project.getName());
            if (fRuntime != null)
            {  
              //Add the highest version supported by the runtime the project is bound to.
              Iterator missingFacetsItr = missingFacets.iterator();
              while (missingFacetsItr.hasNext())
              {
                IProjectFacet facet = ((IProjectFacetVersion)missingFacetsItr.next()).getProjectFacet();
                //Get the highest level of this facet supported by the runtime.
                List versions = null;
                try {
                    versions = facet.getSortedVersions(false);
                } catch (VersionFormatException e) {
                    Set versionSet = facet.getVersions();
                    Iterator itr = versionSet.iterator();
                    versions = new ArrayList();
                    while (itr.hasNext())
                    {
                        versions.add(itr.next());
                    }            
                } catch (CoreException e) {
                    Set versionSet = facet.getVersions();
                    Iterator itr = versionSet.iterator();
                    versions = new ArrayList();
                    while (itr.hasNext())
                    {
                        versions.add(itr.next());
                    }            
                }
                
                //Iterate over the versions in descending order and pick the 
                //first one that fRuntime supports.
                Iterator versionsItr = versions.iterator();
                while(versionsItr.hasNext())
                {
                  boolean match = false;
                  IProjectFacetVersion pfv = (IProjectFacetVersion)versionsItr.next();
                  Set pfvs = new HashSet();
                  pfvs.add(pfv);
                  
                  //Check the required facets to see if this version of this facet is supported.
                  for (int j=0; j<rfvs.length; j++)
                  {
                    RequiredFacetVersion rfv = rfvs[j];
                    IProjectFacetVersion rpfv = rfv.getProjectFacetVersion();
                    if (rpfv.getProjectFacet().getId().equals(pfv.getProjectFacet().getId()))
                    {
                      if (rpfv.getVersionString().equals(pfv.getVersionString()))
                      {
                        match = true;
                      }
                      else
                      {
                        if (rfv.getAllowNewer())
                        {
                          if (greaterThan(pfv.getVersionString(), rpfv.getVersionString()))
                          {
                            match = true;
                          }
                        }
                      }
                    }
                  }
                  
                  if (match)
                  {
                    //Check against Runtime
                    if (FacetUtils.doesRuntimeSupportFacets(fRuntime, pfvs))
                    {
                      //We have a match. Add this one to the master set.
                      facetsToAdd.add(pfv);
                      break;
                    }
                  }                            
                }              
              }
            }
            else
            {
              facetsToAdd = missingFacets;
            }

            status = addFacetsToProject(fProject, facetsToAdd);
          }
        }            
      }
    } catch (CoreException ce)
    {
      //Display an appropriate error message to the user.
      //A CoreException could have been thrown for any of the following three reasons
      //1. The project does not exist
      //2. The project is not open
      //3. There was a problem adding the facets to the project.
      
      if (!project.exists())
      {
        status = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_PROJECT_DOES_NOT_EXIST, new String[] { project.getName()}));            
      }
      else if (!project.isOpen())
      {
        status = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_PROJECT_IS_NOT_OPEN, new String[] { project.getName()}));            
      }
      else
      { 
        status = getErrorStatusForAddingFacets(project.getName(), facetsToAdd, ce);
      }
    }
    
    return status;
  }
  

  /**
   * Adds the provided set of facet versions to the provided faceted project
   * 
   * @param fproject A faceted project which exists in the workspace
   * @param projectFacetVersions A set containing elements of type {@link IProjectFacetVersion}
   * @return An IStatus with a severity of IStatus.OK if the facet 
   * versions were added successfully. Otherwise, an IStatus with a severity of
   * IStatus.ERROR. 
   */
  public static IStatus addFacetsToProject(final IFacetedProject fproject, final Set projectFacetVersions)
  {
    final IStatus[] status = new IStatus[1];
    status[0] = Status.OK_STATUS;
    final Set actions = getInstallActions(projectFacetVersions);
    
    // Create a runnable that applies the install actions to the faceted project
    IRunnableWithProgress runnable = new IRunnableWithProgress()
    {
      public void run(IProgressMonitor shellMonitor) throws InvocationTargetException, InterruptedException
      {
        try
        {
          fproject.modify(actions, shellMonitor);
        } catch (CoreException e)
        {
          status[0] = getErrorStatusForAddingFacets(fproject.getProject().getName(), projectFacetVersions, e);
        }
      }
    };    
        
    // Run the runnable in another thread unless there is no UI thread (Ant scenarios)    
    if (displayPresent())
    {    	
	    try
	    {
	      PlatformUI.getWorkbench().getProgressService().run(true, false, runnable);
	    } catch (InvocationTargetException ite)
	    {
	      status[0] = getErrorStatusForAddingFacets(fproject.getProject().getName(), projectFacetVersions, ite);
	    } catch (InterruptedException ie)
	    {
	      status[0] = getErrorStatusForAddingFacets(fproject.getProject().getName(), projectFacetVersions, ie);
	    }
	}
	else
	{
		try
        {
          fproject.modify(actions, null);
        } catch (CoreException e)
        {
          status[0] = getErrorStatusForAddingFacets(fproject.getProject().getName(), projectFacetVersions, e);
        }
	}
    
    return status[0];
  }
  
  /**
   * Returns an error status indicating that the facet versions could not be
   * added to the faceted project
   * 
   * @param projectName a project name to insert in the error message in the IStatus
   * @param projectFacetVersions a set containing elements of type {@link IProjectFacetVersion}.
   * The facets in this set will be listed in the error message in the IStatus.
   * @param t a Throwable which will be inserted in the IStatus
   * @return an IStatus with severity IStatus.ERROR
   */
  private static IStatus getErrorStatusForAddingFacets(String projectName, Set projectFacetVersions, Throwable t)
  {
    IStatus status = Status.OK_STATUS;
    int size = projectFacetVersions.size();
    if (size > 0)
    {          
      Set facets = new HashSet();
      //Iterate over projectFacetVersions to form a set of IProjectFacets
      Iterator itr = projectFacetVersions.iterator();
      while (itr.hasNext())
      {
        IProjectFacetVersion projectFacet = (IProjectFacetVersion)itr.next();
        IProjectFacet facet = projectFacet.getProjectFacet();
        facets.add(facet);
      }
      String facetList = getFacetListMessageString(facets);
      status = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_ADDING_FACETS_TO_PROJECT, new String[] { projectName, facetList}), t);
    }
    
    return status;
  }
  
  /**
   * Creates a new faceted project with the provided name
   * 
   * @param projectName A String containing the name of the project to be created
   * @return An IStatus with a severity of IStatus.OK if the faceted project
   * was created successfully or if a project of the provided name already
   * exists in the workspace. Otherwise, an IStatus with severity of
   * IStatus.ERROR. 
   */
  public static IStatus createNewFacetedProject(final String projectName)
  {
    final IStatus[] status = new IStatus[1];
    status[0] = Status.OK_STATUS;
    IProject project = ProjectUtilities.getProject(projectName);
    if (!project.exists())
    {
      // Create a runnable that creates a new faceted project.
      IRunnableWithProgress runnable = new IRunnableWithProgress()
      {
        public void run(IProgressMonitor shellMonitor) throws InvocationTargetException, InterruptedException
        {
          try
          {
            IFacetedProject fProject = ProjectFacetsManager.create(projectName, null, shellMonitor);
            if (fProject == null)
            {
              status[0] = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_PROJECT_CREATION, new String[] { projectName }));
            }
          } catch (CoreException e)
          {
            status[0] = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_PROJECT_CREATION, new String[] { projectName }), e);
          }
        }
      };

    // Run the runnable in another thread unless there is no UI thread (Ant scenarios)    	  
      try
      {
    	  if (displayPresent())
    	  {
    		  PlatformUI.getWorkbench().getProgressService().run(true, false, runnable);    		  
    	  }
    	  else
    	  {
    		  try
              {
                IFacetedProject fProject = ProjectFacetsManager.create(projectName, null, null);
                if (fProject == null)
                {
                  status[0] = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_PROJECT_CREATION, new String[] { projectName }));
                }
              } catch (CoreException e)
              {
                status[0] = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_PROJECT_CREATION, new String[] { projectName }), e);
              }  
    	  }        
      } catch (InvocationTargetException ite)
      {
        status[0] = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_PROJECT_CREATION, new String[] { projectName }), ite);
      } catch (InterruptedException ie)
      {
        status[0] = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_PROJECT_CREATION, new String[] { projectName }), ie);
      }
    }

    return status[0];
  }
  
  /**
   * Sets the provided set of facets as fixed on the faceted project
   * 
   * @param fProject A faceted project which exists in the workspace
   * @param fixedFacets A set containing elements of type {@link IProjectFacet}
   * @return An IStatus with a severity of IStatus.OK if the facets 
   * were successfully set as fixed facets on the faceted project. 
   * Otherwise, an IStatus with a severity of IStatus.ERROR.
   * 
   * @see IFacetedProject#setFixedProjectFacets
   */
  public static IStatus setFixedFacetsOnProject(final IFacetedProject fProject, final Set fixedFacets)
  {
    final IStatus[] status = new IStatus[1];
    status[0] = Status.OK_STATUS;

    //Create a runnable that sets the fixed facets on the faceted project
    IRunnableWithProgress runnable = new IRunnableWithProgress()
    {
      public void run(IProgressMonitor shellMonitor) throws InvocationTargetException, InterruptedException
      {
        try
        {
          fProject.setFixedProjectFacets(fixedFacets);
        } catch (CoreException e)
        {
          status[0] = getErrorStatusForSettingFixedFacets(fProject.getProject().getName(), fixedFacets, e);
        }
      }
    };

    // Run the runnable in another thread unless there is no UI thread (Ant scenarios)
    if (displayPresent())
    {
    	try
        {
          PlatformUI.getWorkbench().getProgressService().run(true, false, runnable);
        } catch (InvocationTargetException ite)
        {
          status[0] = getErrorStatusForSettingFixedFacets(fProject.getProject().getName(), fixedFacets, ite);
        } catch (InterruptedException ie)
        {
          status[0] = getErrorStatusForSettingFixedFacets(fProject.getProject().getName(), fixedFacets, ie);
        }	
    }
    else
    {
    	try
        {
          fProject.setFixedProjectFacets(fixedFacets);
        } catch (CoreException e)
        {
          status[0] = getErrorStatusForSettingFixedFacets(fProject.getProject().getName(), fixedFacets, e);
        }
    }       
    
    return status[0];
  }
  
  /**
   * Returns an error status indicating that the facets could not be
   * set as fixed facets on the faceted project
   * 
   * @param projectName a project name to insert in the error message in the IStatus
   * @param facets a set containing elements of type {@link IProjectFacet}.
   * The facets in this set will be listed in the error message in the IStatus.
   * @param t a Throwable which will be inserted in the IStatus
   * @return an IStatus with severity IStatus.ERROR
   */
  private static IStatus getErrorStatusForSettingFixedFacets(String projectName, Set facets, Throwable t)
  {
    IStatus status = Status.OK_STATUS;
    int size = facets.size();
    if (size > 0)
    {          
      String facetList = getFacetListMessageString(facets);      
      status = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_FIXED_FACETS, new String[] { projectName, facetList}), t);
    }
    
    return status;
  }  
  
  
  /**
   * Binds the faceted project to the facet runtime
   * 
   * @param fProject A faceted project which exists in the workspace
   * @param fRuntime A facet runtime
   * @return An IStatus with a severity of IStatus.OK if the faceted project
   * was bound to the facet runtime successfully. Otherwise, an IStatus with severity of
   * IStatus.ERROR. 
   */
  public static IStatus setFacetRuntimeOnProject(final IFacetedProject fProject, final IRuntime fRuntime)
  {
    final IStatus[] status = new IStatus[1];
    status[0] = Status.OK_STATUS;

    //Create a runnable that sets the facet runtime on the faceted project
    IRunnableWithProgress runnable = new IRunnableWithProgress()
    {
      public void run(IProgressMonitor shellMonitor) throws InvocationTargetException, InterruptedException
      {
        try
        {
        	fProject.setTargetedRuntimes(Collections.singleton(fRuntime), shellMonitor);
        } catch (CoreException e)
        {
          status[0] = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_SETTING_RUNTIME, new String[] { fProject.getProject().getName(), fRuntime.getName() }), e);
        }
      }
    };

    // Run the runnable in another thread unless there is no UI thread (Ant scenarios)
    if (displayPresent())
    {
    	try
        {
          PlatformUI.getWorkbench().getProgressService().run(true, false, runnable);
        } catch (InvocationTargetException ite)
        {
          status[0] = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_SETTING_RUNTIME, new String[] { fProject.getProject().getName(), fRuntime.getName() }), ite);
        } catch (InterruptedException ie)
        {
          status[0] = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_SETTING_RUNTIME, new String[] { fProject.getProject().getName(), fRuntime.getName() }), ie);
        }	
    }
    else 
    {
    	try
        {
    		fProject.setTargetedRuntimes(Collections.singleton(fRuntime), null); //jvh - happens here...
        } catch (CoreException e)
        {
          status[0] = StatusUtils.errorStatus(NLS.bind(ConsumptionMessages.MSG_ERROR_SETTING_RUNTIME, new String[] { fProject.getProject().getName(), fRuntime.getName() }), e);
        }
    }
        
    
    return status[0];
  }
  
  /**
   * Returns a translatable delimited list of facet labels derived from the provided
   * set of facets
   * 
   * @param facets a set containing elements of type {@link IProjectFacet}
   * @return String a delimited list of facet labels
   */
  private static String getFacetListMessageString(Set facets)
  {
    String facetListMessage = "";
    int size = facets.size();
    if (size > 0)
    {
      Iterator itr = facets.iterator();
      IProjectFacet firstProjectFacet = (IProjectFacet)itr.next();
      facetListMessage = firstProjectFacet.getLabel();
      
      //Continue appending to facetListMessage until all the facet labels
      //are in the list.
      while (itr.hasNext())
      {
        IProjectFacet projectFacet = (IProjectFacet)itr.next();
        String pfLabel = projectFacet.getLabel();
        facetListMessage = NLS.bind(ConsumptionMessages.MSG_FACETS, new String[] {facetListMessage, pfLabel});
      }            
    }    
    
    return facetListMessage;
  }
  
  
  /**
   * Returns the set of facet versions which can be inferred from the provided Java project
   * 
   * @param javaProject a Java project that exists in the workspace. Must not be null.
   * @return Set containing elements of type {@link IProjectFacetVersion}
   */
  public static Set getFacetsForJavaProject(IJavaProject javaProject)
  {
    Set facets = new HashSet();
    String jdkComplianceLevel = null;
    if (javaProject!=null)
    {
      jdkComplianceLevel = javaProject.getOption("org.eclipse.jdt.core.compiler.compliance", false);
      if (jdkComplianceLevel == null)
      {
        jdkComplianceLevel = JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE);
        if (jdkComplianceLevel == null)
        {
          jdkComplianceLevel = "1.4";
        }
      }
    }
    
    IProjectFacet javaFacet = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_JAVA);
    IProjectFacetVersion javaFacetVersion = null;
    if (jdkComplianceLevel.equals("1.3"))
    {
      javaFacetVersion = javaFacet.getVersion("1.3");
    }
    else if (jdkComplianceLevel.equals("1.4"))
    {
      javaFacetVersion = javaFacet.getVersion("1.4");
    }
    else if (jdkComplianceLevel.equals("1.5"))
    {
      javaFacetVersion = javaFacet.getVersion("5.0");
    }
    else if (jdkComplianceLevel.equals("1.6"))
    {
      javaFacetVersion = javaFacet.getVersion("6.0");
    }
    else
    {
      javaFacetVersion = javaFacet.getVersion("1.4");
    }
 
    facets.add(javaFacetVersion);
    IProjectFacet utilityFacet = ProjectFacetsManager.getProjectFacet(IModuleConstants.JST_UTILITY_MODULE);
    IProjectFacetVersion utilityFacetVersion = null;
    try
    {
      utilityFacetVersion = utilityFacet.getLatestVersion();
    }
    catch (CoreException ce)
    {
      
    }
    if (utilityFacetVersion != null)
    {
      facets.add(utilityFacetVersion);
    }
    return facets;
  }
  
  
  //Methods related to facet runtimes.
  
  /**
   * Returns a set of facet runtimes that support the given
   * required facet versions.
   * @param requiredFacetVersions an array containing elements of type {@link RequiredFacetVersion}
   * @return Set set of facet runtimes that support the given required facet versions.
   * (element type: {@link IRuntime}) 
   */
  public static Set getRuntimes(RequiredFacetVersion[] requiredFacetVersions)
  {
    //Form the sets of IProjectFacetVersions these RequiredFacetVersions represent.
    ArrayList listOfFacetSets = new ArrayList();
    
    HashSet facets = new HashSet();
    int javaFacetIndex = -1;
    for (int i=0; i<requiredFacetVersions.length; i++)
    {
      IProjectFacetVersion pfv = requiredFacetVersions[i].getProjectFacetVersion();
      if (FacetUtils.isJavaFacet(pfv.getProjectFacet()))
      {
        //Remember the index
        javaFacetIndex = i;
      }
      facets.add(requiredFacetVersions[i].getProjectFacetVersion());
    }
    
    listOfFacetSets.add(facets);
    
    //If the java facet was one of the facets in the set, and new versions of java are allowed,
    //create sets that contain the newer permitted versions of the java facets.
    if (javaFacetIndex > -1)
    {
      ArrayList permittedJavaVersions = new ArrayList();
      RequiredFacetVersion rfv = requiredFacetVersions[javaFacetIndex];
      if (rfv.getAllowNewer())
      {
        String version = rfv.getProjectFacetVersion().getVersionString();      
        Set allVersions = rfv.getProjectFacetVersion().getProjectFacet().getVersions();
        Iterator itr = allVersions.iterator();
        while (itr.hasNext())
        {
          IProjectFacetVersion thisPfv = (IProjectFacetVersion)itr.next();
          String thisVersion = thisPfv.getVersionString();
          if (greaterThan(thisVersion, version))
          {
            permittedJavaVersions.add(thisVersion);
          }          
        }
        
        String[] javaVersions = (String[])permittedJavaVersions.toArray(new String[0]);
        
        for (int j=0; j<javaVersions.length; j++)
        {
          HashSet thisFacetSet = new HashSet();
          
          for (int k=0; k<requiredFacetVersions.length; k++)
          {
             if (k==javaFacetIndex)
             {
               IProjectFacetVersion pfv = requiredFacetVersions[k].getProjectFacetVersion().getProjectFacet().getVersion(javaVersions[j]);
               thisFacetSet.add(pfv);
             }
             else
             {
               IProjectFacetVersion pfv = requiredFacetVersions[k].getProjectFacetVersion();
               thisFacetSet.add(pfv);
             }
          }
          
          listOfFacetSets.add(thisFacetSet);          
        }
      }
    }
    
    //Return the union of runtimes for all the facetSets.
    return getRuntimes((Set[])listOfFacetSets.toArray(new Set[0]));
    
  }  
  
  /**
   * Returns whether or not the provided facet runtime supports the provided
   * required facet versions.
   * 
   * @param requiredFacetVersions an array containing elements of type {@link RequiredFacetVersion}
   * @param fRuntimeName name of a {@link IRuntime}
   * @return boolean <code>true</code> if the facet runtime supports the required facet versions.
   * Returns <code>false</code> otherwise.
   */
  public static boolean isFacetRuntimeSupported(RequiredFacetVersion[] requiredFacetVersions, String fRuntimeName)
  {
    Set fRuntimes = getRuntimes(requiredFacetVersions);
    Iterator itr = fRuntimes.iterator();
    while (itr.hasNext())
    {
      IRuntime runtime = (IRuntime)itr.next();
      if (runtime.getName().equals(fRuntimeName))
      {
        return true;
      }      
    }
    
    return false;
  }
    
  /**
   * Returns the union of facet runtimes that support the provided sets of facet versions.
   * 
   * @param facetSets array of Sets, where each Set contains elements of type {@link IProjectFacetVersion}.
   * @return Set containing elements of type {@link IRuntime}
   */
  public static Set getRuntimes(Set[] facetSets)  
  {
    HashSet unionSet = new HashSet();
    for (int i=0; i<facetSets.length; i++)
    {
      Set facets = facetSets[i];
      Set runtimes = RuntimeManager.getRuntimes(facets);
      Iterator itr = runtimes.iterator();
      while (itr.hasNext())
      {
        IRuntime runtime = (IRuntime)itr.next();
        if (!unionSet.contains(runtime))
        {
          unionSet.add(runtime);
        }
      }
    }
    return unionSet;
  }
  
  /**
   * Returns whether or not the provided facet runtime supports the provided set of facet versions.
   * 
   * @param facetRuntime a facet runtime
   * @param projectFacetVersions set containing elements of type {@link IProjectFacetVersion}
   * @return boolean <code>true</code> if the facet runtime supports the provided set of facet versions.
   * Returns <code>false</code> otherwise.
   */
  public static boolean doesRuntimeSupportFacets(IRuntime facetRuntime, Set projectFacetVersions)
  {
  	if ( facetRuntime == null || projectFacetVersions == null)
  		return false;
  	
    Set runtimes = RuntimeManager.getRuntimes(projectFacetVersions);
    Iterator itr = runtimes.iterator();
    while (itr.hasNext())
    {
      IRuntime runtime = (IRuntime)itr.next();
      if (runtime.getName().equals(facetRuntime.getName()))
      {
        return true;
      }
    }
    
    return false;
  }
  
  /**
   * Returns whether versionA is greater than versionB
   * 
   * @param versionA version number of the form 1.2.3
   * @param versionA version number of the form 1.2.3
   * @return boolean <code>true</code> if versionA is greater than versionB, <code>false</code> otherwise.
   */
  public static boolean greaterThan(String versionA, String versionB)
  {
  	if (versionA == null || versionB == null)
  		return false;
  	
    StringTokenizer stA = new StringTokenizer(versionA, ".");
    StringTokenizer stB = new StringTokenizer(versionB, ".");
    
    int sizeA = stA.countTokens();
    int sizeB = stB.countTokens();
    
    int size;
    if (sizeA < sizeB)
    {
      size = sizeA;
    }
    else
      size = sizeB;
    
    for (int i=0; i<size; i++)
    {
      int a = Integer.parseInt(stA.nextToken());
      int b = Integer.parseInt(stB.nextToken());
      if (a!=b)
      {
        return a > b;
      }      
    }
    
    return sizeA > sizeB;
  }
  
  /**
   * Returns whether the provided facet has an id of "jst.java"
   * @param pf facet
   * @return <code>true</code> if facet has an id of "jst.java", <code>false</code> otherwise.
   */
  public static boolean isJavaFacet(IProjectFacet pf)
  {
    if (pf != null && pf.getId().equals("jst.java"))
      return true;
    else
      return false;
  }
  
  /**
   * Returns whether or not the provided project is a faceted Java utility project or a non-faceted Java project.
   * 
   * @param project an IProject
   * @return boolean <code>true</code> if the provided project is a faceted Java utility project 
   * or a non-faceted Java project, <code>false</code> otherwise.
   */
  public static boolean isJavaProject(IProject project)
  {
	  if (project == null)
	    return false;
	  
    //Check if it's a faceted project
    try
    {
      IFacetedProject fProject = ProjectFacetsManager.create(project);
      if (fProject != null)
      {
        //Return true if it's a utility project
        if (J2EEUtils.isJavaComponent(project))
        {
          return true;
        }
        else
        {
          //See if the java facet is the only one it has.
          Set facets = fProject.getProjectFacets();
          if (facets.size()==1)
          {
            IProjectFacetVersion pfv = (IProjectFacetVersion)facets.iterator().next();
            if (isJavaFacet(pfv.getProjectFacet()))
            {
              return true;
            }
          }
        }
      }
      else
      {
        if (ResourceUtils.isJavaProject(project))
        {
          return true;
        }        
      }
    } catch (CoreException ce)
    {
      
    }

    return false;
  }
  
  /**
   * Returns whether or not the provided template id is equal to "template.jst.utility"
   * 
   * @param templateId template id
   * @return boolean <code>true</code> if the provided template id is equal to "template.jst.utility", 
   * <code>false</code> otherwise.
   */
  public static boolean isUtilityTemplate(String templateId)
  {
    if (templateId != null && ProjectFacetsManager.isTemplateDefined(templateId))
    {
      if (templateId.equals("template.jst.utility"))
      {
        return true;
      }
    }
    
    return false;
  }
      
  	/**
  	 * Returns the required facet version of a EAR that should contain the given project. 
  	 * 
  	 * @param project The project
  	 * @return An array of required facet versions.  If no constraints can be inferred from the
  	 * project, an empty array is returned.
  	 */
	public static RequiredFacetVersion[] getRequiredEARFacetVersions(IProject project) {
  		
		int version = 0;
  		
  		if (JavaEEProjectUtilities.isDynamicWebProject(project)) {
  			
  			version = J2EEVersionUtil.convertWebVersionStringToJ2EEVersionID(
  					J2EEProjectUtilities.getJ2EEProjectVersion(project));
  		}
  		else if (JavaEEProjectUtilities.isEJBProject(project)) {
  			
  			version = J2EEVersionUtil.convertEJBVersionStringToJ2EEVersionID(
  					J2EEProjectUtilities.getJ2EEProjectVersion(project));
  		}
  		else if (JavaEEProjectUtilities.isApplicationClientProject(project)) {
  			
  			version = J2EEVersionUtil.convertAppClientVersionStringToJ2EEVersionID(
  					J2EEProjectUtilities.getJ2EEProjectVersion(project));
  		}
  		else
  			// return empty array, no constraints
  			return new RequiredFacetVersion[0];
	  
  		IProjectFacet projectFacet = ProjectFacetsManager.getProjectFacet(IJ2EEModuleConstants.JST_EAR_MODULE);
  		IProjectFacetVersion projectFacetVersion = projectFacet.getVersion(J2EEVersionUtil.convertVersionIntToString(version));

  		RequiredFacetVersion[] rfv = new RequiredFacetVersion[1];
  		rfv[0] = new RequiredFacetVersion();
  		rfv[0].setAllowNewer(false);	  
  		rfv[0].setProjectFacetVersion(projectFacetVersion);
  		
  		return rfv;
  	}
	
	// Check to see if SWT is active and the Display is present or not
	private static boolean displayPresent() {
		Bundle b = Platform.getBundle("org.eclipse.swt");
	    if (b==null) {
	    	return false;
	    }
	    if ((b.getState() != Bundle.RESOLVED && b.getState() != Bundle.ACTIVE) ) {
	    	return false;
	    }
	    try {
	    	if (Display.getCurrent() == null) {
	    		return false;
	    	} else {
	    		return true;
	    	}
	    } catch (NoClassDefFoundError e1) {
	    	return false;
	    } catch (Exception e) {  // if the Display class cannot be loaded for whatever reason
	    	return false;
	    
	    } 
	}
}
