/*******************************************************************************
 * Copyright (c) 2008 IONA Technologies PLC
 * 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:
 * IONA Technologies PLC - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.internal.cxf.ui.widgets;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.wsdl.Definition;
import javax.wsdl.Service;
import javax.xml.namespace.QName;

import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jst.ws.internal.cxf.core.CXFCorePlugin;
import org.eclipse.jst.ws.internal.cxf.core.model.WSDL2JavaContext;
import org.eclipse.jst.ws.internal.cxf.core.model.WSDL2JavaDataModel;
import org.eclipse.jst.ws.internal.cxf.core.utils.JDTUtils;
import org.eclipse.jst.ws.internal.cxf.core.utils.WSDLUtils;
import org.eclipse.jst.ws.internal.cxf.ui.CXFUIMessages;
import org.eclipse.jst.ws.internal.cxf.ui.CXFUIPlugin;
import org.eclipse.jst.ws.internal.cxf.ui.dialogs.ResourceSelectionDialog;
import org.eclipse.jst.ws.internal.cxf.ui.viewers.PackageNameColumnLabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.SelectionDialog;

/**
 * Provides widgets for WSDL2Java preferences, wizards, dialogs. Enables the
 * reuse of widgets in multiple locations. Widgets have there labeling and
 * tooltips set here and where possible listeners are set which update instances
 * of <code>WSDL2JavaContext</code> and <code>WSDL2JavaDataModel</code>.
 * 
 * @author sclarke
 */
public final class WSDL2JavaWidgetFactory {
    private static final String XJC_DV_ARG = "-Xdv"; //$NON-NLS-1$
    private static final String XJC_TS_ARG = "-Xts"; //$NON-NLS-1$
    private static final String XJC_TS_MULTI_ARG = "-Xts:style:multiline"; //$NON-NLS-1$
    private static final String XJC_TS_SIMPLE = "-Xts:style:simple"; //$NON-NLS-1$
    private static final String XJC_LOCATOR_ARG = "-Xlocator"; //$NON-NLS-1$
    private static final String XJC_SYNC_METHODS_ARG = "-Xsync-methods"; //$NON-NLS-1$
    private static final String XJC_MARK_GENERATED_ARG = "-mark-generated"; //$NON-NLS-1$
    private static final String XJC_EPISODE_FILE_ARG = "-episode"; //$NON-NLS-1$

    private WSDL2JavaWidgetFactory() {
    }

    public static Button createGenerateClientButton(Composite parent, final WSDL2JavaContext model) {
        final Button genClientButton = new Button(parent, SWT.CHECK);
        genClientButton.setText(CXFUIMessages.JAVA2WS_GEN_CLIENT_LABEL);
        genClientButton.setToolTipText(CXFUIMessages.WSDL2JAVA_GENERATE_CLIENT_TOOLTIP);
        genClientButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                model.setGenerateClient(genClientButton.getSelection());
            }
        });
        genClientButton.setSelection(model.isGenerateClient());
        return genClientButton;
    }

    public static Button createGenerateServerButton(Composite parent, final WSDL2JavaContext model) {
        final Button genServerButton = new Button(parent, SWT.CHECK);
        genServerButton.setText(CXFUIMessages.JAVA2WS_GEN_SERVER_LABEL);
        genServerButton.setToolTipText(CXFUIMessages.WSDL2JAVA_GENERATE_SERVER_TOOLTIP);
        genServerButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                model.setGenerateServer(genServerButton.getSelection());
            }
        });
        genServerButton.setSelection(model.isGenerateServer());
        return genServerButton;
    }

    public static Button createGenerateImplementationButton(Composite parent, final WSDL2JavaContext model) {
        final Button genImplementatinButton = new Button(parent, SWT.CHECK);
        genImplementatinButton.setText(CXFUIMessages.JAVA2WS_GEN_IMPLEMENTATION_LABEL);
        genImplementatinButton.setToolTipText(CXFUIMessages.WSDL2JAVA_GENERATE_IMPLEMENTATION_TOOLTIP);
        genImplementatinButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                model.setGenerateImplementation(genImplementatinButton.getSelection());
            }
        });
        genImplementatinButton.setSelection(model.isGenerateImplementation());
        return genImplementatinButton;
    }

    public static Button createProcessSOAPHeadersButton(Composite parent, final WSDL2JavaContext model) {
        final Button processSOAPHeadersButton = new Button(parent, SWT.CHECK);
        processSOAPHeadersButton.setText(CXFUIMessages.WSDL2JAVA_PROCESS_SOAP_HEADERS);
        processSOAPHeadersButton.setToolTipText(CXFUIMessages.WSDL2JAVA_PROCESS_SOAP_HEADERS_TOOLTIP);
        processSOAPHeadersButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                model.setProcessSOAPHeaders(processSOAPHeadersButton.getSelection());
            }
        });
        processSOAPHeadersButton.setSelection(model.isProcessSOAPHeaders());
        return processSOAPHeadersButton;
    }

    public static Button createNamespacePackageMappingButton(Composite parent, final WSDL2JavaContext model) {
        final Button namespacePackageMappingButton = new Button(parent, SWT.CHECK);
        namespacePackageMappingButton
                .setText(CXFUIMessages.WSDL2JAVA_LOAD_DEFAULT_NAMESPACE_PACKAGE_MAPPING);
        namespacePackageMappingButton
                .setToolTipText(CXFUIMessages.WSDL2JAVA_DEFAULT_NAMESPACE_LOADING_TOOLTIP);
        namespacePackageMappingButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                model.setLoadDefaultNamespacePackageNameMapping(namespacePackageMappingButton.getSelection());
            }
        });
        namespacePackageMappingButton.setSelection(model.isLoadDefaultNamespacePackageNameMapping());
        return namespacePackageMappingButton;
    }

    public static Button createExcludesNamespaceMappingButton(Composite parent, final WSDL2JavaContext model) {
        final Button excludesNamespaceMappingButton = new Button(parent, SWT.CHECK);
        excludesNamespaceMappingButton
                .setText(CXFUIMessages.WSDL2JAVA_USE_DEFAULT_EXCLUDES_NAMESPACE_MAPPING);
        excludesNamespaceMappingButton
                .setToolTipText(CXFUIMessages.WSDL2JAVA_EXCLUDE_NAMESPACE_LOADING_TOOLTIP);
        excludesNamespaceMappingButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                model.setLoadDefaultExcludesNamepsaceMapping(excludesNamespaceMappingButton.getSelection());
            }
        });
        excludesNamespaceMappingButton.setSelection(model.isLoadDefaultExcludesNamepsaceMapping());
        return excludesNamespaceMappingButton;
    }
    
    public static Button createNoAddressBindingButton(Composite parent, final WSDL2JavaContext model) {
        final Button noAddressBindingButton = new Button(parent, SWT.CHECK);
        noAddressBindingButton.setText(CXFUIMessages.bind(CXFUIMessages.WSDL2JAVA_NO_ADDRESS_BINDING,
                CXFCorePlugin.getEdition()));
        noAddressBindingButton.setToolTipText(
                CXFUIMessages.bind(CXFUIMessages.WSDL2JAVA_NO_ADDRESS_BINDING_TOOLTIP, 
                        CXFCorePlugin.getEdition()));
        noAddressBindingButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                model.setNoAddressBinding(noAddressBindingButton.getSelection());
            }
        });
        noAddressBindingButton.setSelection(model.isNoAddressBinding());
        return noAddressBindingButton;
    }

    public static TableItem createXJCDefaultValuesTableItem(Table xjcArgsTable, final WSDL2JavaContext model) {
        TableItem xjcDefaultValuesItem = new TableItem(xjcArgsTable, SWT.NONE);
        xjcDefaultValuesItem.setText(0, XJC_DV_ARG);
        xjcDefaultValuesItem.setText(1, CXFUIMessages.WSDL2JAVA_XJC_DEFAULT_VALUES);
        xjcDefaultValuesItem.setChecked(model.isXjcUseDefaultValues());
        return xjcDefaultValuesItem;
    }

    public static TableItem createXJCToStringTableItem(Table xjcArgsTable, final WSDL2JavaContext model) {
        TableItem xjcToStringItem = new TableItem(xjcArgsTable, SWT.NONE);
        xjcToStringItem.setText(0, XJC_TS_ARG);
        xjcToStringItem.setText(1, CXFUIMessages.WSDL2JAVA_XJC_TOSTRING);
        xjcToStringItem.setChecked(model.isXjcToString());
        return xjcToStringItem;
    }

    public static TableItem createXJCToStringMultiLineTableItem(Table xjcArgsTable,
            final WSDL2JavaContext model) {
        TableItem xjcToStringMultiLineItem = new TableItem(xjcArgsTable, SWT.NONE);
        xjcToStringMultiLineItem.setText(0, XJC_TS_MULTI_ARG);
        xjcToStringMultiLineItem.setText(1, CXFUIMessages.WSDL2JAVA_XJC_TOSTRING_MULTILINE);
        xjcToStringMultiLineItem.setChecked(model.isXjcToStringMultiLine());
        return xjcToStringMultiLineItem;
    }

    public static TableItem createXJCToStringSimpleTableItem(Table xjcArgsTable, final WSDL2JavaContext model) {
        TableItem xjcToStringSimpleItem = new TableItem(xjcArgsTable, SWT.NONE);
        xjcToStringSimpleItem.setText(0, XJC_TS_SIMPLE);
        xjcToStringSimpleItem.setText(1, CXFUIMessages.WSDL2JAVA_XJC_TOSTRING_SIMPLE);
        xjcToStringSimpleItem.setChecked(model.isXjcToStringSimple());
        return xjcToStringSimpleItem;
    }

    public static TableItem createXJCLocatorTableItem(Table xjcArgsTable, final WSDL2JavaContext model) {
        TableItem xjcLocatorItem = new TableItem(xjcArgsTable, SWT.NONE);
        xjcLocatorItem.setText(0, XJC_LOCATOR_ARG);
        xjcLocatorItem.setText(1, CXFUIMessages.WSDL2JAVA_XJC_LOCATOR);
        xjcLocatorItem.setChecked(model.isXjcLocator());
        return xjcLocatorItem;
    }

    public static TableItem createXJCSyncMethodsTableItem(Table xjcArgsTable, final WSDL2JavaContext model) {
        TableItem xjcSyncMethodsItem = new TableItem(xjcArgsTable, SWT.NONE);
        xjcSyncMethodsItem.setText(0, XJC_SYNC_METHODS_ARG);
        xjcSyncMethodsItem.setText(1, CXFUIMessages.WSDL2JAVA_XJC_SYNC_METHODS);
        xjcSyncMethodsItem.setChecked(model.isXjcSyncMethods());
        return xjcSyncMethodsItem;
    }

    public static TableItem createXJCMarkGeneratedTableItem(Table xjcArgsTable, final WSDL2JavaContext model) {
        TableItem xjcMarkGeneratedItem = new TableItem(xjcArgsTable, SWT.NONE);
        xjcMarkGeneratedItem.setText(0, XJC_MARK_GENERATED_ARG);
        xjcMarkGeneratedItem.setText(1, CXFUIMessages.WSDL2JAVA_XJC_MARK_GENERATED);
        xjcMarkGeneratedItem.setChecked(model.isXjcMarkGenerated());
        return xjcMarkGeneratedItem;
    }

    public static TableItem createXJCEpisodeFileTableItem(Table xjcArgsTable, final WSDL2JavaContext model) {
        TableItem xjcEpisodeFileItem = new TableItem(xjcArgsTable, SWT.NONE);
        xjcEpisodeFileItem.setText(0, XJC_EPISODE_FILE_ARG);
        xjcEpisodeFileItem.setText(1, CXFUIMessages.WSDL2JAVA_XJC_EPISODE_FILE);
        return xjcEpisodeFileItem;
    }

    public static Table createXJCArgTable(Composite parent, final WSDL2JavaContext model) {
        Table xjcArgsTable = new Table(parent, SWT.CHECK | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION);
        xjcArgsTable.setToolTipText(CXFUIMessages.WSDL2JAVA_XJC_ARGS_TOOLTIP);
        xjcArgsTable.setLinesVisible(true);
        xjcArgsTable.setHeaderVisible(true);

        TableLayout tableLayout = new TableLayout();
        xjcArgsTable.setLayout(tableLayout);

        TableColumn xjcArgColumn = new TableColumn(xjcArgsTable, SWT.NONE);
        xjcArgColumn.setText(CXFUIMessages.WSDL2JAVA_XJC_ARG_COLUMN_NAME);

        ColumnWeightData columnWeightData = new ColumnWeightData(100, 100, true);
        tableLayout.addColumnData(columnWeightData);

        TableColumn descriptionColumn = new TableColumn(xjcArgsTable, SWT.NONE);
        descriptionColumn.setText(CXFUIMessages.WSDL2JAVA_XJC_DESCRIPTION_COLUMN_NAME);
        columnWeightData = new ColumnWeightData(200, 200, true);
        tableLayout.addColumnData(columnWeightData);

        xjcArgsTable.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent event) {
                if (event.detail == SWT.CHECK) {
                    TableItem tableItem = (TableItem) event.item;
                    String xjcArg = tableItem.getText(0);
                    boolean checked = tableItem.getChecked();
                    if (xjcArg.equals(XJC_DV_ARG)) {
                        model.setXjcUseDefaultValues(checked);
                    }

                    if (xjcArg.equals(XJC_TS_ARG)) {
                        model.setXjcToString(checked);
                    }

                    if (xjcArg.equals(XJC_TS_MULTI_ARG)) {
                        model.setXjcToStringMultiLine(checked);
                    }

                    if (xjcArg.equals(XJC_TS_SIMPLE)) {
                        model.setXjcToStringSimple(checked);
                    }

                    if (xjcArg.equals(XJC_LOCATOR_ARG)) {
                        model.setXjcLocator(checked);
                    }

                    if (xjcArg.equals(XJC_SYNC_METHODS_ARG)) {
                        model.setXjcSyncMethods(checked);
                    }

                    if (xjcArg.equals(XJC_MARK_GENERATED_ARG)) {
                        model.setXjcMarkGenerated(checked);
                    }
                }
            }

        });

        xjcArgColumn.pack();
        descriptionColumn.pack();

        return xjcArgsTable;
    }

    public static Label createFrontendLabel(Composite parent) {
        Label frontendLabel = new Label(parent, SWT.NONE);
        frontendLabel.setText(CXFUIMessages.CXF_DEFAULT_FRONTEND_LABEL);
        return frontendLabel;
    }

    public static Combo createFrontendCombo(Composite parent, final WSDL2JavaContext model) {
        final Combo frontendCombo = new Combo(parent, SWT.READ_ONLY);
        frontendCombo.setToolTipText(CXFUIMessages.WSDL2JAVA_FRONTEND_TOOLTIP);
        frontendCombo.add(model.getFrontend().getLiteral());
        frontendCombo.setEnabled(false);
        frontendCombo.select(0);
        return frontendCombo;
    }

    public static Label createDatabindingLabel(Composite parent) {
        Label databindingLabel = new Label(parent, SWT.NONE);
        databindingLabel.setText(CXFUIMessages.CXF_DEFAULT_DATABINDING_LABEL);
        return databindingLabel;
    }

    public static Combo createDatabindingCombo(Composite parent, final WSDL2JavaContext model) {
        final Combo databindingCombo = new Combo(parent, SWT.READ_ONLY);
        databindingCombo.setToolTipText(CXFUIMessages.WSDL2JAVA_DATABINDING_TOOLTIP);
        databindingCombo.add(model.getDatabinding().getLiteral());
        databindingCombo.setEnabled(false);
        databindingCombo.select(0);
        return databindingCombo;
    }

    public static Label createWSDLVersionLabel(Composite parent) {
        Label wsdlVersionLabel = new Label(parent, SWT.NONE);
        wsdlVersionLabel.setText(CXFUIMessages.WSDL2JAVA_WSDL_VERSION_LABEL);
        return wsdlVersionLabel;
    }

    public static Combo createWSDLVersionCombo(Composite parent, final WSDL2JavaContext model) {
        final Combo wsdlVersionCombo = new Combo(parent, SWT.READ_ONLY);
        wsdlVersionCombo.setToolTipText(CXFUIMessages.WSDL2JAVA_WSDL_VERSION_TOOLTIP);
        wsdlVersionCombo.add(model.getWsdlVersion());
        wsdlVersionCombo.setEnabled(false);
        wsdlVersionCombo.select(0);
        return wsdlVersionCombo;
    }

    public static Button createDefaultValuesButton(Composite parent, final WSDL2JavaContext model) {
        final Button useDefaultValuesButton = new Button(parent, SWT.CHECK);
        useDefaultValuesButton.setText(CXFUIMessages.WSDL2JAVA_USE_DEFAULT_VALUES);
        useDefaultValuesButton.setToolTipText(CXFUIMessages.WSDL2JAVA_DEFAULT_VALUES_TOOLTIP);
        useDefaultValuesButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                model.setUseDefaultValues(useDefaultValuesButton.getSelection());
            }
        });
        useDefaultValuesButton.setSelection(model.isUseDefaultValues());
        return useDefaultValuesButton;
    }

    public static Label createOutputDirectoryLabel(Composite parent) {
        Label srcDirLabel = new Label(parent, SWT.NONE);
        srcDirLabel.setText(CXFUIMessages.WSDL2JAVA_OUTPUT_DIRECTORY);
        srcDirLabel.setToolTipText(CXFUIMessages.WSDL2JAVA_OUTPUT_DIRECTORY_TOOLTIP);
        return srcDirLabel;
    }

    public static Combo createOutputDirectoryCombo(Composite parent, final WSDL2JavaDataModel model) {
        final Combo outputDirCombo = new Combo(parent, SWT.READ_ONLY);
        outputDirCombo.setToolTipText(CXFUIMessages.WSDL2JAVA_OUTPUT_DIRECTORY_TOOLTIP);
        outputDirCombo.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent event) {
                String javaSourceFolder = outputDirCombo.getText();
                model.setJavaSourceFolder(javaSourceFolder);
            }
        });

        try {
            IPackageFragmentRoot[] packageFragmentRoots = JDTUtils.getJavaProject(model.getProjectName())
                    .getAllPackageFragmentRoots();
            for (int i = 0; i < packageFragmentRoots.length; i++) {
                IPackageFragmentRoot packageFragmentRoot = packageFragmentRoots[i];
                if (packageFragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE) {
                    outputDirCombo.add(packageFragmentRoot.getResource().getFullPath().toOSString());
                }
            }
            outputDirCombo.select(0);
        } catch (JavaModelException jme) {
            CXFUIPlugin.log(jme.getStatus());
        }

        return outputDirCombo;
    }

    public static Label createPackageNameLabel(Composite parent) {
        Label packageNameLabel = new Label(parent, SWT.NONE);
        packageNameLabel.setText(CXFUIMessages.WSDL2JAVA_PACKAGE_NAME);
        packageNameLabel.setToolTipText(CXFUIMessages.WSDL2JAVA_PACKAGE_NAME_TOOLTIP);
        return packageNameLabel;
    }

    public static Text createPackageNameText(Composite parent, final WSDL2JavaDataModel model) {
        final Text packageNameText = new Text(parent, SWT.BORDER);
        packageNameText.setToolTipText(CXFUIMessages.WSDL2JAVA_PACKAGE_NAME_TOOLTIP);

        packageNameText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                String packageName = packageNameText.getText();
                model.getIncludedNamespaces().put(model.getTargetNamespace(), packageName);
            }
        });

        packageNameText.setText(model.getIncludedNamespaces().get(model.getTargetNamespace()));

        return packageNameText;
    }

    public static Button createNamespacePackageMappingButton(Composite parent) {
        final Button namespaceMappingButton = new Button(parent, SWT.CHECK);
        namespaceMappingButton.setText(CXFUIMessages.WSDL2JAVA_PACKAGE_NAME_OPTIONAL);
        namespaceMappingButton.setToolTipText(CXFUIMessages.WSDL2JAVA_PACKAGE_NAME_OPTIONAL_TOOLTIP);
        return namespaceMappingButton;
    }

    public static TableViewerColumn createWSDLNamespaceViewerColumn(TableViewer tableViewer) {
        TableViewerColumn wsdlNamespaceViewerColumn = new TableViewerColumn(tableViewer, SWT.LEFT);
        wsdlNamespaceViewerColumn.setLabelProvider(new ColumnLabelProvider() {

            @Override
            public String getText(Object element) {
                return element.toString();
            }
        });
        TableColumn wsdlNamespaceColumn = wsdlNamespaceViewerColumn.getColumn();
        wsdlNamespaceColumn.setText(CXFUIMessages.WSDL2JAVA_WSDL_NAMESPACE_COLUMN_HEADER);
        wsdlNamespaceColumn.pack();
        return wsdlNamespaceViewerColumn;
    }

    public static TableViewerColumn createPackageNameColumn(TableViewer tableViewer, WSDL2JavaDataModel model) {
        TableViewerColumn packageNameViewerColumn = new TableViewerColumn(tableViewer, SWT.LEFT);
        packageNameViewerColumn.setLabelProvider(new PackageNameColumnLabelProvider(model));

        TableColumn packageNameColumn = packageNameViewerColumn.getColumn();
        packageNameColumn.setText(CXFUIMessages.WSDL2JAVA_PACKAGE_NAME_COLUMN_HEADER);
        packageNameColumn.pack();
        return packageNameViewerColumn;
    }

    public static Label createServiceNameLabel(Composite parent) {
        Label serviceNameLabel = new Label(parent, SWT.NONE);
        serviceNameLabel.setText(CXFUIMessages.WSDL2JAVA_SERVICE_NAME);
        serviceNameLabel.setToolTipText(CXFUIMessages.WSDL2JAVA_SERVICE_NAME_TOOLTIP);
        return serviceNameLabel;
    }

    @SuppressWarnings("unchecked")
    public static Combo createServiceNameCombo(Composite parent, final WSDL2JavaDataModel model) {
        final Combo serviceNameCombo = new Combo(parent, SWT.BORDER | SWT.READ_ONLY);
        serviceNameCombo.setToolTipText(CXFUIMessages.WSDL2JAVA_SERVICE_NAME_TOOLTIP);

        serviceNameCombo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent event) {
                model.setServiceName(serviceNameCombo.getText());
            }
        });

        Definition definition = model.getWsdlDefinition();
        if (definition != null) {
            Map servicesMap = definition.getServices();
            if (servicesMap != null) {
                Set servicesEntrySet = servicesMap.entrySet();
                Iterator servicesIterator = servicesEntrySet.iterator();
                while (servicesIterator.hasNext()) {
                    Map.Entry serviceEntry = (Map.Entry) servicesIterator.next();
                    Service service = (Service) serviceEntry.getValue();
                    QName qName = service.getQName();
                    serviceNameCombo.add(qName.getLocalPart());
                }
                serviceNameCombo.select(-1);
            }
        }

        return serviceNameCombo;
    }

    public static Label createBindingFilesLabel(Composite parent) {
        Label bindingFilesLabel = new Label(parent, SWT.NONE);
        bindingFilesLabel.setText(CXFUIMessages.WSDL2JAVA_BINDING_FILES);
        bindingFilesLabel.setToolTipText(CXFUIMessages.WSDL2JAVA_BINDING_NAME_TOOLTIP);
        return bindingFilesLabel;
    }

    public static List createBindingFilesList(Composite parent) {
        final List bindingFilesList = new List(parent, SWT.MULTI | SWT.BORDER);
        bindingFilesList.setToolTipText(CXFUIMessages.WSDL2JAVA_BINDING_NAME_TOOLTIP);
        return bindingFilesList;
    }

    public static Button createAddBindingFileButton(final Composite parent, final WSDL2JavaDataModel model,
            final List bindingFilesList) {
        Button addBindingFileButton = new Button(parent, SWT.PUSH);
        addBindingFileButton.setText(CXFUIMessages.WSDL2JAVA_BINDING_FILES_ADD);
        addBindingFileButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent event) {
                ResourceSelectionDialog selectionDialog = new ResourceSelectionDialog(
                        parent.getShell(),
                        "xml", //$NON-NLS-1$ 
                        CXFUIMessages.WSDL2JAVA_BINDING_FILE_DIALOG_FILTER_NAME,
                        CXFUIMessages.WSDL2JAVA_BINDING_FILE_DIALOG_TITLE);
                selectionDialog.setMessage(CXFUIMessages.WSDL2JAVA_BINDING_FILE_DIALOG_MESSAGE);
                if (selectionDialog.open() == SelectionDialog.OK) {
                    String result = selectionDialog.getResult()[0].toString();
                    if (!model.getBindingFiles().contains(result)) {
                        model.getBindingFiles().add(result);
                        bindingFilesList.add(result);
                    }
                }
            }
        });
        return addBindingFileButton;
    }

    public static Button createRemoveBindingFileButton(Composite parent, final WSDL2JavaDataModel model,
            final List bindingFilesList) {
        final Button removeBindingFileButton = new Button(parent, SWT.PUSH);
        removeBindingFileButton.setText(CXFUIMessages.WSDL2JAVA_BINDING_FILES_REMOVE);
        removeBindingFileButton.setEnabled(false);
        removeBindingFileButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent event) {
                String[] selectedBindingFiles = bindingFilesList.getSelection();
                for (String bindingFile : selectedBindingFiles) {
                    bindingFilesList.remove(bindingFile);
                    model.getBindingFiles().remove(bindingFile);
                }

                if (bindingFilesList.getItemCount() == 0) {
                    removeBindingFileButton.setEnabled(false);
                }
            }
        });

        bindingFilesList.addPaintListener(new PaintListener() {
            public void paintControl(PaintEvent event) {
                if (bindingFilesList.getItemCount() == 0) {
                    removeBindingFileButton.setEnabled(false);
                } else {
                    removeBindingFileButton.setEnabled(true);
                }
            }
        });

        return removeBindingFileButton;
    }

    public static Label createPaddingLabel(Composite parent) {
        return new Label(parent, SWT.NONE);
    }

    public static Label createXMLCatalogLabel(Composite parent) {
        Label xmlCatalogLabel = new Label(parent, SWT.NONE);
        xmlCatalogLabel.setText(CXFUIMessages.WSDL2JAVA_XML_CATLOG);
        xmlCatalogLabel.setToolTipText(CXFUIMessages.WSDL2JAVA_XML_CATALOG_TOOLTIP);
        return xmlCatalogLabel;
    }

    public static Text createXMLCatalogText(Composite parent, final WSDL2JavaDataModel model) {
        final Text xmlCatalogText = new Text(parent, SWT.BORDER);
        xmlCatalogText.setToolTipText(CXFUIMessages.WSDL2JAVA_XML_CATALOG_TOOLTIP);
        xmlCatalogText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                String xmlCatalog = xmlCatalogText.getText();
                model.setCatalogFile(xmlCatalog);
            }
        });

        return xmlCatalogText;
    }

    public static Button createXMLCatalogBrowseButton(Composite parent) {
        Button xmlCatalogBrowseButton = new Button(parent, SWT.PUSH);
        xmlCatalogBrowseButton.setText(CXFUIMessages.WSDL2JAVA_XML_CATLOG_BROWSE);
        return xmlCatalogBrowseButton;
    }

}
