/*******************************************************************************
 * 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
 * 20080326   171705 trungha@ca.ibm.com - Trung, improve AntTask errors report
 * 20080326   221364 kathy@ca.ibm.com - Kathy Chan
 * 20080402   225032 makandre@ca.ibm.com - Andrew Mak
 * 20080415   227152 makandre@ca.ibm.com - Andrew Mak, Need a way to specify a backup Web service runtime
 * 20080421   228054 makandre@ca.ibm.com - Andrew Mak, NPE in ClientRuntimeSelectionWidgetDefaultingCommand
 * 20080527   234226 kathy@ca.ibm.com - Kathy Chan
 *******************************************************************************/
package org.eclipse.jst.ws.internal.consumption.ui.widgets.runtime;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jst.server.core.FacetUtil;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.common.ServerUtils;
import org.eclipse.jst.ws.internal.consumption.common.FacetMatcher;
import org.eclipse.jst.ws.internal.consumption.common.FacetUtils;
import org.eclipse.jst.ws.internal.consumption.common.RequiredFacetVersion;
import org.eclipse.jst.ws.internal.consumption.ui.ConsumptionUIMessages;
import org.eclipse.jst.ws.internal.consumption.ui.common.DefaultingUtils;
import org.eclipse.jst.ws.internal.consumption.ui.common.ValidationUtils;
import org.eclipse.jst.ws.internal.consumption.ui.plugin.WebServiceConsumptionUIPlugin;
import org.eclipse.jst.ws.internal.consumption.ui.preferences.PersistentServerRuntimeContext;
import org.eclipse.jst.ws.internal.consumption.ui.preferences.ProjectTopologyContext;
import org.eclipse.jst.ws.internal.consumption.ui.wsrt.ClientRuntimeDescriptor;
import org.eclipse.jst.ws.internal.consumption.ui.wsrt.FacetMatchCache;
import org.eclipse.jst.ws.internal.consumption.ui.wsrt.RuntimeDescriptor;
import org.eclipse.jst.ws.internal.consumption.ui.wsrt.ServiceRuntimeDescriptor;
import org.eclipse.jst.ws.internal.consumption.ui.wsrt.WebServiceRuntimeExtensionUtils2;
import org.eclipse.jst.ws.internal.data.TypeRuntimeServer;
import org.eclipse.jst.ws.internal.ui.WSUIPluginMessages;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.command.internal.env.core.context.ResourceContext;
import org.eclipse.wst.command.internal.env.core.selection.SelectionList;
import org.eclipse.wst.command.internal.env.core.selection.SelectionListChoices;
import org.eclipse.wst.common.environment.IEnvironment;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.server.core.IRuntime;
import org.eclipse.wst.server.core.IRuntimeType;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.IServerType;
import org.eclipse.wst.server.core.ServerCore;
import org.eclipse.wst.server.core.ServerUtil;
import org.eclipse.wst.ws.internal.parser.wsil.WebServicesParser;
import org.eclipse.wst.ws.internal.wsrt.IContext;
import org.eclipse.wst.ws.internal.wsrt.ISelection;
import org.eclipse.wst.ws.internal.wsrt.IWebServiceClient;
import org.eclipse.wst.ws.internal.wsrt.IWebServiceRuntime;
import org.eclipse.wst.ws.internal.wsrt.SimpleContext;
import org.eclipse.wst.ws.internal.wsrt.WebServiceClientInfo;
import org.eclipse.wst.ws.internal.wsrt.WebServiceScenario;
import org.eclipse.wst.ws.internal.wsrt.WebServiceState;

public class ClientRuntimeSelectionWidgetDefaultingCommand extends AbstractDataModelOperation
{   
  private String DEFAULT_CLIENT_EAR_PROJECT_EXT = "EAR";
  private TypeRuntimeServer    clientIds_;
  private boolean clientIdsFixed_ = false;
  private String clientRuntimeId_;
  private String clientProjectName_;
  private String clientEarProjectName_;
  protected boolean clientNeedEAR_ = true;
  private String clientComponentType_;
  private FacetMatcher clientFacetMatcher_;
  
  private IContext          context_;
  private ISelection        selection_;
  private IWebServiceClient webServiceClient_;
  private ResourceContext   resourceContext_;
  private boolean           test_;
  
  //A note on initial projects ...
  //The difference between clientInitialProject_ and initialProject_ is that
  //clientInitialProject_ comes from the ObjectSelectionOutputCommand while initialProject_
  //comes from SelectionCommand (i.e. it is the project containing the thing that was selected before 
  //the wizard was launched). In the defaulting algorithm, clientInitialProject_ will 
  //be given first priority. If, however, it is deemed that clientInitialProject_ is not a valid project 
  //because it contains the J2EE Web service for which we are trying to create a client, initialProject_
  //will be given second priority.
  private IProject initialProject_; //This is the project containing the selection prior to the wizard being launched.
  private IProject clientInitialProject_; //This is the project containing the object selection from page 2.
  private String wsdlURI_;
  private WebServicesParser parser_;  

  public ClientRuntimeSelectionWidgetDefaultingCommand()
  {
    super();
  }
  
  public void setClientTypeRuntimeServer( TypeRuntimeServer ids )
  {
    clientIds_ = ids;
  }
  
  public TypeRuntimeServer getClientTypeRuntimeServer()
  {
    return clientIds_; 
  }
  
  public void setClientIdsFixed(boolean b)
  {
    clientIdsFixed_ = b;  
  }
  
  public String getClientRuntimeId()
  {
    return clientRuntimeId_;
  }
  
  public String getClientProjectName()
  {
    return clientProjectName_;
  }
  
  public String getClientEarProjectName()
  {
    return clientEarProjectName_;
  }
  
  public void setClientEarProjectName(String name)
  {
    clientEarProjectName_ = name;
  }
  
  public String getClientComponentType()
  {
    return  clientComponentType_;
  }
  
  public IWebServiceClient getWebService()
  {
    return webServiceClient_;  
  }
    
  public IContext getContext()
  {
    return context_;
  }  
  
  public ISelection getSelection()
  {
    return selection_;    
  }
  
  /**
   * Defaults the following bits of information in the following order:
   * clientRuntimeId_ : the clientRuntimeId. Must be defaulted to non-empty String.
   * clientIds_.runtimeId_: the Web service runtime id. Must be defaulted to non-empty String.
   * clientProjectName_ : the name of the client project. Must be non-empty. May or may not exist.
   * clientComponentType_: the id of the client project template. Must be empty if the client
   *                        project exists. Must be non-empty of the client project does not exist.
   * clientIds_.serverId_: the server type id. May be an empty String if the defaulted Web service runtime
   *                        does not require a server.
   * clientIds_.serverInstanceId_: the server id. May be null or an empty String.
   * clientNeedEAR_: true if an EAR is needed. False otherwise.
   * clientEarProjectName_: the client EAR project. Must be empty if the clientNeedEAR_ is false.
   *                         Must be non-empty if the clientNeedEAR_ is true.
   * webServiceClient_ : the IWebServiceClient based on the calculated defaults. Must be non-null for "Next"
   *                     button to be enabled on the page following this command.
   * context_ : an IContext. Must be non-null for "Next" button to be enabled on the page following this command.                         
   */  
  public IStatus execute(IProgressMonitor monitor, IAdaptable adaptable)
  {

    IEnvironment env = getEnvironment();

    try
    {
      
      //**Step 1** Default the Web service runtime.
    	
      //clientIdsFixed_ is set to true for the Ant scenario. It's always false for the wizard
      //scenarios.
      if (clientIdsFixed_ && (clientProjectName_ == null))
      {
        // Set the clientRuntime based on the runtime, server, and initial
        // selection.
        DefaultRuntimeTriplet drt = getDefaultClientRuntimeForFixedRuntimeAndServer(clientInitialProject_, clientIds_.getServerId());
        clientFacetMatcher_ = drt.getFacetMatcher();
        clientProjectName_ = drt.getProjectName();
        clientRuntimeId_ = drt.getRuntimeId();        
      } 
      else      
      {	
        ValidationUtils vu = new ValidationUtils();
        
        // Set the runtime based on the project containing the object selection/initial selection.
        DefaultRuntimeTriplet drt = null;
        
        if (!vu.isProjectServiceProject(clientInitialProject_, wsdlURI_, parser_) && !clientIdsFixed_)
        {
          //If clientIntialProject_ does not contain the J2EE Web service, choose a clientRuntime based on it.
          drt = getDefaultRuntime(clientInitialProject_, clientIds_.getTypeId(), true, clientIds_.getServerId());
          clientFacetMatcher_ = drt.getFacetMatcher();
          clientProjectName_ = drt.getProjectName(); 
          clientRuntimeId_ = drt.getRuntimeId();          
        }
        else
        {
          //clientInitialProject_ contains the J2EE Web service so don't use it.
          //Try using the initalProject_ instead.
          if (!vu.isProjectServiceProject(initialProject_, wsdlURI_, parser_) && !clientIdsFixed_)
          {
            //If intialProject_ does not contain the J2EE Web service, choose a clientRuntime based on it.
            drt = getDefaultRuntime(initialProject_, clientIds_.getTypeId(), true, clientIds_.getServerId());
            clientFacetMatcher_ = drt.getFacetMatcher();
            clientProjectName_ = drt.getProjectName();
            clientRuntimeId_ = drt.getRuntimeId();            
          }
          else
          {
            //Both clientIntialProject_ and initialProject_ contain the J2EE Web service
            //and cannot be used to influence clientRuntime defaulting.
            //Choose a clientRuntime but don't choose clientInitialProject_
            //as the clientProject.
            drt = getDefaultRuntime(null, clientIds_.getTypeId(), true, clientIds_.getServerId());
            clientRuntimeId_ = drt.getRuntimeId();                      
          }
        }

        //Set the Web service runtime id from the clientRuntime
        clientIds_.setRuntimeId(WebServiceRuntimeExtensionUtils2.getClientRuntimeDescriptorById(clientRuntimeId_).getRuntime()
            .getId());
      }
      
      //**Step 2** Default the client project if it was not already defaulted 
      //as part of defaulting the Web service runtime.
      if (clientProjectName_ == null)
      {
        // Project name did not get set when the runtime was set, so set it now
        clientProjectName_ = getDefaultClientProjectName();
      }

      //**Step 3** Default the client project type.      
      IProject clientProject = ProjectUtilities.getProject(clientProjectName_);
      if (!clientProject.exists())
      {
        // Set the project template
        clientComponentType_ = getDefaultClientProjectTemplate();
      }
      else
      {
        //Set it to an empty String
        clientComponentType_ = "";
      }


      //**Step 4** Default the client server if this is not an Ant scenario.
      if (!clientIdsFixed_)
      {
        IStatus serverStatus = setClientDefaultServer();
        if (serverStatus.getSeverity() == Status.ERROR)
        {
          env.getStatusHandler().reportError(serverStatus);
          return serverStatus;
        }
      }
      
      //**Step 5** Default clientNeedEAR and client EAR if an EAR is needed
      setDefaultClientEarProject();      
      
      
      //**Step 6** Calculate default IWebServiceClient. This is need to make sure that
      // Next is enabled on the page following this command.
      setDefaultsForExtension(env);

      return Status.OK_STATUS;
      
    } catch (Exception e)
    {
      // Catch all Exceptions in order to give some feedback to the user
      IStatus errorStatus = StatusUtils.errorStatus(NLS.bind(ConsumptionUIMessages.MSG_ERROR_TASK_EXCEPTED,
          new String[] { e.getMessage() }), e);
        
      // If the exception has no error msg, it's kind of useless to the user so let's log it
      if ( e.getMessage() == null){
        ILog pluginlog = WebServiceConsumptionUIPlugin.getInstance().getLog();
        pluginlog.log(errorStatus);
        	  
        // create a new IStatus which has a non-null msg, this is to be thrown to the user.
        errorStatus = StatusUtils.errorStatus(NLS.bind(ConsumptionUIMessages.MSG_ERROR_TASK_EXCEPTED,
      	       new String[] { WSUIPluginMessages.MSG_SEE_ERROR_LOG }), e);  
      }
          
      env.getStatusHandler().reportError(errorStatus);
      return errorStatus;
    }
  }
  
  private void setDefaultClientEarProject()
  {    
    //Don't need an ear if this is a Java project, or if the selected template is jst.utility
    IProject clientProject = ProjectUtilities.getProject(clientProjectName_);
    if (clientProject.exists())
    {
      clientNeedEAR_ = !(FacetUtils.isJavaProject(clientProject));
    }
    else
    {
      clientNeedEAR_ = !(FacetUtils.isUtilityTemplate(clientComponentType_));  
    }
    
    //If clientNeedEAR_ is still true, it means that we're not dealing with a Java project
    //or Java project type. Check the server.
    if (clientNeedEAR_)
    {
      // Determine if an ear selection is needed based on the server type.

      String serverId = clientIds_.getServerId();
      if (serverId != null)
      {
        // Use the server type
        String serverTargetId = ServerUtils.getRuntimeTargetIdFromFactoryId(serverId);
        if (serverTargetId != null && serverTargetId.length() > 0)
        {
          if (!ServerUtils.isTargetValidForEAR(serverTargetId, "13"))
          {
            // Default the EAR selection to be empty
            clientNeedEAR_ = false;
          }
        }
      } else {  // serverId == null, assume that it does not need EAR
    	  clientNeedEAR_ = false;
    	  
      }
    }
    
    if (clientNeedEAR_)
    {
    	clientEarProjectName_ = DefaultingUtils.getDefaultEARProjectName(clientProjectName_);
    }
    else
    {
      clientEarProjectName_ = "";
    }   
  }
  
  private IStatus setClientDefaultServer()
  {
    //Choose an existing server the module is already associated with if possible
    IProject clientProject = ProjectUtilities.getProject(clientProjectName_);
    IServer[] configuredServers = ServerUtil.getServersByModule(ServerUtils.getModule(clientProject), null);
    
    if (configuredServers!=null && configuredServers.length>0 && configuredServers[0].getServerType() != null)
    {
      clientIds_.setServerId(configuredServers[0].getServerType().getId());
      clientIds_.setServerInstanceId(configuredServers[0].getId());
      return Status.OK_STATUS;            	
    }
    
    //If the project exists, choose a suitable server or server type based on the existing project's runtime or facets
    if (clientProject.exists())
    {
      IServer server = getServerFromProject(clientProjectName_, clientFacetMatcher_);
      if (server != null && server.getServerType() != null)
      {
        clientIds_.setServerId(server.getServerType().getId());
        clientIds_.setServerInstanceId(server.getId());
        return Status.OK_STATUS;
      }
      else
      {
        IServerType serverType = getServerTypeFromProject(clientProjectName_, clientFacetMatcher_);
        if (serverType != null)
        {
          clientIds_.setServerId(serverType.getId());
          return Status.OK_STATUS;
        }
      }
    }

    //Haven't picked a server/server type on the basis of the project. Pick a server/server type
    //that is compatible with the clientRuntimeId.
    IServer server = getServerFromClientRuntimeId();
    if (server!=null && server.getServerType() != null)
    {
      clientIds_.setServerId(server.getServerType().getId());
      clientIds_.setServerInstanceId(server.getId());
      return Status.OK_STATUS;
    }
    
    IServerType serverType = getServerTypeFromClientRuntimeId();
    if (serverType != null)
    {
      clientIds_.setServerId(serverType.getId());
      return Status.OK_STATUS;
    }    
    
    // No suitable server was found. Popup an error if the default Web service
    // runtime requires a server.
    RuntimeDescriptor runtimeDescriptor = WebServiceRuntimeExtensionUtils2.getRuntimeById(clientIds_.getRuntimeId());
    if (runtimeDescriptor.getServerRequired())
    {
      String runtimeLabel = WebServiceRuntimeExtensionUtils2.getRuntimeLabelById(clientIds_.getRuntimeId());
      IStatus status = StatusUtils.errorStatus(NLS.bind(ConsumptionUIMessages.MSG_ERROR_NO_SERVER_RUNTIME, new String[] {
          runtimeLabel}));
      return status;
    }
    
    return Status.OK_STATUS;
  }
  
  private IServer getServerFromClientRuntimeId()
  {
    IServer[] servers = ServerCore.getServers();
    if (servers != null && servers.length > 0) {
    	
        PersistentServerRuntimeContext context = WebServiceConsumptionUIPlugin.getInstance().getServerRuntimeContext();
        String preferredServerFactoryId = context.getServerFactoryId();
        
        //If a server of the preferred server type is present, check that one first
        for (int j = 0; j < servers.length; j++)
        {
          if (servers[j] != null && servers[j].getServerType() != null)
          {
	          String serverFactoryId = servers[j].getServerType().getId();
	          if (serverFactoryId.equals(preferredServerFactoryId))
	          {
	            if (WebServiceRuntimeExtensionUtils2.doesClientRuntimeSupportServer(clientRuntimeId_, serverFactoryId))
	            {
	              return servers[j];
	            }
	          }
          }
        }
        
        //A server of the preferred server type could not be found or did not match. Check all the existing servers.    
    	
      for (int i = 0; i < servers.length; i++)
      {
    	if (servers[i] != null && servers[i].getServerType() != null)
    	{
	        String serverFactoryId = servers[i].getServerType().getId();
	        if (WebServiceRuntimeExtensionUtils2.doesClientRuntimeSupportServer(clientRuntimeId_, serverFactoryId))
	        {
	          return servers[i];
	        }
	      }
      }
    }
    return null;    
  }
  
  private IServerType getServerTypeFromClientRuntimeId()
  {
    String[] serverTypes = WebServiceRuntimeExtensionUtils2.getServerFactoryIdsByClientRuntime(clientRuntimeId_);
    if (serverTypes!=null && serverTypes.length>0)
    {
      //Return the preferred one if it is in the list
      PersistentServerRuntimeContext context = WebServiceConsumptionUIPlugin.getInstance().getServerRuntimeContext();
      String preferredServerFactoryId = context.getServerFactoryId();
      for (int i=0; i<serverTypes.length; i++)
      {
        if (serverTypes[i].equals(preferredServerFactoryId))
        {
          return ServerCore.findServerType(serverTypes[i]);
        }
      }
      
      return ServerCore.findServerType(serverTypes[0]);
    }    
    
    return null;
  }
  
  protected IServer getServerFromProject(String projectName, FacetMatcher facetMatcher)
  {
    IServer server = null;
    
    IProject project = ProjectUtilities.getProject(projectName);
    IServer[] servers = ServerCore.getServers();
    
    if (servers.length > 0)
    {
      PersistentServerRuntimeContext context = WebServiceConsumptionUIPlugin.getInstance().getServerRuntimeContext();
      String preferredServerFactoryId = context.getServerFactoryId();
        
      // Get the runtime.
      org.eclipse.wst.common.project.facet.core.runtime.IRuntime fRuntime = null;
      IFacetedProject fProject = null;

      if (project != null && project.exists())
      {
        try
        {
          fProject = ProjectFacetsManager.create(project);
          if (fProject != null)
          {
        	  fRuntime = fProject.getPrimaryRuntime();
          }
        } catch (CoreException ce)
        {

        }
      }

      if (fRuntime != null)
      {
        // Get an existing server that has the same runtime.
        IServer firstMatchingServer = null;    	  
        IRuntime sRuntime = FacetUtil.getRuntime(fRuntime);
        for (int i = 0; i < servers.length; i++)
        {
          IServer thisServer = servers[i];
          IRuntime thisServerRuntime = thisServer.getRuntime();
          if ( thisServerRuntime != null && sRuntime != null && thisServerRuntime.getId().equals(sRuntime.getId()))
          {
            if (firstMatchingServer==null)
            {
              firstMatchingServer = thisServer;
            }
              
            if (thisServer != null && thisServer.getServerType() != null && thisServer.getServerType().getId().equals(preferredServerFactoryId))
            {
        	  
              server = thisServer;
              break;
            }
          }
        }
                
        //If a server of the preferred server type was not found but
        //there was a server that matched, return that one.
        if (server == null && firstMatchingServer != null)
        {
          server = firstMatchingServer;
        }        
      }

      // If an existing server could not be chosen on the basis of the project's
      // runtime,
      // try to find an existing server using the project's facets and the
      // facetsToAdd.
      if (server == null)
      {
        if (project!=null && project.exists())
        {
          Set facets = FacetUtils.getFacetsForProject(project.getName());
          if (facets != null)
          {
            Set facetsClone = new HashSet();
            facetsClone.addAll(facets);            
            if (facetMatcher != null && facetMatcher.getFacetsToAdd() != null)
            {
              Iterator itr = facetMatcher.getFacetsToAdd().iterator();
              while (itr.hasNext())
              {
                facetsClone.add(itr.next());  
              }            
            }
            server = getServerFromFacets(facetsClone);            
          }
        }
      }
    }
    return server;
  }
  
  protected IServer getServerFromFacets(Set facets)
  {
	    IServer server = null;
	    Set runtimes = FacetUtils.getRuntimes(new Set[]{facets});
	    Iterator itr = runtimes.iterator();
	    IServer[] servers = ServerCore.getServers();
	    PersistentServerRuntimeContext context = WebServiceConsumptionUIPlugin.getInstance().getServerRuntimeContext();
	    String preferredServerFactoryId = context.getServerFactoryId();
	    
	    //If one of the servers is of the preferred type, and its runtime
	    //is in the set of matching runtimes, return that server.
	    for (int j=0; j<servers.length; j++)      
	    {
	      IServer thisServer = servers[j];
	      if (thisServer != null && thisServer.getServerType() != null && thisServer.getRuntime() != null && thisServer.getServerType().getId().equals(preferredServerFactoryId))
	      {
	    	IRuntime thisServerRuntime = thisServer.getRuntime();
	        //Check to see if it matches any of the runtimes.
	        Iterator runtimesItr = runtimes.iterator();
	        while(runtimesItr.hasNext())
	        {
	          org.eclipse.wst.common.project.facet.core.runtime.IRuntime fRuntime = (org.eclipse.wst.common.project.facet.core.runtime.IRuntime)runtimesItr.next();
	          IRuntime sRuntime = FacetUtil.getRuntime(fRuntime);
	          if (sRuntime != null && thisServerRuntime.getId().equals(sRuntime.getId()))
	          {
	            server = thisServer;
	          }          
	        }
	      }            
	    }
	    
	    if (server == null)
	    {
	      outer: while (itr.hasNext())
	      {
	        org.eclipse.wst.common.project.facet.core.runtime.IRuntime fRuntime = (org.eclipse.wst.common.project.facet.core.runtime.IRuntime) itr
	            .next();
	        IRuntime sRuntime = FacetUtil.getRuntime(fRuntime);
	        for (int i = 0; i < servers.length; i++)
	        {
	          IServer thisServer = servers[i];
	          IRuntime thisServerRuntime = thisServer.getRuntime();
	          if (thisServerRuntime != null && sRuntime != null && thisServerRuntime.getId().equals(sRuntime.getId()))
	          {
	            server = thisServer;
	            break outer;
	          }
	        }
	      }
	    }

	    return server;

  }
  
  protected IServerType getServerTypeFromProject(String projectName, FacetMatcher facetMatcher)
  {
	    IServerType serverType = null;
	    PersistentServerRuntimeContext context = WebServiceConsumptionUIPlugin.getInstance().getServerRuntimeContext();
	    String preferredServerFactoryId = context.getServerFactoryId();
	    
	    IProject project = ProjectUtilities.getProject(projectName);
	    IServerType[] serverTypes = ServerCore.getServerTypes();
	    
	    //Get the runtime.
	    org.eclipse.wst.common.project.facet.core.runtime.IRuntime fRuntime = null;
	    IFacetedProject fProject = null;
	    
	    if (project != null && project.exists())
	    {
	      try
	      {
	        fProject = ProjectFacetsManager.create(project);
	        if (fProject != null)
	        {
	        	fRuntime = fProject.getPrimaryRuntime();
	        }
	      } catch (CoreException ce)
	      {
	        
	      }
	    }
	    
	    if (fRuntime != null)
	    {
	      //Get a server type that has the same runtime type.
	      IRuntime sRuntime = FacetUtil.getRuntime(fRuntime); 
	      if (sRuntime != null)
	      {
		      IRuntimeType sRuntimeType = sRuntime.getRuntimeType();
		      IServerType firstMatchingServerType = null;
		      for (int i=0; i<serverTypes.length; i++)
		      {
		        IServerType thisServerType = serverTypes[i];
		        IRuntimeType thisServerRuntimeType = thisServerType.getRuntimeType();
		        if (sRuntimeType != null && thisServerRuntimeType != null && thisServerRuntimeType.getId().equals(sRuntimeType.getId()))
		        {
		          if (firstMatchingServerType == null)
		          {
		            firstMatchingServerType = thisServerType;
		          }
		          if (thisServerType.getId().equals(preferredServerFactoryId))
		          {
		            serverType = thisServerType;
		            break;
		          }
		        }     
		      }
		      
		      //If the preferred server type was not found but
		      //there was a server type that matched, return that one.        
		      if (serverType == null && firstMatchingServerType != null)
		      {        
		        serverType = firstMatchingServerType;
		      }
	      }
	    }

	    //If a server type could not be chosen on the basis of the project's runtime,
	    //try to find a server type using the project's facets and the facetsToAdd.
	    if (serverType == null)
	    {
	      if (project != null && project.exists())
	      {
	        Set facets = FacetUtils.getFacetsForProject(project.getName());
	        if (facets != null)
	        {
	          Set facetsClone = new HashSet();
	          facetsClone.addAll(facets);          
	          if (facetMatcher != null && facetMatcher.getFacetsToAdd() != null)
	          {
	            Iterator itr = facetMatcher.getFacetsToAdd().iterator();
	            while (itr.hasNext())
	            {
	              facetsClone.add(itr.next());  
	            }            
	          }
	          serverType = getServerTypeFromFacets(facetsClone);          
	        }
	      }
	    }
	    
	    return serverType;

  }
  
  protected IServerType getServerTypeFromFacets(Set facets)
  {
	    IServerType serverType = null;
	    Set runtimes = FacetUtils.getRuntimes(new Set[]{facets});
	    Iterator itr = runtimes.iterator();
	    IServerType[] serverTypes = ServerCore.getServerTypes();
	    PersistentServerRuntimeContext context = WebServiceConsumptionUIPlugin.getInstance().getServerRuntimeContext();
	    String preferredServerFactoryId = context.getServerFactoryId();    

	    //If one of the server types is of the preferred type, and its runtime
	    //is in the set of matching runtimes, return that server type.
	    for (int j=0; j<serverTypes.length; j++)      
	    {
	      IServerType thisServerType = serverTypes[j];
	      IRuntimeType thisServerTypeRuntimeType = thisServerType.getRuntimeType();
	      if (thisServerTypeRuntimeType != null && thisServerType.getId().equals(preferredServerFactoryId))
	      {
	        //Check to see if it matches any of the runtimes.
	        Iterator runtimesItr = runtimes.iterator();
	        while(runtimesItr.hasNext())
	        {
	          org.eclipse.wst.common.project.facet.core.runtime.IRuntime fRuntime = (org.eclipse.wst.common.project.facet.core.runtime.IRuntime)runtimesItr.next();
	          IRuntime sRuntime = FacetUtil.getRuntime(fRuntime);
	          if (sRuntime != null)
	          {
	        	  IRuntimeType sRuntimeType = sRuntime.getRuntimeType();
		          if (sRuntimeType != null && thisServerTypeRuntimeType.getId().equals(sRuntimeType.getId()))
		          {
		            serverType = thisServerType;
		          }          
	          }
	        }
	      }            
	    }
	    
	    
	    if (serverType == null)
	    {
	      outer: while (itr.hasNext())
	      {
	        org.eclipse.wst.common.project.facet.core.runtime.IRuntime fRuntime = (org.eclipse.wst.common.project.facet.core.runtime.IRuntime) itr
	            .next();
	        IRuntime sRuntime = FacetUtil.getRuntime(fRuntime);
	        if (sRuntime != null)
	        {
		        IRuntimeType sRuntimeType = sRuntime.getRuntimeType();
		        for (int i = 0; i < serverTypes.length; i++)
		        {
		          IServerType thisServerType = serverTypes[i];
		          if (thisServerType != null)
		          {
			          IRuntimeType thisServerTypeRuntimeType = thisServerType.getRuntimeType();
			          if (sRuntimeType != null && thisServerTypeRuntimeType != null && thisServerTypeRuntimeType.getId().equals(sRuntimeType.getId()))
			          {
			            serverType = thisServerType;
			            break outer;
			          }
		          }
		        }
	        }
	      }
	    }

	    return serverType;

  }  
  
  protected IServer getServerFromProjectType(String templateId, FacetMatcher facetMatcher)
  {
    IServer server = null;
    Set facets = FacetUtils.getInitialFacetVersionsFromTemplate(templateId);
    if (facetMatcher.getFacetsToAdd() != null)
    {
      Iterator itr = facetMatcher.getFacetsToAdd().iterator();
      while (itr.hasNext())
      {
        facets.add(itr.next());  
      }            
    }
    server = getServerFromFacets(facets);
    return server;
  }
  
  protected IServerType getServerTypeFromProjectType(String templateId, FacetMatcher facetMatcher)
  {
    IServerType serverType = null;
    Set facets = FacetUtils.getInitialFacetVersionsFromTemplate(templateId);
    if (facetMatcher.getFacetsToAdd() != null)
    {
      Iterator itr = facetMatcher.getFacetsToAdd().iterator();
      while (itr.hasNext())
      {
        facets.add(itr.next());  
      }            
    }
    //TODO Instead of passing in a single set of facets, pass in multiple sets, if the
    //jst.java facet is one of them and the clientRuntimeId allows newer.
    serverType = getServerTypeFromFacets(facets);
    return serverType;    
  }
  
  private String getDefaultClientProjectTemplate()
  {
    String[] templates = WebServiceRuntimeExtensionUtils2.getClientProjectTemplates(clientIds_.getTypeId(), clientIds_.getRuntimeId());
    
    //Walk the list of client project types in the project topology preference
    ProjectTopologyContext ptc= WebServiceConsumptionUIPlugin.getInstance().getProjectTopologyContext();
    String[] preferredTemplateIds = ptc.getClientTypes();
    for (int j=0; j<preferredTemplateIds.length; j++)
    {
      for (int i=0; i<templates.length; i++)
      {
        String templateId = templates[i];
        if (templateId.equals(preferredTemplateIds[j]))
        {
          
          boolean matches = WebServiceRuntimeExtensionUtils2.doesClientRuntimeSupportTemplate(clientRuntimeId_, templateId);
          if (matches)
          {
            return templates[i];            
          }
        }                                    
      }      
    }

    //Since the preferredTemplateIds contains the union of all project types for all client runtimes, we are
    //guaranteed to have returned by now, so the code below will never be executed under normal
    //circumstances. Just return something to satisfy the compiler.    
    if (templates.length > 0)
      return templates[0];
    
    return "";
  }
  
  private String getDefaultClientProjectName()
  {
    ValidationUtils vu = new ValidationUtils();
    IProject[] projects = FacetUtils.getAllProjects();
    ClientRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getClientRuntimeDescriptorById(clientRuntimeId_);
    RequiredFacetVersion[] rfvs = desc.getRequiredFacetVersions();
    
    //Check each project and its facetRuntime for compatibility with the clientRuntime
    for (int i=0; i<projects.length; i++)
    {
      if (!vu.isProjectServiceProject(projects[i], wsdlURI_, parser_))
      {
        Set facetVersions = FacetUtils.getFacetsForProject(projects[i].getName());
        org.eclipse.wst.common.project.facet.core.runtime.IRuntime fRuntime = null;
        String fRuntimeName = null;
        fRuntime = FacetUtils.getFacetRuntimeForProject(projects[i].getName());
        if (fRuntime != null)
        {
          fRuntimeName = fRuntime.getName();
        }

        if (facetVersions != null)
        {

          // FacetMatcher fm = FacetUtils.match(rfvs, facetVersions);
          FacetMatcher fm = FacetMatchCache.getInstance().getMatchForProject(true, clientRuntimeId_, projects[i].getName());
          boolean facetRuntimeMatches = true;
          if (fRuntimeName != null)
          {
            facetRuntimeMatches = FacetUtils.isFacetRuntimeSupported(rfvs, fRuntimeName);
          }

          if (fm.isMatch() && facetRuntimeMatches)
          {
            clientFacetMatcher_ = fm;
            return projects[i].getName();
          }
        }
      }
    }
    
    //No project was suitable, return a new project name
    return ResourceUtils.getDefaultWebProjectName();
    
  }
  
  private DefaultRuntimeTriplet getDefaultClientRuntimeForFixedRuntimeAndServer(IProject project, String runtimePreferredServer)
  {
    String[] clientRuntimes = WebServiceRuntimeExtensionUtils2.getClientRuntimesByType(clientIds_.getTypeId(), runtimePreferredServer);
    ArrayList validClientRuntimes = new ArrayList();
    for (int i=0; i<clientRuntimes.length; i++ )
    {
      ClientRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getClientRuntimeDescriptorById(clientRuntimes[i]);
      if (desc.getRuntime().getId().equals(clientIds_.getRuntimeId()))
      {
        //Check if this client runtime supports the server
        if (WebServiceRuntimeExtensionUtils2.doesClientRuntimeSupportServer(desc.getId(), clientIds_.getServerId()))
        {
          validClientRuntimes.add(desc.getId());
          if (project != null && project.exists())
          {
            //RequiredFacetVersion[] rfv = desc.getRequiredFacetVersions();
            Set facetVersions = FacetUtils.getFacetsForProject(project.getName());
            if (facetVersions != null)
            {
              //FacetMatcher fm = FacetUtils.match(rfv, facetVersions);
              FacetMatcher fm = FacetMatchCache.getInstance().getMatchForProject(true, clientRuntimes[i], project.getName());
              if (fm.isMatch())
              {
                DefaultRuntimeTriplet drt = new DefaultRuntimeTriplet();
                drt.setFacetMatcher(fm);
                drt.setProjectName(project.getName());
                drt.setRuntimeId(desc.getId());
                return drt;                
              }                      
            }
          }
          
        }
      }
      
    }
    
    if (validClientRuntimes.size() > 0)
    {
      //We couldn't match to the initially selected project so return the first valid runtime.
      DefaultRuntimeTriplet drt = new DefaultRuntimeTriplet();
      drt.setFacetMatcher(null);
      drt.setProjectName(null);
      drt.setRuntimeId(((String[])validClientRuntimes.toArray(new String[0]))[0]);
      return drt;            
    }
    else
    {
      //There are no client runtimes that match the fixed runtime and server. Fall back to original algorithm
      clientIdsFixed_ = false;
      return getDefaultRuntime(project, clientIds_.getTypeId(), true, clientIds_.getServerId());
    }
  }  
    
  protected DefaultRuntimeTriplet getDefaultRuntime(IProject project, String typeId, boolean isClient, String runtimePreferredServer)
  {
    String[] runtimes = null;
    if (isClient)
    {
      runtimes = WebServiceRuntimeExtensionUtils2.getClientRuntimesByType(typeId, runtimePreferredServer);
    }
    else
    {
      runtimes = WebServiceRuntimeExtensionUtils2.getServiceRuntimesByServiceType(typeId, runtimePreferredServer);
    }
        
    //Split the array of service/client runtimes into one containing the preferred set and one containing the rest.
    PersistentServerRuntimeContext context = WebServiceConsumptionUIPlugin.getInstance().getServerRuntimeContext();
    String preferredRuntimeId = context.getRuntimeId();
    String fallbackRuntimeId = context.getFallbackRuntimeId();
    ArrayList preferredRuntimeIdsList = new ArrayList();
    ArrayList otherRuntimeIdsList = new ArrayList();
    for (int k=0; k<runtimes.length; k++ )
    {
      String descRuntimeId = null;
      if (isClient)
      {
        ClientRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getClientRuntimeDescriptorById(runtimes[k]);
        descRuntimeId = desc.getRuntime().getId();
      }
      else
      {
        ServiceRuntimeDescriptor desc = WebServiceRuntimeExtensionUtils2.getServiceRuntimeDescriptorById(runtimes[k]);
        descRuntimeId = desc.getRuntime().getId();
      }
      
      if (descRuntimeId.equals(preferredRuntimeId))
      {
        preferredRuntimeIdsList.add(runtimes[k]);
      }
      else if (descRuntimeId.equals(fallbackRuntimeId)) 
      {
    	otherRuntimeIdsList.add(0, runtimes[k]);  // add to beginning of otherRuntimeIdsList
      }
      else
      {
        otherRuntimeIdsList.add(runtimes[k]);
      }
    }
    String[] preferredRuntimeIds = (String[])preferredRuntimeIdsList.toArray(new String[0]);
    String[] otherRuntimeIds = (String[])otherRuntimeIdsList.toArray(new String[0]);
    
    Set facetVersions = null;
    org.eclipse.wst.common.project.facet.core.runtime.IRuntime fRuntime = null;
    String fRuntimeName = null;
    
    //If the initially selected project exists and facets can be inferred from it, look for
    //a service/client runtime that matches the project's facets and also, if possible, its facet runtime.
    //Preference should be given to the preferred service/client runtimes. 
    if (project != null && project.exists())
    {
      facetVersions = FacetUtils.getFacetsForProject(project.getName());
      fRuntime = FacetUtils.getFacetRuntimeForProject(project.getName());
      fRuntimeName = null;
      if (fRuntime != null)
      {
        fRuntimeName = fRuntime.getName();        
      }
      
      if (facetVersions != null)
      {
        //1. First check to see if one of the preferred service/client runtimes matches the existing
        //project's facets and runtime.
        for (int p = 0; p < preferredRuntimeIds.length; p++)
        {
          RequiredFacetVersion[] prfv = null;
          if (isClient)
          {
            prfv = WebServiceRuntimeExtensionUtils2.getClientRuntimeDescriptorById(preferredRuntimeIds[p]).getRequiredFacetVersions();
          }
          else
          {
            prfv = WebServiceRuntimeExtensionUtils2.getServiceRuntimeDescriptorById(preferredRuntimeIds[p]).getRequiredFacetVersions();
          }
          
          //FacetMatcher fm = FacetUtils.match(prfv, facetVersions);
          FacetMatcher fm = FacetMatchCache.getInstance().getMatchForProject(isClient, preferredRuntimeIds[p], project.getName());
          boolean facetRuntimeMatches = true;
          if (fRuntimeName != null)
          {
            facetRuntimeMatches = FacetUtils.isFacetRuntimeSupported(prfv, fRuntimeName);  
          }          
          
          if (fm.isMatch() && facetRuntimeMatches)
          {
            DefaultRuntimeTriplet drt = new DefaultRuntimeTriplet();
            drt.setFacetMatcher(fm);
            drt.setProjectName(project.getName());
            drt.setRuntimeId(preferredRuntimeIds[p]);
            return drt;
          }
        }
        
        //2. Second, check to see if one of the other clientRuntimes matches the existing
        //project's facets and runtime.        
        for (int i=0; i<otherRuntimeIds.length; i++)
        {        
          RequiredFacetVersion[] rfv = null;
          if (isClient)
          {
            rfv = WebServiceRuntimeExtensionUtils2.getClientRuntimeDescriptorById(otherRuntimeIds[i]).getRequiredFacetVersions();  
          }
          else
          {
            rfv = WebServiceRuntimeExtensionUtils2.getServiceRuntimeDescriptorById(otherRuntimeIds[i]).getRequiredFacetVersions();
          }
          
          FacetMatcher fm = FacetMatchCache.getInstance().getMatchForProject(isClient, otherRuntimeIds[i], project.getName());
          boolean facetRuntimeMatches = true;
          if (fRuntimeName != null)
          {
            facetRuntimeMatches = FacetUtils.isFacetRuntimeSupported(rfv, fRuntimeName);  
          }                      
          if (fm.isMatch() && facetRuntimeMatches)
          {
            DefaultRuntimeTriplet drt = new DefaultRuntimeTriplet();
            drt.setFacetMatcher(fm);
            drt.setProjectName(project.getName());
            drt.setRuntimeId(otherRuntimeIds[i]);
            return drt;
          }                              
        }
        
        //3. Third, check to see if one of the preferred clientRuntimes matches the existing
        //project's facets.
        for (int p = 0; p < preferredRuntimeIds.length; p++)
        {
            FacetMatcher fm = FacetMatchCache.getInstance().getMatchForProject(isClient, preferredRuntimeIds[p], project.getName()); 
            if (fm.isMatch())
            {
              DefaultRuntimeTriplet drt = new DefaultRuntimeTriplet();
              drt.setFacetMatcher(fm);
              drt.setProjectName(project.getName());
              drt.setRuntimeId(preferredRuntimeIds[p]);
              return drt;
            }         
        }
        
        //4. Fourth, check to see if the one the other clientRuntimes matches the existing
        //project's facets.        
        for (int i=0; i<otherRuntimeIds.length; i++)
        {
            FacetMatcher fm = FacetMatchCache.getInstance().getMatchForProject(isClient, otherRuntimeIds[i], project.getName()); 
            if (fm.isMatch())
            {
              DefaultRuntimeTriplet drt = new DefaultRuntimeTriplet();
              drt.setFacetMatcher(fm);
              drt.setProjectName(project.getName());
              drt.setRuntimeId(otherRuntimeIds[i]);
              return drt;
            }        
        }        
      }            
    }
    
    //Haven't returned yet so this means that the intitially selected project cannot be used
    //to influence the selection of the service/client runtime. 
    
      //Use the preferred project types to influence the selection of a runtime.
      ProjectTopologyContext ptc = WebServiceConsumptionUIPlugin.getInstance().getProjectTopologyContext();
      String[] preferredTemplateIds = null;
      if (isClient)
      {
        preferredTemplateIds = ptc.getClientTypes();  
      }
      else
      {
        preferredTemplateIds = ptc.getServiceTypes();
      }
      
    
      for (int n=0; n<preferredTemplateIds.length; n++)
      {
        String preferredTemplateId = preferredTemplateIds[n];

        for (int m=0; m<preferredRuntimeIds.length; m++)
        {
          //If this client or service runtime supports this template, choose it and exit.        
          boolean matches = false;
          if (isClient)
          {
            matches = WebServiceRuntimeExtensionUtils2.doesClientRuntimeSupportTemplate(preferredRuntimeIds[m], preferredTemplateId);            
          }
          else
          {
            matches = WebServiceRuntimeExtensionUtils2.doesServiceRuntimeSupportTemplate(preferredRuntimeIds[m], preferredTemplateId);
          }
          
          if (matches)
          {
            DefaultRuntimeTriplet drt = new DefaultRuntimeTriplet();
            drt.setFacetMatcher(null);
            //If the project doesn't exist, use the name of the project that was passed in.
            //If the project exists, it means that previous code in this method
            //determined it to not be a suitable project. Clear the project name.
            if (project==null || project.exists())
            {
              drt.setProjectName(null);
            }
            else
            {
              drt.setProjectName(project.getName());
            }
            drt.setRuntimeId(preferredRuntimeIds[m]);
            return drt;            
          }        
        }
      }
    
    
    //Still haven't returned. Return the first preferred service/client runtime id.
    if (preferredRuntimeIds.length > 0)
    {
      DefaultRuntimeTriplet drt = new DefaultRuntimeTriplet();
      drt.setFacetMatcher(null);
      //If the project doesn't exist, use the name of the project that was passed in.
      //If the project exists, it means that previous code in this method
      //determined it to not be a suitable project. Clear the project name.      
      if (project==null || project.exists())
      {
        drt.setProjectName(null);
      }
      else
      {
        drt.setProjectName(project.getName());
      }
      drt.setRuntimeId(preferredRuntimeIds[0]);
      return drt;      
    }
      
    if (runtimes.length > 0)
    {
      DefaultRuntimeTriplet drt = new DefaultRuntimeTriplet();
      drt.setFacetMatcher(null);
      //If the project doesn't exist, use the name of the project that was passed in.
      //If the project exists, it means that previous code in this method
      //determined it to not be a suitable project. Clear the project name.
      if (project==null || project.exists())
      {
        drt.setProjectName(null);
      }
      else
      {
        drt.setProjectName(project.getName());
      }
      drt.setRuntimeId(runtimes[0]);
      return drt;
    }
    else
    {
      DefaultRuntimeTriplet drt = new DefaultRuntimeTriplet();
      drt.setFacetMatcher(null);
      //If the project doesn't exist, use the name of the project that was passed in.
      //If the project exists, it means that previous code in this method
      //determined it to not be a suitable project. Clear the project name.
      if (project==null || project.exists())
      {
        drt.setProjectName(null);
      }
      else
      {
        drt.setProjectName(project.getName());
      }
      drt.setRuntimeId(null);
      return drt;
    }    
  }
  /**
 * 
 * @param project
 * @return
 */
  protected SelectionListChoices getProjectEARChoice(IProject project)
  {
    String[] flexProjects = getAllFlexibleProjects();
    SelectionList list = new SelectionList(flexProjects, 0);
    return new SelectionListChoices(list, null);
  }
  
  protected SelectionList getEARProjects()
  {
    String[] flexProjects = getAllFlexibleProjects();
    return new SelectionList(flexProjects, 0);
  }
  
  protected IResource getResourceFromInitialSelection(IStructuredSelection selection)
  {
    if (selection != null && selection.size() == 1)
    {
      Object obj = selection.getFirstElement();
      if (obj != null) 
      {
        try
        { 
          IResource resource = ResourceUtils.getResourceFromSelection(obj);
          return resource;
        } catch(CoreException e)
        {
          return null;
        }        
      }
    }
    return null;
  }
  
  
      
  /*
   * Set defaults for the client-side from the service-side if possible.
   * Sets clientProjectName_ to a value based on the service project name.
   * 
   * Returns an IStatus.OK if the service side values for server and Web 
   * service runtime can be used to set the values for clientRuntimeId_,
   * clientComponentType_, all the values in clientIds_, and clientEarProjectName_.
   * 
   * Returns an IStatus.ERROR otherwise, leaving only the clientProjectName_ set. 
   */
  protected IStatus defaultClientSideFromServiceSide(String serviceProjectName, TypeRuntimeServer serviceIds, boolean serviceNeedEAR, String serviceEarProjectName)
  {
    //1. Start with setting the default client project name based on the service project name.
    boolean isEJB = false;
    String implId = WebServiceRuntimeExtensionUtils2.getWebServiceImplIdFromTypeId(serviceIds.getTypeId());
    isEJB = (implId.equals("org.eclipse.jst.ws.wsImpl.ejb"));
    String[] updatedNames = ResourceUtils.getClientProjectComponentName(serviceProjectName, serviceProjectName, isEJB);
    clientProjectName_ = updatedNames[0];
    
    //2. Ideally, the server and runtime on the client-side will be defaulted
    //   to the same values as the service side. If a client runtime id that 
    //   supports clientProjectName_ and the service-side server and runtime defaults
    //   can be found, choose it.
    IProject clientProject = ProjectUtilities.getProject(clientProjectName_);
    TypeRuntimeServer testIds = new TypeRuntimeServer();
    testIds.setTypeId(clientIds_.getTypeId());
    testIds.setRuntimeId(serviceIds.getRuntimeId());
    testIds.setServerId(serviceIds.getServerId());
    testIds.setServerInstanceId(serviceIds.getServerInstanceId());
    
    if (clientProject.exists())
    {
      clientComponentType_ = "";
      clientRuntimeId_ = WebServiceRuntimeExtensionUtils2.getClientRuntimeId(testIds, serviceProjectName, clientComponentType_);
      if (clientRuntimeId_ != null && clientRuntimeId_.length()>0)
      {
        clientIds_.setRuntimeId(serviceIds.getRuntimeId());
        clientIds_.setServerId(serviceIds.getServerId());
        clientIds_.setServerInstanceId(serviceIds.getServerInstanceId());
      }      
    }
    else
    {
      //See if there is a client project type that supports the service-side
      //server and runtime defaults. Pick a client project type based on project topology preferences.
      //Choose the clientRuntimeId_ accordingly.
      String[] templateIds = WebServiceRuntimeExtensionUtils2.getClientProjectTemplates(clientIds_.getTypeId(), testIds.getRuntimeId());
      if (templateIds != null && templateIds.length > 0)
      {
        ProjectTopologyContext ptc = WebServiceConsumptionUIPlugin.getInstance().getProjectTopologyContext();
        String[] preferredTemplateIds = ptc.getClientTypes();
        outer: for (int j = 0; j < preferredTemplateIds.length; j++)
        {
          for (int i = 0; i < templateIds.length; i++)
          {
            String templateId = templateIds[i];
            if (templateId.equals(preferredTemplateIds[j]))
            {
              // Get a clientRuntimeId for this template
              String newClientRuntimeId = WebServiceRuntimeExtensionUtils2.getClientRuntimeId(testIds, clientProjectName_,
                  templateId);
              if (newClientRuntimeId.length() > 0)
              {
                clientRuntimeId_ = newClientRuntimeId;
                clientComponentType_ = templateId;
                clientIds_.setRuntimeId(serviceIds.getRuntimeId());
                clientIds_.setServerId(serviceIds.getServerId());
                clientIds_.setServerInstanceId(serviceIds.getServerInstanceId());                
                break outer;
              }
            }
          }
        }
      }
    } 
    
    //3. If step 2 was successful, clientRuntimeId_ should now be set, along with clientProjectName_,
    //   clientComponentType_, and all the values in clientIds_. All that remains is setting the EAR.
    if (clientRuntimeId_ != null && clientRuntimeId_.length()>0)
    {
      setDefaultClientEarProject();
      //Update the client side EAR from the service side EAR if necessary.
      if (serviceNeedEAR)
      {
        defaultClientEarFromServiceEar(serviceProjectName, serviceEarProjectName); 
      }
      return Status.OK_STATUS;
    }
    else
    {
      //Step 2 was not successful. Client side defaulting cannot be done using the service side server
      //and web service runtime defaults. Return an error status.
      return StatusUtils.errorStatus("");
    }
  }
  
  protected void defaultClientEarFromServiceEar(String serviceProjectName, String serviceEarProjectName)
  {
    //Client side
    if (clientNeedEAR_)
    {
      IProject clientProject = ProjectUtilities.getProject(clientProjectName_);
      if(clientProject==null || !clientProject.exists() 
        || !(clientEarProjectName_.equalsIgnoreCase(serviceEarProjectName)))
      {
        ProjectTopologyContext ptc= WebServiceConsumptionUIPlugin.getInstance().getProjectTopologyContext();         
        if (!ptc.isUseTwoEARs()) 
        {
          clientEarProjectName_ = serviceEarProjectName;
        }
        else 
        {
          IProject proxyEARProject = getUniqueClientEAR(clientEarProjectName_, serviceEarProjectName, clientProjectName_, serviceProjectName);
          clientEarProjectName_ = proxyEARProject.getName();
        }     
      }
    }
    
  }
  
  private IProject getUniqueClientEAR(String earProjectName, String serviceEARProject, String clientProjectName, String serviceProjectName) {

    String projectName = new String();
    //If the client project doesn't exist and the service project does, ensure the
    //the client side EAR's J2EE level is such that the service project could be added to it.
    //This will ensure we don't default the page with a client project EAR at a lower
    //J2EE level than the service side.
    boolean goodJ2EELevel = true;
    if (!earProjectName.equalsIgnoreCase(serviceEARProject))
    {
      IProject clientProject = ProjectUtilities.getProject(clientProjectName);
      IProject serviceProject = ProjectUtilities.getProject(serviceProjectName);
      IProject earProject = ProjectUtilities.getProject(earProjectName);
      if (!clientProject.exists() && serviceProject.exists())
      {
        IStatus associationStatus = J2EEUtils.canAssociateProjectToEAR(serviceProject, earProject);
        goodJ2EELevel = (associationStatus.getSeverity() == IStatus.OK);
      }
    }
    
    if (!earProjectName.equalsIgnoreCase(serviceEARProject) && goodJ2EELevel) {
      projectName = earProjectName;
    }    
    else {
      projectName = clientProjectName+DEFAULT_CLIENT_EAR_PROJECT_EXT;
      int i=1;      
      while (projectName.equalsIgnoreCase(serviceEARProject)) {
        projectName = projectName+i;
        i++;
      }
    }
    return projectName.equals("") ? null : ResourceUtils.getWorkspaceRoot().getProject(projectName);
    
  }
  
  private void setDefaultsForExtension(IEnvironment env)
  {
    IWebServiceRuntime wsrt = WebServiceRuntimeExtensionUtils2.getClientRuntime(clientRuntimeId_);
    if (wsrt != null)
    {
      WebServiceClientInfo wsInfo = new WebServiceClientInfo();      
      wsInfo.setServerFactoryId(clientIds_.getServerId());
      wsInfo.setServerInstanceId(clientIds_.getServerInstanceId());
      wsInfo.setState(WebServiceState.UNKNOWN_LITERAL);
      wsInfo.setWebServiceRuntimeId(clientIds_.getRuntimeId());
      wsInfo.setWsdlURL(wsdlURI_);

      webServiceClient_ = wsrt.getWebServiceClient(wsInfo);
      WebServiceScenario scenario = WebServiceScenario.CLIENT_LITERAL;
      if (resourceContext_ != null)
      {
        context_ = new SimpleContext(true, true, true, true, true, true, test_, false, scenario, resourceContext_.isOverwriteFilesEnabled(), resourceContext_
            .isCreateFoldersEnabled(), resourceContext_.isCheckoutFilesEnabled());
      }
    }
  
  }
  
  public void setClientInitialSelection(IStructuredSelection selection)
  {
    if (clientInitialProject_ == null)
    {
      clientInitialProject_ = getProjectFromInitialSelection(selection);
    }
  }
  
  // This is for the Ant scenario where the client project name can be set in the property file.
  // If the user has set the ClientProjectName use it for defaulting purposes
  public void setClientProjectName(String name)
  {
	  clientProjectName_ = name;
  }

  public void setClientInitialProject(IProject clientInitialProject)
  {
    clientInitialProject_ = clientInitialProject;
  }
  
  /**
   * @param initialInitialSelection_ The initialInitialSelection_ to set.
   */
  public void setInitialInitialSelection(IStructuredSelection initialInitialSelection)
  {
    initialProject_ = getProjectFromInitialSelection(initialInitialSelection);
  }
  
  public boolean getClientNeedEAR()
  {
    return clientNeedEAR_;
  }

  /**
   * @param parser_ The parser_ to set.
   */
  public void setWebServicesParser(WebServicesParser parser) {
    parser_ = parser;
  }
  
  public void setWsdlURI(String wsdlURI)
  {
    wsdlURI_ = wsdlURI;
  }
  
  public void setTestService(boolean testService)
  {
    test_ = testService;
  }   
  
  public void setResourceContext( ResourceContext resourceContext )
  {
    resourceContext_ = resourceContext;   
  }  
  
  private IProject getProjectFromInitialSelection(IStructuredSelection selection)
  {
    if (selection != null && selection.size() == 1)
    {
      Object obj = selection.getFirstElement();
      if (obj != null) 
      {
        try
        { 
          IResource resource = ResourceUtils.getResourceFromSelection(obj);
          if (resource==null) 
            return null;
          IProject p = ResourceUtils.getProjectOf(resource.getFullPath());
          return p;
        } catch(CoreException e)
        {
          return null;
        }        
      }
    }
    return null;
  }
  
  protected String[] getAllFlexibleProjects()
  {
    Vector v = new Vector();
    IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
    for (int i = 0; i < projects.length; i++)
    {
      if (!projects[i].getName().equals("Servers") && !projects[i].getName().startsWith("."))
      {
        v.add(projects[i].getName());
      }
    }    
    
    return (String[])v.toArray(new String[0]);
    
  }
  
  protected class FacetRuntimeMatcher
  {
    FacetMatcher facetMatcher;
    boolean runtimeMatches;
    
    public FacetMatcher getFacetMatcher()
    {
      return facetMatcher;
    }
    public void setFacetMatcher(FacetMatcher facetMatcher)
    {
      this.facetMatcher = facetMatcher;
    }
    public boolean isRuntimeMatches()
    {
      return runtimeMatches;
    }
    public void setRuntimeMatches(boolean runtimeMatches)
    {
      this.runtimeMatches = runtimeMatches;
    }   
  }
  
  protected class DefaultRuntimeTriplet
  {
    FacetMatcher facetMatcher_;
    String projectName_;
    String runtimeId_;
    
    
    public DefaultRuntimeTriplet()
    {
    }
    
    public FacetMatcher getFacetMatcher()
    {
      return facetMatcher_;
    }
    public void setFacetMatcher(FacetMatcher facetMatcher_)
    {
      this.facetMatcher_ = facetMatcher_;
    }
    public String getProjectName()
    {
      return projectName_;
    }
    public void setProjectName(String projectName_)
    {
      this.projectName_ = projectName_;
    }
    public String getRuntimeId()
    {
      return runtimeId_;
    }
    public void setRuntimeId(String runtimeId_)
    {
      this.runtimeId_ = runtimeId_;
    }        
  }
}
