/*******************************************************************************
 * Copyright (c) 2004, 2009 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
 * -------- -------- -----------------------------------------------------------
 * 20060524   142635 gilberta@ca.ibm.com - Gilbert Andrews
 * 20060815   104870 makandre@ca.ibm.com - Andrew Mak, enable/disable test page controls base on settings in test facility extension
 * 20060815   153903 makandre@ca.ibm.com - Andrew Mak, Browse does not work in generate client test page
 * 20080325   184761 gilberta@ca.ibm.com - Gilbert Andrews
 * 20080425   221232 gilberta@ca.ibm.com - Gilbert Andrews
 * 20080506   227848 makandre@ca.ibm.com - Andrew Mak, Disabled "Run on Server" checkbox is in checked state
 * 20080527   234192 gilberta@ca.ibm.com - Gilbert Andrews
 * 20080616   237298 gilberta@ca.ibm.com - Gilbert Andrews
 * 20080619   237797 gilberta@ca.ibm.com - Gilbert Andrews
 * 20080723   241303 gilberta@ca.ibm.com - Gilbert Andrews
 * 20080808   243602 rkklai@ca.ibm.com   - Raymond Lai, fix NPE when changing runtime (the server combo)
 * 20090302   242462 ericdp@ca.ibm.com - Eric D. Peters, Save Web services wizard settings
 *******************************************************************************/
package org.eclipse.jst.ws.internal.consumption.ui.widgets.test;

import java.util.Set;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.consumption.common.FacetUtils;
import org.eclipse.jst.ws.internal.consumption.common.FolderResourceFilter;
import org.eclipse.jst.ws.internal.consumption.ui.ConsumptionUIMessages;
import org.eclipse.jst.ws.internal.consumption.ui.common.LabelsAndIds;
import org.eclipse.jst.ws.internal.consumption.ui.plugin.WebServiceConsumptionUIPlugin;
import org.eclipse.jst.ws.internal.ext.test.WebServiceTestExtension;
import org.eclipse.jst.ws.internal.ext.test.WebServiceTestRegistry;
import org.eclipse.jst.ws.internal.ui.common.ComboWithHistory;
import org.eclipse.jst.ws.internal.ui.common.UIUtils;
import org.eclipse.jst.ws.internal.ui.dialog.DialogUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.command.internal.env.core.selection.BooleanSelection;
import org.eclipse.wst.command.internal.env.core.selection.SelectionList;
import org.eclipse.wst.command.internal.env.ui.widgets.SimpleWidgetDataContributor;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents;
import org.eclipse.wst.server.core.IRuntime;
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.internal.facets.FacetUtil;


public class ClientTestWidget extends SimpleWidgetDataContributor
{
  private String pluginId_ = "org.eclipse.jst.ws.consumption.ui";

  /*CONTEXT_ID PWSM0001 for the Sample Page*/
  private String INFOPOP_PWSM_PAGE =  "PWSM0001";
  //
  private Button testCheckbox_;
  /*CONTEXT_ID PWSM0002 for the Test check box of the Sample Page*/
  private String INFOPOP_PWSM_CHECKBOX_TEST = "PWSM0002";

  private Combo testTypeCombo_;
   /*CONTEXT_ID PWSM0003 for the Test Type Combo box of the Sample Page*/
  private String INFOPOP_PWSM_COMBOBOX_TEST = "PWSM0003";
  
  private Combo runtimesCombo;
  /*CONTEXT_ID PWSM0004 for the server type combo box of the Sample Page*/
  private String INFOPOP_PWSM_COMBOBOX_SERVER = "PWSM0004";
  
  private Combo serverInstanceTypeCombo_;
  /*CONTEXT_ID PWSM0005 for the server instance combo box of the Sample Page*/
  private String INFOPOP_PWSM_COMBOBOX_SERVER_INSTANCE = "PWSM0005";

  private Text  jspFolderText_;
  /*CONTEXT_ID PWSM0008 for the JSP Folder field of the Sample Page*/
  private String INFOPOP_PWSM_TEXT_JSP_FOLDER = "PWSM0008";

  private Button sampleFolderBrowseButton_;
  /*CONTEXT_ID PWSM0009 for the JSP Folder Browse button of the Sample Page*/
  private String INFOPOP_PWSM_BUTTON_JSP_FOLDER_BROWSE = "PWSM0009";

  private Text projectCombo_;
  /*CONTEXT_ID PWSM0010 for the Project combo box of the Sample Page*/
  private String INFOPOP_PWSM_COMBO_PROJECT = "PWSM0010";

  private Tree methodsTree_;

  private Button selectAllMethodsButton_;
  /*CONTEXT_ID PWSM0006 for the Select All button of the Sample Page*/
  private String INFOPOP_PWSM_BUTTON_SELECT_ALL = "PWSM0006";

  private Button deselectAllMethodsButton_;
  /*CONTEXT_ID PWSM0007 for the Deselect All button of the Sample Page*/
  private String INFOPOP_PWSM_BUTTON_DESELECT_ALL = "PWSM0007";

  private ComboWithHistory sampleFolderText_;
  /*CONTEXT_ID PWSM0014 for the Folder field of the Sample Page*/   
  private String INFOPOP_PWSM_TEXT_SAMPLE_FOLDER = "PWSM0014";
  private ModifyListener sampleFolderTextModifyListener;

  //
  private Button runTestCheckbox_;  
  /*CONTEXT_ID PWSM0015 for the run test check box of the Sample Page*/
  private String INFOPOP_PWSM_CHECKBOX_LAUNCH = "PWSM0015";
  //
  private Text earCombo_;
  /*CONTEXT_ID PWSM0016 for the EAR combo box of the Sample Page*/
  private String INFOPOP_PWSM_EAR_COMBO = "PWSM0016";
  
  private Composite            comboGroup_; 
  private SelectionList        testFacilities_;
  private FolderResourceFilter folderFilter_ = new FolderResourceFilter();
  private IStructuredSelection initialSelection_;
  private boolean isTestWidget = false;
  private boolean isPopup = false;
  private boolean isWebProject = false;
  
  private LabelsAndIds runtimes_;
  private LabelsAndIds serverInstances_;
  
  private IPath webContentPath_;
  private IResource webContent_;
    
  public WidgetDataEvents addControls( Composite parent, Listener statusListener )
  {
    
	  
	isTestWidget = true;
    UIUtils      uiUtils  = new UIUtils( pluginId_ );
        
	parent.setToolTipText( ConsumptionUIMessages.TOOLTIP_PWSM_PAGE );
	PlatformUI.getWorkbench().getHelpSystem().setHelp( parent, pluginId_ + "." + INFOPOP_PWSM_PAGE );
    
    testCheckbox_ = uiUtils.createCheckbox( parent, ConsumptionUIMessages.BUTTON_TEST,
    		ConsumptionUIMessages.TOOLTIP_PWSM_CHECKBOX_TEST,
                                            INFOPOP_PWSM_CHECKBOX_TEST );
    testCheckbox_.addSelectionListener( new SelectionAdapter()
                                        {
                                          public void widgetSelected( SelectionEvent evt )
                                          {
                                            handleTestButton();
                                          }
                                        });
    
    comboGroup_ = uiUtils.createComposite( parent, 3, 5, 0 );
    
    testTypeCombo_ = uiUtils.createCombo( comboGroup_, ConsumptionUIMessages.LABEL_TEST_TYPES,
    									ConsumptionUIMessages.TOOLTIP_PWSM_COMBOBOX_TEST,
                                          INFOPOP_PWSM_COMBOBOX_TEST,
                                          SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY );
    testTypeCombo_.addSelectionListener(
    		new SelectionAdapter() {
    			public void widgetSelected(SelectionEvent e) {
    				handleTestFacilitySelection();
    			}
    		}
    );    
    
    
    
    new Label( comboGroup_, SWT.NONE );
    
    projectCombo_ = uiUtils.createText( comboGroup_, ConsumptionUIMessages.LABEL_JSP_PROJECT_NAME,
    									ConsumptionUIMessages.TOOLTIP_PWSM_COMBO_PROJECT,
                                          INFOPOP_PWSM_COMBO_PROJECT,
                                          SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY );
    
    new Label( comboGroup_, SWT.NONE );
    
    
    earCombo_ = uiUtils.createText( comboGroup_, ConsumptionUIMessages.LABEL_EAR_PROJECTS,
    								ConsumptionUIMessages.TOOLTIP_PWSM_EAR_PROJECT,
                                     INFOPOP_PWSM_EAR_COMBO,
                                     SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY );
    
    new Label( comboGroup_, SWT.NONE );
    
    
    
    sampleFolderText_ = uiUtils.createComboWithHistory(comboGroup_, ConsumptionUIMessages.LABEL_FOLDER_NAME,
    										ConsumptionUIMessages.TOOLTIP_PWSM_TEXT_SAMPLE_FOLDER,
                                            INFOPOP_PWSM_TEXT_SAMPLE_FOLDER,
                                            SWT.SINGLE | SWT.BORDER , WebServiceConsumptionUIPlugin.getInstance().getDialogSettings());
    
    
	sampleFolderTextModifyListener = new ModifyListener() 
			{
			public void modifyText(ModifyEvent evt) {
				handleFolderText();
			}

			};
		
    sampleFolderText_.addModifyListener(sampleFolderTextModifyListener);
       
    sampleFolderBrowseButton_ = uiUtils.createPushButton( comboGroup_, ConsumptionUIMessages.BUTTON_BROWSE, 
    											ConsumptionUIMessages.TOOLTIP_PWSM_BUTTON_JSP_FOLDER_BROWSE,
                                                          INFOPOP_PWSM_BUTTON_JSP_FOLDER_BROWSE );
    sampleFolderBrowseButton_.addSelectionListener( new SelectionAdapter()
                                                    {
                                                      public void widgetSelected( SelectionEvent evt )
                                                      {
                                                        handleSampleBrowse(); 
                                                      }
                                                    });
    
    jspFolderText_ = uiUtils.createText(comboGroup_, ConsumptionUIMessages.LABEL_JSP_FOLDER_NAME,
    		ConsumptionUIMessages.TOOLTIP_PWSM_TEXT_JSP_FOLDER,
            INFOPOP_PWSM_TEXT_JSP_FOLDER,
            SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY );
    
    
    new Label( comboGroup_, SWT.NONE );
    
    Group methodsGroup = uiUtils.createGroup( parent, ConsumptionUIMessages.LABEL_METHODS,  
    				ConsumptionUIMessages.TOOLTIP_PWSM_TREE_METHODS, null );
    
	methodsGroup.setLayoutData( uiUtils.createFillAll() );
	
	GridLayout layout = new GridLayout();
	layout.marginHeight = 0;
	layout.marginWidth = 0;
	methodsGroup.setLayout( layout );
	
	// TODO No infopop for this tree.
	methodsTree_ = uiUtils.createTree( methodsGroup, ConsumptionUIMessages.TOOLTIP_PWSM_TREE_METHODS, 
	                                   null,
	                   				   SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL	| SWT.CHECK );

    Composite selectButtons = uiUtils.createComposite( methodsGroup, 2 );
    
    selectAllMethodsButton_ 
      = uiUtils.createPushButton( selectButtons, ConsumptionUIMessages.BUTTON_SELECT_ALL, 
    		  ConsumptionUIMessages.TOOLTIP_PWSM_BUTTON_SELECT_ALL,
                                                 INFOPOP_PWSM_BUTTON_SELECT_ALL );
    selectAllMethodsButton_.addSelectionListener( new SelectionAdapter() 
                                                  {
                                                    public void widgetSelected( SelectionEvent evt )
                                                    {
                                                      handleSelectAll( true );
                                                    }
                                                  });
    
    deselectAllMethodsButton_ 
      = uiUtils.createPushButton( selectButtons, ConsumptionUIMessages.BUTTON_DESELECT_ALL, 
    		  					ConsumptionUIMessages.TOOLTIP_PWSM_BUTTON_DESELECT_ALL,
                                  INFOPOP_PWSM_BUTTON_DESELECT_ALL );
    deselectAllMethodsButton_.addSelectionListener( new SelectionAdapter() 
                                                    {
                                                      public void widgetSelected( SelectionEvent evt )
                                                      {
                                                        handleSelectAll( false );
                                                      }
                                                    });
    
    runTestCheckbox_ = uiUtils.createCheckbox( parent, ConsumptionUIMessages.BUTTON_RUN_TEST,
    										ConsumptionUIMessages.TOOLTIP_PWSM_CHECKBOX_LAUNCH,
                                               INFOPOP_PWSM_CHECKBOX_LAUNCH );
    runTestCheckbox_.addSelectionListener( new SelectionAdapter() 
    {
        public void widgetSelected( SelectionEvent evt )
        {
          handleRunTestCheckBox();
        }
      });
    
    return this;
  }
  
  private void handleRunTestCheckBox(){
	  boolean enabled = runTestCheckbox_.getSelection();
	  runtimesCombo.setEnabled(enabled);
	  serverInstanceTypeCombo_.setEnabled(enabled);
	  
  }
  
  private void handleFolderText()
  {
	// webContentPath_ is set when jspFolderText_ is set for the first time.  Therefore,
	// if webContentPath_ is still null, there is no need to touch jspFolderText_ yet.
	  
	if (webContentPath_ == null)
		return;
	  
  	String folder = sampleFolderText_.getText();	
    jspFolderText_.setText(webContentPath_.toString() + IPath.SEPARATOR + folder);
  }
  
  private void handleSampleBrowse()
  {
    IPath      selectedPath       = null;
    IResource  initialResource    = null;
    
    try
    {
      initialResource = ResourceUtils.getResourceFromSelection( initialSelection_ );
    }
    catch( CoreException exc )
    {  
    }
    
    if( initialResource == null )initialResource = webContent_;
    
    IResource resource = DialogUtils.browseResources( comboGroup_.getShell(), 
                                                      webContent_,
                                                      initialResource, 
                                                      folderFilter_ );
    
    if( resource != null )
    {
      selectedPath = resource.getFullPath();   
    
      int webModuleSegments = selectedPath.matchingFirstSegments(webContentPath_);
  	  
      sampleFolderText_.removeModifyListener(sampleFolderTextModifyListener);
      sampleFolderText_.removeAll();
      
      if ( webModuleSegments < webContentPath_.segmentCount() )
      {
    	sampleFolderText_.add("", 0);
        handleFolderText();
      }
      else
      {
        sampleFolderText_.add(selectedPath.removeFirstSegments(webModuleSegments).toString(), 0);
        handleFolderText();
      }
      sampleFolderText_.select(0);
      sampleFolderText_.restoreWidgetHistory("org.eclipse.jst.ws.internal.consumption.ui.widgets.test.ClientTestWidget.sampleFolderText_");
      sampleFolderText_.addModifyListener(sampleFolderTextModifyListener);

    }
  }
  
  private void handleTestButton()
  {
    boolean enabled = testCheckbox_.getSelection();
    
    testTypeCombo_.setEnabled( enabled );
    
    if (enabled && testFacilities_ != null) {
    	handleTestFacilitySelection();
    	return;
    }    

    sampleFolderText_.setEnabled( enabled );
    methodsTree_.setEnabled( enabled );
    if(canRunTestClient_)
    	runTestCheckbox_.setEnabled( enabled );
    selectAllMethodsButton_.setEnabled( enabled );
    deselectAllMethodsButton_.setEnabled( enabled );
    sampleFolderBrowseButton_.setEnabled( enabled );
    
  
  
  }
  
  private void handleTestFacilitySelection() {
	  
	  String clientTestID = getTestFacility().getSelection();
	  	
	  WebServiceTestExtension testExtension = 
		  (WebServiceTestExtension) WebServiceTestRegistry.getInstance()
		  .getWebServiceExtensionsByName(clientTestID);
	    
      boolean hasCodeGen = testExtension.isCodeGenNeeded();
      
      // folder selection is only applicable for test facilities with codegen
      sampleFolderText_.setEnabled( hasCodeGen );
      sampleFolderBrowseButton_.setEnabled( hasCodeGen && webContent_ != null );
      
      boolean hasMethods = testExtension.areMethodsNeeded();
      
      // method selection is only applicable for test facilities with methods
      methodsTree_.setEnabled( hasMethods );      
      selectAllMethodsButton_.setEnabled( hasMethods );
      deselectAllMethodsButton_.setEnabled( hasMethods );
      
      // run on server only applicable for test facilities that needs launching
      if(canRunTestClient_)
    	  runTestCheckbox_.setEnabled( testExtension.isServerNeeded() );
  }
  
  private void handleSelectAll( boolean value )
  {
	TreeItem[] items = methodsTree_.getItems();
	
	for( int i = 0; i < items.length; i++ ) 
	{
	  items[i].setChecked(value);
	}
  } 
  
  private void handleServerChange()
  {
	  int selection = runtimesCombo.getSelectionIndex();
	  serverInstances_.clear();
	  serverInstanceTypeCombo_.removeAll();
	  IServer[] servers = org.eclipse.wst.server.core.ServerCore.getServers();
	  for(int j =0; j<servers.length;j++){
			String id = runtimes_.getId(selection);
			if(id.equals(servers[j].getRuntime().getId())){
				serverInstances_.add(servers[j].getId(), servers[j].getName());
				serverInstanceTypeCombo_.add(servers[j].getName());
			}
	  }
	  serverInstanceTypeCombo_.select(0);
	 
  }  
  
  // Here are the getters and setters for this widget.
  public void setTestService( Boolean testService )
  {
    testCheckbox_.setSelection( testService.booleanValue() );
    handleTestButton();
  }
  
  public Boolean getTestService()
  {
    return new Boolean( testCheckbox_.getSelection() );
  }
  
  public void setTestFacility( SelectionList testFacilities )
  {
    testFacilities_ = testFacilities;
    testTypeCombo_.setItems( testFacilities.getList() );
    testTypeCombo_.select( testFacilities.getIndex() );
    handleTestFacilitySelection();
  }
  
  public SelectionList getTestFacility()
  {
    testFacilities_.setIndex( testTypeCombo_.getSelectionIndex() );
    return testFacilities_;
  }
  
  public String getTestID()
  {
    return testTypeCombo_.getText();
  }
  
  /**
   * Given a project name which may be of the (obsolete) format "project/module",
   * return only the project part of the name
   * 
   * @param project The project name.
   * @return If the name has the format "project/module", returns only "project", 
   * otherwise returns the name as is.
   */
  private String extractProjectName(String project) {
	  
	  int index = project.indexOf("/");
	  
	  if (index != -1)
		  project = project.substring(0, index);
	  
	  return project;
  }
  
  
  public void initServersTypes() 
  {
	if(runtimes_  == null)
		runtimes_ = new LabelsAndIds();
	IServer[] servers = org.eclipse.wst.server.core.ServerCore.getServers();
	IRuntime[] runtimes = org.eclipse.wst.server.core.ServerCore.getRuntimes();
	IServerType[] serverTypes = ServerCore.getServerTypes();
	
	
	
	String projectName = projectCombo_.getText();
	
	Set projectFacets = FacetUtils.getFacetsForProject(projectName);
	for(int i = 0;i<runtimes.length;i++){
		boolean showServer = false;
		
		if(runtimes[i].isStub()){
			for(int l =0; l<servers.length;l++){
				if(servers[l].getRuntime() != null){
					if(runtimes[i].getId().equals(servers[l].getRuntime().getId())){
						showServer = true;
					}
				}
			}
		}
		else showServer = true;
		
		if(showServer && canRunTestClient_){	
			if(isWebProject){
				org.eclipse.wst.common.project.facet.core.runtime.IRuntime runtime = FacetUtil.getRuntime(runtimes[i]);
				if(FacetUtils.doesRuntimeSupportFacets(runtime, projectFacets)){
					runtimes_.add(runtimes[i].getId(), runtimes[i].getName());
					runtimesCombo.add( runtimes[i].getName() );
				}
			}
			else{
				runtimes_.add(runtimes[i].getId(), runtimes[i].getName());
				runtimesCombo.add( runtimes[i].getName() );	
			}
		}
	}
	
	runtimesCombo.select(0);
	if(serverInstances_  == null)
		serverInstances_ = new LabelsAndIds();
	
	
	String id = runtimes_.getId(0);
	if(id != null){
		for(int k =0; k<servers.length;k++){
			if(servers[k].getRuntime() != null){
				if(id.equals(servers[k].getRuntime().getId())&& canRunTestClient_){
					serverInstances_.add(servers[k].getId(), servers[k].getName());
					serverInstanceTypeCombo_.add(servers[k].getName());
				}
			}
		}
		serverInstanceTypeCombo_.select(0);
	}
		
	serverInstanceTypeCombo_.setEnabled(canRunTestClient_ && runTestCheckbox_.getSelection());
	runtimesCombo.setEnabled(canRunTestClient_ && runTestCheckbox_.getSelection());
  }
  
  
  
  
  public void setSampleProject(String clientProject) 
  {
	projectCombo_.setText(extractProjectName(clientProject));
  }
  
  public void setSampleProjectEAR(String clientProjectEAR) 
  {
    earCombo_.setText(extractProjectName(clientProjectEAR));
  }
  
  public String getFolder()
  {
    return sampleFolderText_.getText();
  }
  
  public void setFolder( String folder )
  {
    sampleFolderText_.removeModifyListener(sampleFolderTextModifyListener);
    sampleFolderText_.removeAll();
    sampleFolderText_.add( folder);
    sampleFolderText_.select(0);
    sampleFolderText_.addModifyListener(sampleFolderTextModifyListener);
    
  }
  
  public boolean getIsTestWidget()
  {
  	return isTestWidget;
  }
  
  public void setJspFolder( String folder )
  {
	webContentPath_ = (new Path(folder)).removeLastSegments(1);
	webContent_ = ResourceUtils.findResource(webContentPath_);	
	sampleFolderBrowseButton_.setEnabled(webContent_ != null);
	  
    jspFolderText_.setText( folder );
  }
  
  public String getJspFolder()
  {
    return jspFolderText_.getText();
  }
  
  public void setLaunchedServiceTestName (String launchedServiceTestName)
  {
  }
  
  public boolean getRunTestClient()
  {
    return runTestCheckbox_.getSelection();
  }
  
  public void setRunTestClient( boolean value )
  {
	  runTestCheckbox_.setSelection( value );
  }
  
  public void setIsWebProject( boolean value )
  {
	  isWebProject = value;
  }
  
  private boolean canRunTestClient_;
  
  public void setCanRunTestClient(boolean canRunTestClient){
	  canRunTestClient_ = canRunTestClient;
	  if(!canRunTestClient_) {
		  runTestCheckbox_.setSelection(false);
		  runTestCheckbox_.setEnabled(false);
	  }
  }
  
  public void setPopup(boolean popup){
	  isPopup = popup;
	  if(isPopup){
		  UIUtils      uiUtils  = new UIUtils( pluginId_ );
		  runtimesCombo = uiUtils.createCombo( comboGroup_, ConsumptionUIMessages.LABEL_SERVERS_LIST,
					ConsumptionUIMessages.TOOLTIP_PWSM_COMBOBOX_SERVER,
					INFOPOP_PWSM_COMBOBOX_SERVER,
		              SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY );
		    	runtimesCombo.addSelectionListener(
		    		new SelectionAdapter() {
		    			public void widgetSelected(SelectionEvent e) {
		    				handleServerChange();
		    			}
		    		}
		    	);    
		    
		  new Label( comboGroup_, SWT.NONE );
		
	  
		  serverInstanceTypeCombo_ = uiUtils.createCombo( comboGroup_, ConsumptionUIMessages.LABEL_SERVERS_INSTANCES,
					ConsumptionUIMessages.TOOLTIP_PWSM_COMBOBOX_SERVER_INSTANCE,
					INFOPOP_PWSM_COMBOBOX_SERVER_INSTANCE,
		              SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY );
		    
		  new Label( comboGroup_, SWT.NONE );
		  initServersTypes();
	  
	  }
  }
  
  public boolean getCanRunTestClient()
  {
	  return canRunTestClient_;
  }
  
  public String getServerInstanceId(){
	  int instanceLabel = serverInstanceTypeCombo_.getSelectionIndex();
	  if(instanceLabel == -1) return null;
	  return serverInstances_.getId(instanceLabel);
  }
  
  
  public String getExistingServerId(){
	  int typeLabel = runtimesCombo.getSelectionIndex();
	  if(typeLabel == -1) return null;
	  return runtimes_.getId(typeLabel);
  }
  
  public BooleanSelection[] getMethods()
  {
    TreeItem[]         items   = methodsTree_.getItems();
    BooleanSelection[] methods = new BooleanSelection[items.length];
    
    for( int index = 0; index < items.length; index++ )
    {
      methods[index] = new BooleanSelection( items[index].getText(), items[index].getChecked() );
    }
    
    return methods;
  }
  
  public void setMethods( BooleanSelection[] methods )
  {
    methodsTree_.removeAll();
    
    for( int index = 0; index < methods.length; index++ )
    {
      if(methods[index] == null)continue;
      TreeItem item = new TreeItem( methodsTree_, SWT.NULL );
      item.setText( methods[index].getValue() );
      item.setChecked( methods[index].isSelected() );
    }
  }
  
  public void setInitialSelection( IStructuredSelection selection )
  {
    initialSelection_ = selection;
  }
  
  public IStatus getStatus() {
	  if(!canRunTestClient_)
		  return StatusUtils.warningStatus(ConsumptionUIMessages.MSG_SERVER_NOT_FOUND_WARNING);
  
	  return  Status.OK_STATUS;
  }

public void externalize() {
	super.externalize();
	sampleFolderText_.storeWidgetHistory("org.eclipse.jst.ws.internal.consumption.ui.widgets.test.ClientTestWidget.sampleFolderText_");
}

public void internalize() {		
	sampleFolderText_.removeModifyListener(sampleFolderTextModifyListener);
	sampleFolderText_.restoreWidgetHistory("org.eclipse.jst.ws.internal.consumption.ui.widgets.test.ClientTestWidget.sampleFolderText_");
	sampleFolderText_.addModifyListener(sampleFolderTextModifyListener);
}
}
