/*******************************************************************************
 * 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
 * 20080731   242721 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 (otherRuntimeIds.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(otherRuntimeIds[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())
      {
        boolean canAssociate = J2EEUtils.canAssociateProjectToEARWithoutWarning(serviceProject, earProject);
        goodJ2EELevel = (canAssociate);
      }
    }
    
    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_;
    }        
  }
}
