/*******************************************************************************
 * Copyright (c) 2004, 2010 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
 * -------- -------- -----------------------------------------------------------
 * 20060407   135415 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060407   135443 joan@ca.ibm.com - Joan Haggarty
 * 20060410   135442 kathy@ca.ibm.com - Kathy Chan
 * 20060410   135441 joan@ca.ibm.com - Joan Haggarty
 * 20060410   135562 joan@ca.ibm.com - Joan Haggarty
 * 20060411   136167 kathy@ca.ibm.com - Kathy Chan
 * 20060417   136390/136391/136159 joan@ca.ibm.com - Joan Haggarty
 * 20060413   135581 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060420   136158 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060420   136705 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060420   136182 kathy@ca.ibm.com - Kathy Chan
 * 20060420   137820 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060420   135912 joan@ca.ibm.com - Joan Haggarty
 * 20060421   136761 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060424   138052 kathy@ca.ibm.com - Kathy Chan
 * 20060425   137831 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060426   138519 joan@ca.ibm.com - Joan Haggarty
 * 20060427   138058 joan@ca.ibm.com - Joan Haggarty
 * 20060504   138035 joan@ca.ibm.com - Joan Haggarty
 * 20060524   142276 joan@ca.ibm.com - Joan Haggarty
 * 20060529   141422 kathy@ca.ibm.com - Kathy Chan
 * 20060605   145081 joan@ca.ibm.com - Joan Haggarty
 * 20060607   144826 joan@ca.ibm.com - Joan Haggarty
 * 20060607   144049 joan@ca.ibm.com - Joan Haggarty
 * 20060614   146270 joan@ca.ibm.com - Joan Haggarty
 * 20060616   147317 joan@ca.ibm.com - Joan Haggarty
 * 20060717   150577 makandre@ca.ibm.com - Andrew Mak
 * 20060726   150865 sengpl@ca.ibm.com -  Seng Phung-Lu
 * 20060803   152486 makandre@ca.ibm.com - Andrew Mak, Typing WSDL in Service definition field is very slow
 * 20060817   140017 makandre@ca.ibm.com - Andrew Mak, longer project or server/runtime strings do not resize wizard
 * 20060825   135570 makandre@ca.ibm.com - Andrew Mak, Service implementation URL not displayed properly on first page
 * 20060829   155441 makandre@ca.ibm.com - Andrew Mak, web service wizard hangs during resize
 * 20060830   155114 pmoogk@ca.ibm.com - Peter Moogk, Updated patch for this defect.
 * 20060831   155441 makandre@ca.ibm.com - Andrew Mak, Small tweak for this bug
 * 20061003   159142 kathy@ca.ibm.com - Kathy Chan
 * 20061212   164177 makandre@ca.ibm.com - Andrew Mak, Incorrect validation error complaining about runtime not supporting a project type
 * 20061212   159911 makandre@ca.ibm.com - Andrew Mak, changing service definition resets some configuration fields
 * 20070205   172687 makandre@ca.ibm.com - Andrew Mak, NPE in Scencario Defaults preferences page
 * 20071130   203826 kathy@ca.ibm.com - Kathy Chan
 * 20080205   170141 kathy@ca.ibm.com - Kathy Chan
 * 20080215   216337 pmoogk@ca.ibm.com - Peter Moogk
 * 20080301   221034 kathy@ca.ibm.com - Kathy Chan
 * 20080312   147442 trungha@ca.ibm.com - Trung Ha
 * 20080318   213330 trungha@ca.ibm.com - Trung, Non-conventional Java naming prevents creating Web Services (client)
 * 20080326   198439 kathy@ca.ibm.com - Kathy Chan
 * 20080402   198439 kathy@ca.ibm.com - Kathy Chan
 * 20080416   215084 gilberta@ca.ibm.com - Gilbert Andrews
 * 20080417   227599 kathy@ca.ibm.com - Kathy Chan
 * 20080613   236523 makandre@ca.ibm.com - Andrew Mak, Overwrite setting on Web service wizard is coupled with preference
 * 20090926   248448 mahutch@ca.ibm.com - Mark Hutchinson, Should not resize WS Wizard for long WSDL file names
 * 20090121   261730 zhang@ca.ibm.com - Allan Zhang, WebService client runtime id return null
 * 20090302   242462 ericdp@ca.ibm.com - Eric D. Peters, Save Web services wizard settings
 * 20090313   268567 ericdp@ca.ibm.com - Eric D. Peters, persisted wizard settings gone unless launching on object
 * 20090326   269097 kchong@ca.ibm.com - Keith Chong, [Accessibility] Web services wizard dialog should be selected after canceling the Browse for class dialog
 * 20100511   309395 mahutch@ca.ibm.com - Mark Hutchinson, WS Wizard Converting Java Project into Utility Project without any warning
 *******************************************************************************/
package org.eclipse.jst.ws.internal.creation.ui.widgets;


import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
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.widgets.IObjectSelectionLaunchable;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.IPackable;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.ProjectSelectionDialog;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.WebServiceClientTypeWidget;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.object.IObjectSelectionWidget;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.object.ObjectSelectionOutputCommand;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.object.ObjectSelectionRegistry;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.object.ObjectSelectionWidget;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.object.Timer;
import org.eclipse.jst.ws.internal.consumption.ui.widgets.runtime.ProjectSelectionWidget;
import org.eclipse.jst.ws.internal.consumption.ui.wizard.RuntimeServerSelectionDialog;
import org.eclipse.jst.ws.internal.consumption.ui.wsrt.WebServiceImpl;
import org.eclipse.jst.ws.internal.consumption.ui.wsrt.WebServiceRuntimeExtensionUtils2;
import org.eclipse.jst.ws.internal.context.ScenarioContext;
import org.eclipse.jst.ws.internal.creation.ui.plugin.WebServiceCreationUIPlugin;
import org.eclipse.jst.ws.internal.creation.ui.widgets.runtime.ServerRuntimeSelectionWidgetDefaultingCommand;
import org.eclipse.jst.ws.internal.data.LabelsAndIds;
import org.eclipse.jst.ws.internal.data.TypeRuntimeServer;
import org.eclipse.jst.ws.internal.plugin.WebServicePlugin;
import org.eclipse.jst.ws.internal.ui.common.ComboWithHistory;
import org.eclipse.jst.ws.internal.ui.common.UIUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.Accessible;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleControlAdapter;
import org.eclipse.swt.accessibility.AccessibleControlEvent;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
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.events.SelectionListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
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.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.HyperlinkGroup;
import org.eclipse.ui.forms.HyperlinkSettings;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.eclipse.ui.forms.widgets.Hyperlink;
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.ui.widgets.PageInfo;
import org.eclipse.wst.command.internal.env.ui.widgets.SimpleWidgetDataContributor;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetContributor;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetContributorFactory;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents;
import org.eclipse.wst.ws.internal.parser.wsil.WebServicesParser;
import org.eclipse.wst.ws.internal.ui.plugin.WSUIPlugin;
import org.eclipse.wst.ws.internal.wsrt.IWebServiceRuntimeChecker;
import org.eclipse.wst.ws.internal.wsrt.WebServiceScenario;

public class ServerWizardWidget extends SimpleWidgetDataContributor implements Runnable, IPackable {
	
	//INFOPOPS
    /* CONTEXT_ID WSWSCEN0001 for the Scenario Page */
	private String INFOPOP_WSWSCEN_PAGE = "WSWSCEN0001";
	 /* CONTEXT_ID WSWSCEN0010 for the Web Service Type combo box of the Scenario Page */
	 private String INFOPOP_WSWSCEN_COMBO_SERVICETYPE = "WSWSCEN0010";
	 /* CONTEXT_ID WSWSCEN0014 for the monitor service checkbox of the Scenario page */
	 private String INFOPOP_WSWSCEN_CHECKBOX_MONITOR_SERVICE = "WSWSCEN0014";
	 /* CONTEXT_ID WSWSCEN0012 for the Launch UDDI check box of the Scenario Page */
	 private String INFOPOP_WSWSCEN_CHECKBOX_LAUNCH_WS = "WSWSCEN0012";
	 /* CONTEXT_ID WSWSCEN0020 for the Service Implemenation text field of the Scenario Page */
	 private String INFOPOP_WSWSCEN_TEXT_SERVICE_IMPL = "WSWSCEN0020";
	 /* CONTEXT_ID WSWSCEN0021 for theService Slider of the Scenario Page */
	 private String INFOPOP_WSWSCEN_SCALE_SERVICE = "WSWSCEN0021";
	 /* CONTEXT_ID WSWSCEN0022 for the Server hyperlink of the Scenario Page */
	 private String INFOPOP_WSWSCEN_HYPERLINK_SERVER = "WSWSCEN0022";
	 /* CONTEXT_ID WSWSCEN0023 for the Runtime hyperlink of the Scenario Page */
	 private String INFOPOP_WSWSCEN_HYPERLINK_RUNTIME = "WSWSCEN0023";
	 /* CONTEXT_ID WSWSCEN0024 for theProjects hyperlink of the Scenario Page */
	 private String INFOPOP_WSWSCEN_HYPERLINK_PROJECTS  = "WSWSCEN0024";
	 /* CONTEXT_ID WSWSCEN0030 for the Overwrite Files checkbox of the Scenario Page */
	 private String INFOPOP_WSWSCEN_CHECKBOX_OVERWRITE = "WSWSCEN0030";
	 
	private ScaleSelectionListener scaleSelectionListener = new ScaleSelectionListener();
	private Listener statusListener_;
	private ModifyListener objectModifyListener_ ;
	private int validationState_;
	boolean validObjectSelection_ = true;

	private ImageRegistry imageReg_;
	
	private TypeRuntimeServer ids_;
	private LabelsAndIds labelIds_;
	private String serviceProjectName_;
	private IProject initialProject_;
	private String serviceEarProjectName_;
	private String serviceComponentType_;
	private WebServicesParser parser_;
	private boolean needEar_;
		 
	private boolean developService_;
	private boolean assembleService_;
	private boolean deployService_;
	
	private IStructuredSelection objectSelection_;
	private Boolean testService_;
	private Boolean startService_;
	private Boolean installService_;

	private boolean displayPreferences_;
	private boolean preferencesPage_;

	private Composite groupComposite_;
	private Composite hCompService_;	
	private WebServiceClientTypeWidget clientWidget_;
    private Label serviceLabel_;
	private Combo webserviceType_;
	private ComboWithHistory serviceImpl_;
	private Scale serviceScale_;
	private Label topologySpot_;
	private Button browseButton_;
	private Button publishButton_;
	private Button monitorButton_;
	private Button overwriteButton_;	
	private ServiceImplSelectionDialog browseDialog_;
	private ProjectSelectionDialog projectDialog_;
	private Hyperlink hLinkServiceRuntime_;
	private Hyperlink hLinkServiceServer_;
	private Hyperlink hLinkServiceProject_;
	private Hyperlink hLinkServiceEAR_;
		
	private Object objectSelectionWidget_; //may be IObjectSelectionLaunchable or IObjectSelectionWidget
	
	private ResourceContext resourceContext_;
	
	private Timer timer_ = null;
		
	private UIUtils utils_ = new UIUtils("org.eclipse.jst.ws.creation.ui");
	
	private boolean forceRefreshRuntime = false;
	
	private String GRAPHIC_SERVICE_0="icons/service_test.jpg"; //$NON-NLS-N$
	private String GRAPHIC_SERVICE_1="icons/service_run.jpg";  //$NON-NLS-N$
	private String GRAPHIC_SERVICE_2="icons/service_install.jpg"; //$NON-NLS-N$
	private String GRAPHIC_SERVICE_3="icons/service_deploy.jpg"; //$NON-NLS-N$
	private String GRAPHIC_SERVICE_4="icons/service_assemble.jpg"; //$NON-NLS-N$
	private String GRAPHIC_SERVICE_5="icons/service_develop.jpg"; //$NON-NLS-N$
		
	private String ICON_SCALE_BG_0="icons/scale0_bground.jpg"; //$NON-NLS-N$
	private String ICON_SCALE_BG_1="icons/scale1_bground.jpg"; //$NON-NLS-N$
	private String ICON_SCALE_BG_2="icons/scale2_bground.jpg"; //$NON-NLS-N$
	private String ICON_SCALE_BG_3="icons/scale3_bground.jpg"; //$NON-NLS-N$
	private String ICON_SCALE_BG_4="icons/scale4_bground.jpg"; //$NON-NLS-N$
	private String ICON_SCALE_BG_5="icons/scale5_bground.jpg"; //$NON-NLS-N$
	private String ICON_SCALE_BG_6="icons/scale6_bground.jpg"; //$NON-NLS-N$

	private String SERVICE_RUNTIME_PREFIX = ConsumptionUIMessages.LABEL_RUNTIMES_LIST ; 
    private String SERVICE_SERVER_PREFIX =  ConsumptionUIMessages.LABEL_SERVERS_LIST;
    private String SERVICE_PROJECT_PREFIX = ConsumptionUIMessages.LABEL_SERVICE_PROJECT;
    private String SERVICE_EAR_PREFIX = ConsumptionUIMessages.LABEL_SERVICE_EAR_PROJECT;
    
    /**
     * @param displayPreferences Set to true if preferences such as overwrite should be displayed on the wizard page
     * @param prefPage  Set to true if the widget is being used on the preferences page.  Alters widget layout.
     */
	public ServerWizardWidget(boolean displayPreferences, boolean prefPage) {
		displayPreferences_ = displayPreferences;
		preferencesPage_ = prefPage;
		initImageRegistry();
		validationState_ = ValidationUtils.VALIDATE_ALL;
	}
	
	private Composite serviceComposite_;
	
	/**
	 * Run this ServerWizardWidget, which validates the entry field values.
	 */
	public void run() {
		
		// do minimal check here, this call will determine if we at least
		// have a "validObjectSelection_"
		checkServiceImplTextStatus();
		
		if (validObjectSelection_)
		{
			boolean refreshRuntime = (getWebServiceScenario() != WebServiceScenario.TOPDOWN); 
			
			if (objectSelectionWidget_ instanceof IObjectSelectionLaunchable)
		       {
				IObjectSelectionLaunchable launchable = (IObjectSelectionLaunchable)objectSelectionWidget_;
				callObjectTransformation(launchable.getObjectSelection(), launchable.getProject(), launchable.getComponentName(), refreshRuntime);								
		       }
			else 
			{
				IObjectSelectionWidget widget = (IObjectSelectionWidget)objectSelectionWidget_;
				callObjectTransformation(widget.getObjectSelection(), widget.getProject(), widget.getComponentName(), refreshRuntime);
		    }	
		}
		else
			setObjectSelection(null);
		
		// do full validation after all transformations and calculations have occurred
		validationState_ = ValidationUtils.VALIDATE_ALL;
		statusListener_.handleEvent(null);		
	}
	
	/**
	 * Pack this widget and the client-side widget as well. 
	 */
	private void packSelf() {
		// don't need to call packIt(), since clientWidget_ has a callback to packIt() already.
		clientWidget_.packIt();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jst.ws.internal.consumption.ui.widgets.IPackable#packIt()
	 */
	public void packIt() {		
		groupComposite_.pack(true);
		utils_.horizontalResize(groupComposite_.getShell(), groupComposite_, UIUtils.DEFAULT_PADDING);
	}
	
	public WidgetDataEvents addControls(Composite parent,
			Listener statusListener) {
				
		statusListener_ = statusListener;
		utils_.createInfoPop(parent, INFOPOP_WSWSCEN_PAGE);
		
		Composite typeComposite = utils_.createComposite(parent, 3);

		webserviceType_ = utils_.createCombo(typeComposite,
				ConsumptionUIMessages.LABEL_WEBSERVICETYPE,
				ConsumptionUIMessages.TOOLTIP_PWPR_COMBO_TYPE,
				INFOPOP_WSWSCEN_COMBO_SERVICETYPE, SWT.SINGLE | SWT.BORDER
						| SWT.READ_ONLY);
		GridData gdata1 = (GridData) webserviceType_.getLayoutData();
		gdata1.horizontalSpan = 2;
		webserviceType_.setLayoutData(gdata1);
		
		webserviceType_.addSelectionListener(new SelectionListener(){
			public void widgetDefaultSelected(SelectionEvent e) {}
			
			public void widgetSelected(SelectionEvent e) {
				String oldTypeId = ids_.getTypeId();
				int currentSelectionIdx = webserviceType_.getSelectionIndex();
				String currentTypeId = labelIds_.getIds_()[currentSelectionIdx];
				if (!oldTypeId.equals(currentTypeId)) {					
					ids_.setTypeId(currentTypeId);
					
					// don't need to refresh runtime or validate fields if we are on the preference page, just return
					if (preferencesPage_)
						return;
						
					int oldScenario = WebServiceRuntimeExtensionUtils2.getScenarioFromTypeId(oldTypeId);
					int currentScenario = WebServiceRuntimeExtensionUtils2.getScenarioFromTypeId(currentTypeId);

			      objectSelectionWidget_ = getSelectionWidget();
					// change the label for the service
					// implementation/definition based on the web service type
					handleTypeChange();					

					// After bug 159911, we will not refresh the runtime in TOPDOWN scenario unless we absolutely
					// have to.  Therefore, if we are switching from another scenario type, we should check if the 
					// current selections are valid for this TOPDOWN scenario, if not, try to pick a more suitable 
					// runtime.
					if (currentScenario == WebServiceScenario.TOPDOWN) {
						validationState_ = ValidationUtils.VALIDATE_SERVER_RUNTIME_CHANGES;
						
						// this will force a refresh the next time the wsdl is changed
						forceRefreshRuntime = !checkErrorStatus().isOK();
					}
					
					//if the web service type change is from one top-down type to another
					//top-down type leave the object selection field in tact and refresh
					//the server/runtime project defaulting.
					//Otherwise clear the object selection field since it's value is not valid anymore
					if (oldScenario==WebServiceScenario.TOPDOWN && currentScenario==WebServiceScenario.TOPDOWN)						
					{
						// if switching from one TOPDOWN scenario to another TOPDOWN scenario and
						// we've determined that the current runtime selection is not suitable, we 
						// can refresh the runtime now (don't need to wait for the next time the
						// wsdl is changed).
						if (forceRefreshRuntime) {
							refreshServerRuntimeSelection();
							forceRefreshRuntime = false;
						}
					}
					else
					{
						//clear the object selection field
						// serviceImpl may be null if on the preferences page
						if (serviceImpl_ != null)
						{
							serviceImpl_.removeModifyListener(objectModifyListener_);
							serviceImpl_.setText("");
							setObjectSelection(null);
							serviceImpl_.addModifyListener(objectModifyListener_);
						}						   
					}	
					//restore widget values, serviceImpl may be null if on the preferences page
					if (serviceImpl_ != null) {
						String webServiceTypeID= null;
						   if (ids_ != null)
							   webServiceTypeID = ids_.getTypeId();
							serviceImpl_.removeModifyListener(objectModifyListener_);
							String currentlySelectedValue = serviceImpl_.getText();
							serviceImpl_.removeAll();
							if (currentlySelectedValue != null)
								serviceImpl_.setText(currentlySelectedValue);
							serviceImpl_.restoreWidgetHistory(webServiceTypeID);
							serviceImpl_.addModifyListener(objectModifyListener_);

					}

			   validationState_ = ValidationUtils.VALIDATE_ALL;
			   statusListener_.handleEvent(null);			   
					
			}
		  }
			
		});
		
		// Create text field and browse for object selection if not on preferences page
		if (!preferencesPage_)
		{
			//text of this label is based on the web service type selected in webserviceType_ combo
			serviceLabel_ = new Label( typeComposite, SWT.WRAP);
			serviceLabel_.setText(ConsumptionUIMessages.LABEL_WEBSERVICEIMPL);
			serviceLabel_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_TEXT_IMPL);

			serviceImpl_ = new ComboWithHistory(typeComposite, SWT.LEFT | SWT.BORDER, WSUIPlugin.getInstance().getDialogSettings());
			GridData griddata = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
			griddata.widthHint = 225;
			serviceImpl_.setLayoutData( griddata );
			serviceImpl_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_TEXT_IMPL);
			utils_.createInfoPop(serviceImpl_, INFOPOP_WSWSCEN_TEXT_SERVICE_IMPL);
			
			objectModifyListener_ = new ModifyListener(){
				public void modifyText(ModifyEvent e) {
				    if (serviceImpl_.getText().indexOf(':') > 0) {
				        timer_ = Timer.newInstance(timer_, Display.getCurrent(), ServerWizardWidget.this);
				        timer_.startTimer();
				    }
				    else
				        run();
				}
			};
			
			serviceImpl_.addModifyListener(objectModifyListener_);
			serviceImpl_.addSelectionListener(	new SelectionAdapter()
			{
					public void widgetSelected(SelectionEvent e) {
						int index = serviceImpl_.getSelectionIndex();
						serviceImpl_.removeModifyListener(objectModifyListener_);
				       	serviceImpl_.setText(serviceImpl_.getItem(index));
				        serviceImpl_.addModifyListener(objectModifyListener_);
				}
			});
			browseButton_ = utils_.createPushButton(typeComposite,
					ConsumptionUIMessages.BUTTON_BROWSE, ConsumptionUIMessages.TOOLTIP_WSWSCEN_BUTTON_BROWSE_IMPL, null);

			browseButton_.addSelectionListener(new ServiceImplBrowseListener());
		}
		// Service Lifecycle section - scales for service & client, graphic
		
		groupComposite_ = new Composite(parent, SWT.NONE);
		GridLayout gclayout = new GridLayout();
		gclayout.numColumns = 2;
		gclayout.horizontalSpacing=0;		
		gclayout.marginHeight=0;		
		gclayout.marginBottom=5;
		groupComposite_.setLayout( gclayout );
	    GridData gcGridData = new GridData(SWT.BEGINNING, SWT.BEGINNING, true, true);
	    groupComposite_.setLayoutData(gcGridData);		
	    
	    groupComposite_.addControlListener(new ControlListener()
		{
			public void controlMoved(ControlEvent e) {
				// TODO Auto-generated method stub
				
			}
			public void controlResized(ControlEvent e) {
				groupComposite_.pack(true);				
			}
		});
	    
		serviceComposite_ =  new Composite(groupComposite_, SWT.NONE);
		GridLayout gridlayout   = new GridLayout();
	    gridlayout.numColumns   = 2;
	    gridlayout.horizontalSpacing=0;
	    gridlayout.marginHeight=0;
	    serviceComposite_.setLayout( gridlayout );
	    GridData scGridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
	    serviceComposite_.setLayoutData(scGridData);    
	    
		serviceComposite_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_SERVICE);
	
		
		serviceScale_ = new Scale(serviceComposite_, SWT.VERTICAL | SWT.BORDER);
	    utils_.createInfoPop(serviceScale_, INFOPOP_WSWSCEN_SCALE_SERVICE);
		serviceScale_.setMinimum(0);
		serviceScale_.setMaximum(6);
		serviceScale_.setIncrement(1);
		serviceScale_.setPageIncrement(1);
		serviceScale_.addSelectionListener(scaleSelectionListener);
		serviceScale_.setSelection(getServiceGeneration());
		serviceScale_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_SERVICE);
		
		Accessible accessibleScale = serviceScale_.getAccessible();
		accessibleScale.addAccessibleListener(new AccessibleAdapter(){
			//	return a string that describes what to do with the slider
			//  this is read by the screen reader when the slider first gets focus
			public void getName(AccessibleEvent e) {
				e.result = ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_SERVICE;			
			}			
		});
		accessibleScale.addAccessibleControlListener(new AccessibleControlAdapter(){
			// return a meaningful string when the screen reader
			// attempts to get the value from the service scale
			public void getValue(AccessibleControlEvent e) {
				int selection = serviceScale_.getSelection();
				switch (selection) {
				case 0:
					e.result = ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_TEST;
					break;
				case 1:
					e.result = ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_RUN;
					break;
				case 2:
					e.result = ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_INSTALL;
					break;
				case 3:
					e.result = ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_DEPLOY;
					break;
				case 4:
					e.result = ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_ASSEMBLE;
					break;
				case 5:					
				case 6:
					e.result = ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_DEVELOP;
					break;
				default:
					break;
				}								
			}
		});	
		
		GridData layoutData1 = new GridData();
		layoutData1.horizontalAlignment=SWT.CENTER;
		layoutData1.verticalAlignment = SWT.BEGINNING;
		Rectangle scaleR = (imageReg_.get(ICON_SCALE_BG_0)).getBounds();
		layoutData1.heightHint=scaleR.height;
		layoutData1.widthHint=scaleR.width+1;
		serviceScale_.setLayoutData(layoutData1);		
		
		topologySpot_ = new Label(serviceComposite_, SWT.BORDER | SWT.TOP );
		topologySpot_.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
		topologySpot_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_SERVICE);
		
		GridData layoutData2 = new GridData();		
		layoutData2.horizontalAlignment=SWT.BEGINNING;				
		layoutData2.verticalAlignment = SWT.BEGINNING;
		Rectangle topR = (imageReg_.get(GRAPHIC_SERVICE_0)).getBounds();
		layoutData2.heightHint=topR.height;
		layoutData2.widthHint=topR.width;
		topologySpot_.setLayoutData(layoutData2);		
				
		setGraphics(getServiceGeneration());
		
		hCompService_ = utils_.createComposite(groupComposite_, 1);
		
		Label serviceDetailsLabel = new Label(hCompService_, SWT.NONE);
		serviceDetailsLabel.setText(ConsumptionUIMessages.LABEL_SUMMARY);
		
		hLinkServiceServer_= new Hyperlink(hCompService_, SWT.NULL);
		utils_.createInfoPop(hLinkServiceServer_, INFOPOP_WSWSCEN_HYPERLINK_SERVER);
		hLinkServiceServer_.setToolTipText(ConsumptionUIMessages.TOOLTIP_PWRS_TEXT_SERVER);
		hLinkServiceServer_.addHyperlinkListener(new IHyperlinkListener(){
			public void linkActivated(HyperlinkEvent e){				
				launchRuntimeSelectionDialog(false, true);				
			}
			public void linkEntered(HyperlinkEvent e){}
			public void linkExited(HyperlinkEvent e){}			
		});

		hLinkServiceRuntime_ = new Hyperlink(hCompService_, SWT.NULL);
		utils_.createInfoPop(hLinkServiceRuntime_, INFOPOP_WSWSCEN_HYPERLINK_RUNTIME);
		hLinkServiceRuntime_.setToolTipText(ConsumptionUIMessages.TOOLTIP_PWRS_TEXT_RUNTIME);
		hLinkServiceRuntime_.addHyperlinkListener(new IHyperlinkListener(){
			public void linkActivated(HyperlinkEvent e){
								launchRuntimeSelectionDialog(false);
			}
			public void linkEntered(HyperlinkEvent e){}
			public void linkExited(HyperlinkEvent e){}			
		});
		
		IWorkbench workbench = PlatformUI.getWorkbench();
		projectDialog_ = new ProjectSelectionDialog(workbench.getActiveWorkbenchWindow().getShell(), 
				new PageInfo(ConsumptionUIMessages.DIALOG_TITILE_SERVICE_PROJECT_SETTINGS, "", 
                        new WidgetContributorFactory()
  						{	
  							public WidgetContributor create()
  							{	  						 
  							   return new ProjectSelectionWidget();
  							}
  						}));
		
		hLinkServiceProject_= new Hyperlink(hCompService_, SWT.NULL);
		utils_.createInfoPop(hLinkServiceRuntime_, INFOPOP_WSWSCEN_HYPERLINK_PROJECTS);
		hLinkServiceProject_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_SERVICEPROJECT_LINK);
		hLinkServiceProject_.addHyperlinkListener(new IHyperlinkListener(){
			public void linkActivated(HyperlinkEvent e){
				launchProjectDialog();				
			}
			public void linkEntered(HyperlinkEvent e){}
			public void linkExited(HyperlinkEvent e){}			
		});
		
		hLinkServiceEAR_= new Hyperlink(hCompService_, SWT.NULL);
		utils_.createInfoPop(hLinkServiceRuntime_, INFOPOP_WSWSCEN_HYPERLINK_PROJECTS);
		hLinkServiceEAR_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_SERVICEPROJECT_LINK);
		hLinkServiceEAR_.addHyperlinkListener(new IHyperlinkListener(){
			public void linkActivated(HyperlinkEvent e){
				launchProjectDialog();			
			}
			public void linkEntered(HyperlinkEvent e){}
			public void linkExited(HyperlinkEvent e){}			
		});		

		hLinkServiceServer_.setText(SERVICE_SERVER_PREFIX); 
		hLinkServiceRuntime_.setText(SERVICE_RUNTIME_PREFIX);
		hLinkServiceProject_.setText(SERVICE_PROJECT_PREFIX);
		hLinkServiceEAR_.setText(SERVICE_EAR_PREFIX);
		
		HyperlinkGroup serverRuntimeGroup = new HyperlinkGroup(Display.getCurrent());
		
		serverRuntimeGroup.add(hLinkServiceServer_);
		serverRuntimeGroup.add(hLinkServiceRuntime_);
		serverRuntimeGroup.add(hLinkServiceProject_);
		serverRuntimeGroup.add(hLinkServiceEAR_);
		serverRuntimeGroup.setHyperlinkUnderlineMode(HyperlinkSettings.UNDERLINE_ALWAYS);
    
		utils_.createHorizontalSeparator(parent, 1);		
		
		// Add client widgets...
		clientWidget_ = new WebServiceClientTypeWidget(false);
	    clientWidget_.addControls(parent, statusListener );
	    clientWidget_.setPackable(this);
	    clientWidget_.enableClientSlider(serviceScale_.getSelection()<=ScenarioContext.WS_START);
		
		// Advanced buttons section
		utils_.createHorizontalSeparator(parent, 3);
		
		Composite advancedButtonPanel = utils_.createComposite(parent, 1);
		
		publishButton_ = utils_.createCheckbox(advancedButtonPanel,
				ConsumptionUIMessages.BUTTON_WSWSCEN_PUBLISH, ConsumptionUIMessages.TOOLTIP_PWPR_CHECKBOX_LAUNCH_WS, INFOPOP_WSWSCEN_CHECKBOX_LAUNCH_WS);		
		monitorButton_ = utils_.createCheckbox(advancedButtonPanel,
				ConsumptionUIMessages.CHECKBOX_MONITOR_WEBSERVICE, ConsumptionUIMessages.TOOLTIP_PWPR_CHECKBOX_MONITOR_SERVICE, INFOPOP_WSWSCEN_CHECKBOX_MONITOR_SERVICE);

		if (displayPreferences_ && getResourceContext().isOverwriteFilesEnabled()) {
			utils_.createHorizontalSeparator(parent, 1);			
			Composite prefButtonPanel = utils_.createComposite(parent, 1);
			overwriteButton_ = utils_.createCheckbox(prefButtonPanel,
					ConsumptionUIMessages.CHECKBOX_OVERWRITE_FILES, ConsumptionUIMessages.TOOLTIP_WSWSCEN_BUTTON_OVERWRITE_FILES, INFOPOP_WSWSCEN_CHECKBOX_OVERWRITE);
			overwriteButton_.setSelection(getResourceContext()
					.isOverwriteFilesEnabled());
			overwriteButton_.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					getResourceContext().setOverwriteFilesEnabled(overwriteButton_.getSelection());
				}
			});
		}

		return this;
	}	
	
	private void launchProjectDialog()
	{
		String currentProjectName = getServiceProjectName();
		String currentEarProjectName = getServiceEarProjectName();
		String currentProjectType = getServiceComponentType();
		boolean currentNeedEar = getServiceNeedEAR();
		
		projectDialog_.setProjectName(currentProjectName);
		projectDialog_.setEarProjectName(currentEarProjectName);
		projectDialog_.setProjectComponentType(currentProjectType);
		projectDialog_.setNeedEAR(currentNeedEar);
		
		int status = projectDialog_.open();
		if (status == Window.OK)
		{
			String newProjectName = projectDialog_.getProjectName();
			String newEarProjectName = projectDialog_.getEarProjectName();
			String newProjectType = projectDialog_.getProjectComponentType();
			boolean newNeedEar = projectDialog_.getNeedEAR();	
			
			//Update project settings and validate page if selections changed.
			if (!newProjectName.equals(currentProjectName)
					|| !newEarProjectName.equals(currentEarProjectName)
					|| !newProjectType.equals(currentProjectType)
					|| newNeedEar != currentNeedEar) {
				setServiceProjectName(newProjectName);
				setServiceEarProjectName(newEarProjectName);
				setServiceComponentType(newProjectType);
				setServiceNeedEAR(newNeedEar);				
				validationState_ = (new ValidationUtils()).getNewValidationState(validationState_, ValidationUtils.VALIDATE_PROJECT_CHANGES);
				statusListener_.handleEvent(null);
			}
			
			/*check to see if text has changed for project and EAR
			if so, repaint links */
			if (!newProjectName.equals(currentProjectName))
			{
				hLinkServiceProject_.pack(true);
				packSelf();	 
			}
			if (!newEarProjectName.equals(currentEarProjectName))
			{
				hLinkServiceEAR_.pack(true);
				packSelf();	  					
			}
		}
	}
		
	private void launchRuntimeSelectionDialog(boolean clientContext)
	{
		launchRuntimeSelectionDialog(clientContext, false);
	}
		
	private void launchRuntimeSelectionDialog(boolean clientContext, boolean selectServerFirst) 	
	{	
		byte mode = clientContext ? (byte)1 : (byte)0;
		
		//TODO: jvh - investigate - don't think j2ee version shouldn't be hard coded (last parm) 
		//  question - where to pick it up from?
		//Remember the current values
		TypeRuntimeServer currentServiceTRS = getServiceTypeRuntimeServer();
		IWorkbench workbench = PlatformUI.getWorkbench();
		RuntimeServerSelectionDialog rssd = new RuntimeServerSelectionDialog(
				workbench.getActiveWorkbenchWindow().getShell(), mode, currentServiceTRS, "14");	
		rssd.setSelectServerFirst(selectServerFirst);		
		int result = rssd.open();		
		if (result == Window.OK)
		{
			TypeRuntimeServer newServiceTRS = rssd.getTypeRuntimeServer();
			if (!currentServiceTRS.equals(newServiceTRS))
			{
				setServiceTypeRuntimeServer(newServiceTRS);	
				refreshClientServerRuntimeSelection();	
				validationState_ = (new ValidationUtils()).getNewValidationState(validationState_, ValidationUtils.VALIDATE_SERVER_RUNTIME_CHANGES);
				clientWidget_.setValidationState(ValidationUtils.VALIDATE_SERVER_RUNTIME_CHANGES);
				statusListener_.handleEvent(null); //Revalidate the page since server/runtime selections changed.
			}
			
		}		
	}	
	
	public void setClientTypeRuntimeServer(TypeRuntimeServer ids) {
		clientWidget_.setTypeRuntimeServer( ids );
	}

	public TypeRuntimeServer getClientTypeRuntimeServer() {
		return clientWidget_.getTypeRuntimeServer();
	}

	public void setInstallClient(Boolean install) {
		clientWidget_.setInstallClient( install );
	}

	public Boolean getInstallClient() {		
		return clientWidget_.getInstallClient();
	}
	
	public void setStartClient(Boolean startClient) {
		clientWidget_.setStartClient( startClient );
	}

	public Boolean getStartClient() {		
		return clientWidget_.getStartClient();
	}
	
	public void setTestClient(Boolean testClient) {
		clientWidget_.setTestClient( testClient );
	}

	public Boolean getTestClient() {		
		return clientWidget_.getTestClient();
	}
	
	public void setDevelopClient(boolean develop) {
		clientWidget_.setDevelopClient( develop );
	}

	public boolean getDevelopClient() {		
		return clientWidget_.getDevelopClient();
	}
	
	public void setAssembleClient(boolean assemble) {
		clientWidget_.setAssembleClient( assemble );
	}

	public boolean getAssembleClient() {		
		return clientWidget_.getAssembleClient();
	}
	
	public void setDeployClient(boolean deploy) {
		clientWidget_.setDeployClient( deploy );
	}

	public boolean getDeployClient() {		
		return clientWidget_.getDeployClient();
	}

private void handleTypeChange()
	{
		if (!preferencesPage_) {
		   int scenario = getWebServiceScenario();
		   
		   if (scenario == WebServiceScenario.BOTTOMUP)
		   {
			  serviceLabel_.setText(ConsumptionUIMessages.LABEL_WEBSERVICEIMPL);
		   }
		   else if (scenario == WebServiceScenario.TOPDOWN)
		   {
			   serviceLabel_.setText(ConsumptionUIMessages.LABEL_WEBSERVICEDEF);
		   }
		}
	}

	public void setServiceTypeRuntimeServer(TypeRuntimeServer ids) {
		LabelsAndIds labelIds = WebServiceRuntimeExtensionUtils2
				.getServiceTypeLabels();
		// rskreg
		int selection = 0;
		String[] serviceIds = labelIds.getIds_();
		String selectedId = ids.getTypeId();

		webserviceType_.setItems(labelIds.getLabels_());

		// Now find the selected one.
		for (int index = 0; index < serviceIds.length; index++) {
			if (selectedId.equals(serviceIds[index])) {
				selection = index;
				break;
			}
		}
		webserviceType_.select(selection);
		
		ids_ = ids;
		
		if (ids_ != null)
		{
			String serviceServerText = "";
			String serverId = ids_.getServerId();
			if (serverId != null && serverId.length()>0)
			{
			  serviceServerText = WebServiceRuntimeExtensionUtils2.getServerLabelById(serverId);
			}
			String serviceRuntimeText = WebServiceRuntimeExtensionUtils2.getRuntimeLabelById(ids_.getRuntimeId());
			
			String currentServerText = hLinkServiceServer_.getText();
			String currentRuntimeText = hLinkServiceRuntime_.getText();
			String newServerText = SERVICE_SERVER_PREFIX + " " + serviceServerText;
			String newRuntimeText = SERVICE_RUNTIME_PREFIX + " " + serviceRuntimeText;
			hLinkServiceServer_.setText(newServerText);
			hLinkServiceRuntime_.setText(newRuntimeText);		
			
			/*check to see if text has changed for server or runtime
			if so, repaint links */
			if (!newServerText.equals(currentServerText))
			{
				hLinkServiceServer_.pack(true);
				packSelf();
			}			
			
			if (!newRuntimeText.equals(currentRuntimeText))
			{
				hLinkServiceRuntime_.pack(true);
				packSelf();
			} 
		}				
		labelIds_ = labelIds;
		handleTypeChange();
		
		if (projectDialog_ != null)
			projectDialog_.setTypeRuntimeServer(ids_);
		
		
		//When the server changes, the state of needEar could change.
		//If the the server change results in a change in the state of needEar,
		//update needEar and serviceEarProjectName.
		ValidationUtils vu = new ValidationUtils();
		boolean oldNeedEar = getServiceNeedEAR();
		boolean serviceProjectOrProjectTypeNeedsEar;

		if (!oldNeedEar)
		{
			//If an EAR was not needed previously it could have been because of the project/project type or the server.
			//If it was because of the project/project type, changing the server should have no impact
			//on the state of needEar.
			serviceProjectOrProjectTypeNeedsEar = vu.projectOrProjectTypeNeedsEar(getServiceProjectName(), getServiceComponentType());
		}
		else
		{
			serviceProjectOrProjectTypeNeedsEar = true;
		}
		
		//boolean serviceProjectOrProjectTypeNeedsEar = vu.projectOrProjectTypeNeedsEar(getServiceProjectName(), getServiceComponentType());
		if (serviceProjectOrProjectTypeNeedsEar)
		{
			//Could not rule out need for an Ear from the project/project type so changing the server
			//may impact the need for an Ear.

			boolean currentServiceServerNeedsEar = vu.serverNeedsEAR(getServiceTypeRuntimeServer().getServerId());
			if (oldNeedEar != currentServiceServerNeedsEar)
			{
				//Update needEar and serviceEarProjectName.
				if (currentServiceServerNeedsEar)
				{
					//Calculate a reasonable default for the Ear project name
					String earProjectName = DefaultingUtils.getDefaultEARProjectName(getServiceProjectName());
					setServiceNeedEAR(currentServiceServerNeedsEar);
					setServiceEarProjectName(earProjectName);
				}
				else
				{
					setServiceNeedEAR(currentServiceServerNeedsEar);
					setServiceEarProjectName("");					
				}
				
			}
		}		
	}

	public TypeRuntimeServer getServiceTypeRuntimeServer() {
		return ids_;
	}

	public void setServiceGeneration(int value)
	{
		serviceScale_.setSelection(value);
		setGraphics(value);
		
		//enable client widget based on service scale setting
		clientWidget_.enableClientSlider(value<=ScenarioContext.WS_START);
		
		/*for popup case need to make sure that the UI is refreshed based on 
		changes to data*/
		packSelf();
	}	

	public int getServiceGeneration()
	{
		return serviceScale_.getSelection();
	}
	
	public boolean getDevelopService() {
		return developService_;
	}

	public void setDevelopService(boolean developService) {
		this.developService_ = developService;
	}	
	
	public boolean getAssembleService() {
		return assembleService_;
	}

	public void setAssembleService(boolean assembleService) {
		this.assembleService_ = assembleService;
	}

	public boolean getDeployService() {
		return deployService_;
	}

	public void setDeployService(boolean deployService) {
		this.deployService_ = deployService;
	}
	
	public Boolean getStartService(){
		return startService_;
	}
	
	public void setStartService(Boolean value) {
        startService_=value;
	}

	public Boolean getInstallService() {
		return installService_;
	}

	public void setInstallService(Boolean value) {
        installService_=value;
	}

	public Boolean getTestService() {
        return 
        new Boolean( testService_.booleanValue() || clientWidget_.getTestClient().booleanValue());
	}

	public void setTestService(Boolean value) {
        testService_= value;
	}
	public Boolean getMonitorService() {
		return new Boolean(monitorButton_.getSelection());
	}

	public void setMonitorService(Boolean value) {
		monitorButton_.setSelection(value.booleanValue());
	}

	public Boolean getPublishService() {		
		return new Boolean(publishButton_.getSelection());
	}

	public void setPublishService(Boolean value) {
		publishButton_.setSelection( value.booleanValue() );
	}

	public Boolean getGenerateProxy() {
		return new Boolean(clientWidget_.getGenerateProxy());		
	}

	public void setClientGeneration(int value)
	{
		clientWidget_.setClientGeneration(value);
		/*for popup case need to make sure that the UI is refreshed based on 
			changes to data*/
		packSelf();
	}
	
	public String getClientEarProjectName()
	{
		return clientWidget_.getClientEarProjectName();
	}
	
	public String getClientProjectName()
	{
		return clientWidget_.getClientProjectName();
	}
	
	public int getClientGeneration()
	{
		return clientWidget_.getClientGeneration();
	}	

	public ResourceContext getResourceContext() {
		if (resourceContext_ == null) {
			resourceContext_ = WebServicePlugin.getInstance()
					.getResourceContext();
		}
		return resourceContext_;
	}

	public void setResourceContext(ResourceContext context) {
		resourceContext_ = context;
	}

	public IStructuredSelection getObjectSelection()
	{
		return objectSelection_;		
	}
	
	public void setObjectSelection(IStructuredSelection selection )
	{
		objectSelection_ = selection;
	}
	
	public WebServicesParser getWebServicesParser()
	{
		return parser_;
	}
	
	public void setWebServicesParser(WebServicesParser parser)
	{
		parser_ = parser;
		clientWidget_.setWebServicesParser(parser);
	}
	public void externalize() {
		super.externalize();
		if (!preferencesPage_) {
			   String webServiceTypeID= null;
			   if (ids_ != null)
				   webServiceTypeID = ids_.getTypeId();
			   serviceImpl_.storeWidgetHistory(webServiceTypeID);
			}
	}
	
	public void internalize() {		
		
		if (preferencesPage_)
			return;
		
		if (objectSelectionWidget_ == null)
			objectSelectionWidget_ = getSelectionWidget();
		
		String displayable = null;
		
		if (objectSelectionWidget_ instanceof IObjectSelectionLaunchable) {		
			IObjectSelectionLaunchable launchable = (IObjectSelectionLaunchable) objectSelectionWidget_;
			launchable.setInitialSelection(objectSelection_);
			objectSelection_ = launchable.getObjectSelection();
			displayable = launchable.getObjectSelectionDisplayableString();
		}
		else {
			IObjectSelectionWidget selectionWidget = (IObjectSelectionWidget) objectSelectionWidget_;
			selectionWidget.setInitialSelection(objectSelection_);
		    displayable = selectionWidget.getObjectSelectionDisplayableString();
		}

		serviceImpl_.removeModifyListener(objectModifyListener_);
		if (displayable != null && displayable.length() != 0)
			serviceImpl_.setText(displayable);
		String webServiceTypeID = null;
		if (ids_ != null)
			webServiceTypeID = ids_.getTypeId();
		serviceImpl_.restoreWidgetHistory(webServiceTypeID);
		serviceImpl_.addModifyListener(objectModifyListener_);

			
	}

	public IStatus getStatus() {
		IStatus status = Status.OK_STATUS;

		IStatus missingFieldStatus = checkMissingFieldStatus();
		if (missingFieldStatus.getSeverity() == IStatus.ERROR) {
			return missingFieldStatus;
		}

		IStatus serviceImplValidationStatus = checkServiceImplTextStatus();
		if (serviceImplValidationStatus.getSeverity() == IStatus.ERROR) {
			return serviceImplValidationStatus;
		}
		else if (serviceImplValidationStatus.getSeverity() == IStatus.WARNING){
			return serviceImplValidationStatus;
		}

		IStatus possibleErrorStatus = checkErrorStatus();
		if (possibleErrorStatus.getSeverity() == IStatus.ERROR || possibleErrorStatus.getSeverity() == IStatus.WARNING) {
			return possibleErrorStatus;
		}

		IStatus possibleWarningStatus = checkWarningStatus();
		if (possibleWarningStatus.getSeverity() == IStatus.WARNING) {
			return possibleWarningStatus;
		}

		// If no warnings/errors were reported, clear validation state on
		// service side and client side (if enabled)
		validationState_ = ValidationUtils.VALIDATE_NONE;
		if (clientWidget_.getGenerateProxy()) {
			clientWidget_.setValidationState(ValidationUtils.VALIDATE_NONE);
		}

		return status;
	}
	
	/*
	 * call validation code in the object selection widget to ensure any
	 * modifications to the serviceImpl_ field are valid
	 */
	private IStatus checkServiceImplTextStatus() {
		
		String fieldText = serviceImpl_.getText().trim();

		if (objectSelectionWidget_ == null)
		{
			objectSelectionWidget_ = getSelectionWidget();
		}
		
		IObjectSelectionLaunchable launchable = null;
		if (objectSelectionWidget_ instanceof IObjectSelectionLaunchable)
		    {      	
				launchable = (IObjectSelectionLaunchable)objectSelectionWidget_;
				validObjectSelection_ = launchable.validate(fieldText);
			}
			else 
			{
				IObjectSelectionWidget widget = (IObjectSelectionWidget)objectSelectionWidget_;
				validObjectSelection_ = widget.validate(fieldText);
			}
		
		if (!validObjectSelection_)
		{
			int scenario = getWebServiceScenario();
			
			if (scenario == WebServiceScenario.BOTTOMUP){
				if (launchable != null){
					IStatus valStatus = launchable.validateSelection(new StructuredSelection(fieldText));
					if (valStatus.getSeverity() == IStatus.WARNING)
						return StatusUtils.warningStatus(ConsumptionUIMessages.MSG_WARN_SERVICE_IMPL_NAMING_CONVENTION);
				}
				else
					return StatusUtils.errorStatus(ConsumptionUIMessages.MSG_INVALID_SERVICE_IMPL);
			}
			else
				return StatusUtils.errorStatus(ConsumptionUIMessages.MSG_INVALID_SERVICE_DEF);			
		}		
		
		return Status.OK_STATUS;
	}

	private int getWebServiceScenario()
	{
		   int index = webserviceType_.getSelectionIndex();	
		   String typeId = labelIds_.getIds_()[index];
		   return WebServiceRuntimeExtensionUtils2.getScenarioFromTypeId(typeId);		
	}
	
	private IStatus checkMissingFieldStatus() {

		// 1. Check for missing fields on service side
		ValidationUtils valUtils = new ValidationUtils();
		String serviceImpl = serviceImpl_.getText().trim();
		String typeId = getServiceTypeRuntimeServer().getTypeId();
		String runtimeId = getServiceTypeRuntimeServer().getRuntimeId();
		String serverId = getServiceTypeRuntimeServer().getServerId();
		String projectName = getServiceProjectName();
		boolean needEar = getServiceNeedEAR();
		String earProjectName = getServiceEarProjectName();
		String projectTypeId = getServiceComponentType();
		
		IStatus serviceMissingFieldStatus = valUtils.checkMissingFieldStatus(validationState_, typeId, serviceImpl,
				runtimeId, serverId, projectName, needEar, earProjectName, projectTypeId, false);
		if (serviceMissingFieldStatus.getSeverity() == IStatus.ERROR) {
			return serviceMissingFieldStatus;
		}

		// 2. Check for missing fields on the client side if it's visible.
		if (clientWidget_.getGenerateProxy()) {
			IStatus clientMissingFieldsStatus = clientWidget_.checkMissingFieldStatus();
			if (clientMissingFieldsStatus.getSeverity() == IStatus.ERROR) {
				return clientMissingFieldsStatus;
			}

		}

		return Status.OK_STATUS;
	}

	private IStatus checkErrorStatus() {

		ValidationUtils valUtils = new ValidationUtils();

		// 1. Check for errors on service side
		String projectName = getServiceProjectName();
		boolean needEar = getServiceNeedEAR();
		String earProjectName = getServiceEarProjectName();
		String projectTypeId = getServiceComponentType();
		String initialProjectName = "";
		if (initialProject_ != null) {
			initialProjectName = initialProject_.getName();
		} 
		IStatus serviceSideErrorStatus = valUtils.checkErrorStatus(validationState_, getServiceTypeRuntimeServer(), projectName, initialProjectName, needEar, earProjectName, projectTypeId, false);
		if (serviceSideErrorStatus.getSeverity() == IStatus.ERROR) {
			return serviceSideErrorStatus;
		}

		// 2. Check for errors on client side if it is visible
		if (clientWidget_.getGenerateProxy()) {
			IStatus clientSideErrorStatus = clientWidget_.checkErrorStatus();
			if (clientSideErrorStatus.getSeverity() == IStatus.ERROR) {
				return clientSideErrorStatus;
			}

			// 3. Check for errors that span service and client if client side
			// is visible.
			int clientValidationState = clientWidget_.getValidationState();
			if (validationState_ == ValidationUtils.VALIDATE_ALL
					|| validationState_ == ValidationUtils.VALIDATE_PROJECT_CHANGES
					|| clientValidationState == ValidationUtils.VALIDATE_ALL
					|| clientValidationState == ValidationUtils.VALIDATE_PROJECT_CHANGES) {
				IWebServiceRuntimeChecker runtimeChecker = null;

				String serviceRuntimeId = WebServiceRuntimeExtensionUtils2.getServiceRuntimeId(getServiceTypeRuntimeServer(), projectName, projectTypeId);	    		
				runtimeChecker = WebServiceRuntimeExtensionUtils2.getServiceRuntimeChecker(serviceRuntimeId);

				if (runtimeChecker != null) {
					return runtimeChecker.checkServiceClientCompatibility(
							getServiceNeedEAR(), getServiceEarProjectName(), getServiceProjectName(), 
							clientWidget_.getClientNeedEAR(), clientWidget_.getClientEarProjectName(), 
							clientWidget_.getClientProjectName());
				}
			}
		}

		return Status.OK_STATUS;
	}

	private IStatus checkWarningStatus() {
		ValidationUtils valUtils = new ValidationUtils();
		// 1. Check for warnings on the service side
		int scaleSetting = getServiceGeneration();
		String serverId = getServiceTypeRuntimeServer().getServerId();
		IStatus serviceWarningStatus = valUtils.checkWarningStatus(validationState_, scaleSetting, serverId, getServiceTypeRuntimeServer().getServerInstanceId(), false, getServiceProjectName(), initialProject_, getServiceTypeRuntimeServer().getTypeId());
		if (serviceWarningStatus.getSeverity() == IStatus.WARNING) {
			return serviceWarningStatus;
		}

		// 2. Check for warnings on the client side if it's enabled
		if (clientWidget_.getGenerateProxy()) {
			IStatus clientWarningStatus = clientWidget_.checkWarningStatus();
			if (clientWarningStatus.getSeverity() == IStatus.WARNING) {
				return clientWarningStatus;
			}

		}

		return Status.OK_STATUS;
	}
		
	protected void initImageRegistry()
	{
		imageReg_ = new ImageRegistry(Display.getCurrent());
		
		imageReg_.put(ICON_SCALE_BG_0, WebServiceConsumptionUIPlugin
				.getImageDescriptor(ICON_SCALE_BG_0));
		imageReg_.put(ICON_SCALE_BG_1, WebServiceConsumptionUIPlugin
				.getImageDescriptor(ICON_SCALE_BG_1));
		imageReg_.put(ICON_SCALE_BG_2, WebServiceConsumptionUIPlugin
				.getImageDescriptor(ICON_SCALE_BG_2));
		imageReg_.put(ICON_SCALE_BG_3, WebServiceConsumptionUIPlugin
				.getImageDescriptor(ICON_SCALE_BG_3));
		imageReg_.put(ICON_SCALE_BG_4, WebServiceConsumptionUIPlugin
				.getImageDescriptor(ICON_SCALE_BG_4));
		imageReg_.put(ICON_SCALE_BG_5, WebServiceConsumptionUIPlugin
				.getImageDescriptor(ICON_SCALE_BG_5));
		imageReg_.put(ICON_SCALE_BG_6, WebServiceConsumptionUIPlugin
				.getImageDescriptor(ICON_SCALE_BG_6));
		
		imageReg_.put(GRAPHIC_SERVICE_0, WebServiceCreationUIPlugin
				.getImageDescriptor(GRAPHIC_SERVICE_0));
		imageReg_.put(GRAPHIC_SERVICE_1, WebServiceCreationUIPlugin
				.getImageDescriptor(GRAPHIC_SERVICE_1));
		imageReg_.put(GRAPHIC_SERVICE_2, WebServiceCreationUIPlugin
				.getImageDescriptor(GRAPHIC_SERVICE_2));
		imageReg_.put(GRAPHIC_SERVICE_3, WebServiceCreationUIPlugin
				.getImageDescriptor(GRAPHIC_SERVICE_3));
		imageReg_.put(GRAPHIC_SERVICE_4, WebServiceCreationUIPlugin
				.getImageDescriptor(GRAPHIC_SERVICE_4));
		imageReg_.put(GRAPHIC_SERVICE_5, WebServiceCreationUIPlugin
				.getImageDescriptor(GRAPHIC_SERVICE_5));
	}
	
	private void setAdvancedOptions(boolean enabled)
	{
		monitorButton_.setEnabled(enabled); 
		publishButton_.setEnabled(enabled);		
	}
	
	public void setServiceProjectName(String name)
	  {
		serviceProjectName_= name;
		hLinkServiceProject_.setText(SERVICE_PROJECT_PREFIX + " " + serviceProjectName_);
		hLinkServiceProject_.pack(true);
		packSelf();	
	  }
	
	public void setInitialProject(IProject project)
	{
		initialProject_ = project;
	}
	
	 public void setServiceEarProjectName(String name)
	  {	  
		 serviceEarProjectName_ = name;
		 refreshEARLink();
	  }
	 
	  public void refreshEARLink()
	  {
		  hLinkServiceEAR_.setVisible(needEar_); 
		  if (needEar_)
		  {			 
			  hLinkServiceEAR_.setText(SERVICE_EAR_PREFIX + " " + serviceEarProjectName_);
			  hLinkServiceEAR_.pack(true);
			  packSelf();
		  }
	  }
	 public void setServiceComponentType( String type )
	  {
		 serviceComponentType_ = type;
	  }
	 
	  public void setClientProjectName(String name)
	  {
	    clientWidget_.setClientProjectName(name);  
	  }  
	  
	  public void setClientEarProjectName(String name)
	  {
	    clientWidget_.setClientEarProjectName(name);  
	  }
	  
	  IProject project_;
	  
	  public String getServiceComponentType()
	  {
		  return serviceComponentType_;
	  }
	  
	  public void setClientComponentType(String type)
	  {
		  clientWidget_.setClientComponentType(type);
	  }
	  
	  public String getClientComponentType()
	  {
		  return clientWidget_.getClientComponentType();
	  }
	 
	  public String getServiceProjectName()
	  {
		  return serviceProjectName_;
	  }
	  
	  public String getServiceEarProjectName()
	  {
		  return serviceEarProjectName_;
	  }
	  
	  public void setClientProject(IProject project)
	  {
		  clientWidget_.setProject(project);
	  }
	  
	  private IProject getClientProject()
	  {
		  return clientWidget_.getProject(); 
	  }
	  
	  public void setProject(IProject project)
	  {
		  project_ = project;
	  }	  
	  	  
	  public IProject getProject()
	  {
		  return project_;
	  }
	  
	  public String getServiceRuntimeId()
	  {
		  // calculate the most appropriate serviceRuntimeId based on current settings.
		  return WebServiceRuntimeExtensionUtils2.getServiceRuntimeId(getServiceTypeRuntimeServer(), getServiceProjectName(), getServiceComponentType());    
	  }
	  
	  public String getClientRuntimeId()
	  {
		  return clientWidget_.getClientRuntimeId();
	  }
	  
	  public void setServiceNeedEAR(boolean b)
	  {
		  needEar_ = b;
		  refreshEARLink();
	  }
	  
	  public boolean getServiceNeedEAR()
	  {
		  return needEar_;
	  }
	  
	  public void setClientNeedEAR(boolean b)
	  {
	    clientWidget_.setClientNeedEAR(b);
	  }	  
	  
	  public boolean getClientNeedEAR()
	  {
		  return clientWidget_.getClientNeedEAR();
	  }
	  
	  // looks through extensions and returns the appropriate selection widget
	  private Object getSelectionWidget()
	  {
			String         wst      = getServiceTypeRuntimeServer().getTypeId();
			int            scenario = WebServiceRuntimeExtensionUtils2.getScenarioFromTypeId(wst);
			String         implId   = WebServiceRuntimeExtensionUtils2.getWebServiceImplIdFromTypeId(wst);
		  WebServiceImpl wsimpl   = WebServiceRuntimeExtensionUtils2.getWebServiceImplById(implId);
      Object         result   = null;
        
		    
		  if (wsimpl != null)
		  {
		    String objectSelectionWidgetId = null;
		    if (scenario == WebServiceScenario.TOPDOWN)
		    {
		      objectSelectionWidgetId = "org.eclipse.jst.ws.internal.consumption.ui.widgets.object.WSDLSelectionWidget";
		    }
		    else
		    {
		      objectSelectionWidgetId = wsimpl.getObjectSelectionWidget();
		    }
        
        ObjectSelectionRegistry registry = ObjectSelectionRegistry.getInstance();
        boolean editable = registry.getExternalModify( objectSelectionWidgetId );
                
        serviceImpl_.setEnabled( editable );
        result = registry.getSelectionWidget( objectSelectionWidgetId );
      }
      
		  return result;
	  }
	 
	// for the purposes of disabling the service implementation controls from the preferences dialog
	public void disableNonPreferenceWidgets()
	{
		if (serviceImpl_ != null)
			serviceImpl_.setEnabled(false);
		if (browseButton_ != null)
			browseButton_.setEnabled(false);
		if (hCompService_ != null)
		{
			hCompService_.setVisible(false);			
		}
		clientWidget_.disableNonPreferenceWidgets();
	}
	
	private void setGraphics(int value)
	{
		String iconImage = "";
		String toplogyImage = "";
		switch (value) {
		case 0:
			iconImage=ICON_SCALE_BG_0;
			toplogyImage=GRAPHIC_SERVICE_0;
			break;
		case 1:
			iconImage=ICON_SCALE_BG_1;
			toplogyImage=GRAPHIC_SERVICE_1;
			break;
		case 2:
			iconImage=ICON_SCALE_BG_2;
			toplogyImage=GRAPHIC_SERVICE_2;
			break;
		case 3:
			iconImage=ICON_SCALE_BG_3;
			toplogyImage=GRAPHIC_SERVICE_3;
			break;
		case 4:
			iconImage=ICON_SCALE_BG_4;
			toplogyImage=GRAPHIC_SERVICE_4;
			break;
		case 5:					
		case 6:
			iconImage=ICON_SCALE_BG_5;
			toplogyImage=GRAPHIC_SERVICE_5;
			break;
		default:
			break;
		}
		serviceScale_.setBackgroundImage(imageReg_.get(iconImage));
		topologySpot_.setImage(imageReg_.get(toplogyImage));
	}
	
	private void refreshServerRuntimeSelection()
	{		
		//new up ServerRuntimeSelectionWidgetDefaultingCommand
		ServerRuntimeSelectionWidgetDefaultingCommand serverRTDefaultCmd = new ServerRuntimeSelectionWidgetDefaultingCommand();
		
		  //call setters of new defaulting command:
	      serverRTDefaultCmd.setInitialSelection(getObjectSelection());
	      serverRTDefaultCmd.setInitialProject(getProject());
	      serverRTDefaultCmd.setGenerateProxy(clientWidget_.getGenerateProxy());
	      serverRTDefaultCmd.setServiceTypeRuntimeServer(getServiceTypeRuntimeServer());
		  serverRTDefaultCmd.setWebServicesParser(getWebServicesParser());     
		  serverRTDefaultCmd.setClientInitialSelection(getObjectSelection());
	      serverRTDefaultCmd.setClientInitialProject(getClientProject());
	      serverRTDefaultCmd.setClientEarProjectName(clientWidget_.getClientEarProjectName());
		  serverRTDefaultCmd.setClientTypeRuntimeServer(getClientTypeRuntimeServer());
		  		  
		  serverRTDefaultCmd.execute(null, null);
		  
		  //perform mappings from the defaulting command to the project settings...	
		  setServiceProjectName(serverRTDefaultCmd.getServiceProjectName());
		  setServiceEarProjectName(serverRTDefaultCmd.getServiceEarProjectName());
		  setServiceComponentType(serverRTDefaultCmd.getServiceComponentType());
		  setClientProjectName(serverRTDefaultCmd.getClientProjectName());
		  setClientEarProjectName(serverRTDefaultCmd.getClientEarProjectName());
		  setServiceTypeRuntimeServer(serverRTDefaultCmd.getServiceTypeRuntimeServer());
          setClientTypeRuntimeServer(serverRTDefaultCmd.getClientTypeRuntimeServer());
          setServiceNeedEAR(serverRTDefaultCmd.getServiceNeedEAR());
          setClientNeedEAR(serverRTDefaultCmd.getClientNeedEAR());
          setClientComponentType(serverRTDefaultCmd.getClientComponentType());
	}
	
	/**
	 *  Update client server and runtime based on service side
	 */
	private void refreshClientServerRuntimeSelection()
	{	
		TypeRuntimeServer clientTypeRuntimeserver = getClientTypeRuntimeServer();
		clientTypeRuntimeserver.setRuntimeId(getServiceTypeRuntimeServer().getRuntimeId());
		clientTypeRuntimeserver.setServerId(getServiceTypeRuntimeServer().getServerId());
		clientTypeRuntimeserver.setServerInstanceId(getServiceTypeRuntimeServer().getServerInstanceId());
		setClientTypeRuntimeServer(clientTypeRuntimeserver);
	}	
		
	
	private void callObjectTransformation(IStructuredSelection objectSelection,
			IProject project, String componentName, boolean refreshRuntime)
	{
		ObjectSelectionOutputCommand objOutputCommand = new ObjectSelectionOutputCommand();
		   objOutputCommand.setTypeRuntimeServer(getServiceTypeRuntimeServer());
		   objOutputCommand.setObjectSelection(objectSelection);
	       objOutputCommand.setProject(project);
	       objOutputCommand.setComponentName(componentName);			   
	       
	       objOutputCommand.execute(null, null);
        
	       setWebServicesParser(objOutputCommand.getWebServicesParser());
	       setObjectSelection(objOutputCommand.getObjectSelection());
	       setProject(objOutputCommand.getProject());      		       
	       
	       if (refreshRuntime || forceRefreshRuntime)
	    	   refreshServerRuntimeSelection();  
	       
	       forceRefreshRuntime = false;
	}
	
	private class ScaleSelectionListener implements SelectionListener
	{
		public void widgetSelected(SelectionEvent e) {			
			    
			    Scale scale = (Scale)e.widget;
				int selection = scale.getSelection();
				
				//TODO: change the hard coded integers here to the the ScenarioContext.WS_xxx when in less critical phase
				switch (selection) {
				case 0:
					serviceScale_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_TEST);
					break;
				case 1:
					serviceScale_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_RUN);
					break;
				case 2:
					serviceScale_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_INSTALL);
					break;
				case 3:
					serviceScale_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_DEPLOY);
					break;
				case 4:
					serviceScale_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_ASSEMBLE);
					break;
				case 5:					
				case 6:
					serviceScale_.setSelection(ScenarioContext.WS_DEVELOP); //"no selection" is not allowed...must develop service @ minimum
					serviceScale_.setToolTipText(ConsumptionUIMessages.TOOLTIP_WSWSCEN_SCALE_DEVELOP);
					//reset local selection so that setters get correct value below
					selection = ScenarioContext.WS_DEVELOP;
					break;
				default:
					break;
				}
				
				setDevelopService(selection <= ScenarioContext.WS_DEVELOP);
				setAssembleService(selection <= ScenarioContext.WS_ASSEMBLE);
				setDeployService(selection <= ScenarioContext.WS_DEPLOY);
				
				setTestService(new Boolean(selection <= ScenarioContext.WS_TEST));
				setInstallService(new Boolean(selection <= ScenarioContext.WS_INSTALL));
				setStartService(new Boolean(selection <= ScenarioContext.WS_START));
				setAdvancedOptions(selection <= ScenarioContext.WS_INSTALL);
				clientWidget_.enableClientSlider(selection <= ScenarioContext.WS_START);
				
				setGraphics(selection);
				
				//Validate the page
				validationState_ = (new ValidationUtils()).getNewValidationState(validationState_, ValidationUtils.VALIDATE_SCALE_CHANGES);
				statusListener_.handleEvent(null);
				
			}		

		public void widgetDefaultSelected(SelectionEvent e) {
			widgetSelected(e);
		}
	}
	
	private class ServiceImplBrowseListener implements SelectionListener
	{
		public void widgetDefaultSelected(SelectionEvent e) {
			// TODO Auto-generated method stub			
		}
		
		public void widgetSelected(SelectionEvent e) {     
			   
			  if (objectSelectionWidget_ == null)
				   objectSelectionWidget_ = getSelectionWidget();
			  
			   IStructuredSelection objectSelection = null;
			   IProject project = null;
			   String componentName="";
			   int result=Dialog.CANCEL;
			   
			   // This should be the Web Service Wizard Dialog's shell, and should be non-null.
			   Shell shell = Display.getCurrent().getActiveShell();
			   
			   if (objectSelectionWidget_ instanceof IObjectSelectionLaunchable)
		       {      	
				 IObjectSelectionLaunchable launchable = ((IObjectSelectionLaunchable)objectSelectionWidget_);
				 launchable.setInitialSelection(getObjectSelection());

				 // Bug 269097 - Use the Web Service's dialog shell, not the platform workbench's shell
		         result = launchable.launch(shell);
		         if (result == Dialog.OK)
		         {
		        	 serviceImpl_.removeModifyListener(objectModifyListener_);
			         serviceImpl_.setText(launchable.getObjectSelectionDisplayableString());
			         serviceImpl_.addModifyListener(objectModifyListener_);
			         objectSelection = launchable.getObjectSelection();
			         project = launchable.getProject();
			         componentName= launchable.getComponentName();
		         }
		       }
			   else
			   {
					// bug 269097 -  - Use the Web Service's dialog shell, not the platform workbench's shell.
					browseDialog_ = new ServiceImplSelectionDialog(shell, 
							new PageInfo(ConsumptionUIMessages.DIALOG_TITILE_SERVICE_IMPL_SELECTION, "", 
									new WidgetContributorFactory()
							{	
								public WidgetContributor create()
								{	  						 
									return new ObjectSelectionWidget();
								}
							}));		

				   browseDialog_.setTypeRuntimeServer(getServiceTypeRuntimeServer());
				   browseDialog_.setInitialSelection(getObjectSelection());
			       result = browseDialog_.open();
			       if (result == Dialog.OK)
			       {
			    	   serviceImpl_.removeModifyListener(objectModifyListener_);
				       serviceImpl_.setText(browseDialog_.getDisplayableSelectionString()); 
				       serviceImpl_.addModifyListener(objectModifyListener_);
				       objectSelection = browseDialog_.getObjectSelection();
				       project = browseDialog_.getProject();
				       componentName= browseDialog_.getComponentName();			       
			       }
			       browseDialog_ = null;
			   }
			   
			   // call ObjectSelectionOutputCommand to carry out any transformation on the objectSelection
			   if (result == Dialog.OK)
			   {
				   callObjectTransformation(objectSelection, project, componentName, getWebServiceScenario() != WebServiceScenario.TOPDOWN);				   
			       validationState_ = ValidationUtils.VALIDATE_ALL;
			       statusListener_.handleEvent(null); // validate the page
			   }			   
	    }
	}

	
}

