/*******************************************************************************
 * Copyright (c) 2011 BSI Business Systems Integration AG.
 * 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:
 *     Daniel Wiehl (BSI Business Systems Integration AG) - initial API and implementation
 ******************************************************************************/
package org.eclipse.scout.sdk.ws.jaxws.util;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.jws.WebService;
import javax.wsdl.Binding;
import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.extensions.UnknownExtensibilityElement;
import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceClient;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMemberValuePair;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jdt.core.search.TypeDeclarationMatch;
import org.eclipse.jdt.core.search.TypeNameMatch;
import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
import org.eclipse.jdt.internal.corext.codemanipulation.OrganizeImportsOperation;
import org.eclipse.jdt.internal.corext.codemanipulation.OrganizeImportsOperation.IChooseImportQuery;
import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.FolderSelectionDialog;
import org.eclipse.jdt.ui.SharedASTProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.scout.commons.CompareUtility;
import org.eclipse.scout.commons.StringUtility;
import org.eclipse.scout.commons.xmlparser.ScoutXmlDocument;
import org.eclipse.scout.commons.xmlparser.ScoutXmlDocument.ScoutXmlElement;
import org.eclipse.scout.sdk.jobs.OperationJob;
import org.eclipse.scout.sdk.ui.internal.ScoutSdkUi;
import org.eclipse.scout.sdk.ui.view.properties.part.ISection;
import org.eclipse.scout.sdk.util.pde.PluginModelHelper;
import org.eclipse.scout.sdk.util.resources.ResourceUtility;
import org.eclipse.scout.sdk.util.signature.CompilationUnitImportValidator;
import org.eclipse.scout.sdk.util.signature.SignatureUtility;
import org.eclipse.scout.sdk.util.type.TypeUtility;
import org.eclipse.scout.sdk.workspace.IScoutBundle;
import org.eclipse.scout.sdk.workspace.IScoutElement;
import org.eclipse.scout.sdk.ws.jaxws.JaxWsConstants;
import org.eclipse.scout.sdk.ws.jaxws.JaxWsRuntimeClasses;
import org.eclipse.scout.sdk.ws.jaxws.JaxWsSdk;
import org.eclipse.scout.sdk.ws.jaxws.operation.OverrideUnimplementedMethodsOperation;
import org.eclipse.scout.sdk.ws.jaxws.resource.XmlResource;
import org.eclipse.scout.sdk.ws.jaxws.swt.model.BuildJaxWsBean;
import org.eclipse.scout.sdk.ws.jaxws.swt.view.part.AnnotationProperty;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.views.navigator.ResourceComparator;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.sun.xml.internal.bind.api.impl.NameConverter;

@SuppressWarnings("restriction")
public final class JaxWsSdkUtility {

  private JaxWsSdkUtility() {
  }

  public static boolean isValidJavaIdentifier(String identifier) {
    if (StringUtility.isNullOrEmpty(identifier)) {
      return false;
    }

    char[] chars = identifier.toCharArray();
    for (int i = 0; i < chars.length; i++) {
      if (i == 0) {
        if (!Character.isJavaIdentifierStart(chars[i])) {
          return false;
        }
      }
      else {
        if (!Character.isJavaIdentifierPart(chars[i])) {
          return false;
        }
      }
    }

    return true;
  }

  public static boolean exists(IResource resource) {
    refreshLocal(resource, IResource.DEPTH_ONE);
    return resource != null && resource.exists() && resource.isSynchronized(IResource.DEPTH_ONE);
  }

  public static void refreshLocal(IResource resource, int depth) {
    try {
      if (resource != null && !resource.isSynchronized(depth)) {
        resource.refreshLocal(depth, new NullProgressMonitor());
      }
    }
    catch (CoreException e) {
      JaxWsSdk.logWarning("The 'resource '" + resource.getFullPath().toPortableString() + "' could not be synchronized with the filesystem.");
    }
  }

  public static IFile toFile(IScoutBundle bundle, File file) {
    if (bundle == null || file == null) {
      return null;
    }

    IPath path = new Path(file.getAbsolutePath()).makeRelativeTo(bundle.getProject().getLocation());
    return JaxWsSdkUtility.getFile(bundle, path.toPortableString(), false);
  }

  public static File toFile(IFile file) {
    if (file == null) {
      return null;
    }
    return new File(file.getLocationURI());
  }

  public static IFile getFile(IScoutBundle scoutBundle, String path, boolean autoCreate) {
    return getFile(scoutBundle, null, path, autoCreate);
  }

  public static IFile getFile(IScoutBundle scoutBundle, String projectRelativePath, String fileName, boolean autoCreate) {
    if (fileName == null) {
      return null;
    }
    IPath path;
    if (StringUtility.isNullOrEmpty(projectRelativePath)) {
      path = new Path(fileName);
    }
    else {
      // ensure that the path begins and ends with a slash
      projectRelativePath = normalizePath(projectRelativePath, SeparatorType.BothType);
      path = new Path(projectRelativePath + fileName);
    }

    IFile file = scoutBundle.getProject().getFile(path);
    prepareFileAccess(file, autoCreate);
    return file;
  }

  public static void prepareFileAccess(IFile file, boolean autoCreate) {
    refreshLocal(file, IResource.DEPTH_ZERO);

    if (!exists(file) && autoCreate) {
      try {
        // create the folders if they do not exist yet
        if (file.getParent() instanceof IFolder) {
          ResourceUtility.mkdirs(file.getParent(), new NullProgressMonitor());
        }
        // the file does not already exist. Therefore create an empty file
        InputStream inputStream = new ByteArrayInputStream(new byte[0]);
        file.create(inputStream, true, new NullProgressMonitor());
      }
      catch (CoreException e) {
        throw new RuntimeException("An unexpected error occured while creating empty file", e);
      }
    }

    // register folder in build properties
    if (autoCreate && file.getParent() instanceof IFolder) {
      IFolder folder = (IFolder) file.getParent();
      if (!folder.getProjectRelativePath().toPortableString().contains("build")) {
        try {
          PluginModelHelper h = new PluginModelHelper(file.getProject());
          h.BuildProperties.addBinaryBuildEntry(folder);
          h.save();
        }
        catch (CoreException e) {
          JaxWsSdk.logError("failed to register folder in build.properties", e);
        }
      }
    }
  }

  public static IFolder getFolder(IScoutBundle scoutBundle, String projectRelativePath, boolean autoCreate) {
    if (StringUtility.isNullOrEmpty(projectRelativePath)) {
      return null;
    }
    // ensure that the path begins and ends with a slash
    IPath path = new Path(normalizePath(projectRelativePath, SeparatorType.BothType));
    IFolder folder = scoutBundle.getProject().getFolder(path);
    prepareFolderAccess(folder, autoCreate);
    return folder;
  }

  public static void prepareFolderAccess(IFolder folder, boolean autoCreate) {
    refreshLocal(folder, IResource.DEPTH_INFINITE);

    if (!folder.exists() && autoCreate) {
      try {
        // create the folders if they do not exist yet
        ResourceUtility.mkdirs(folder, new NullProgressMonitor());
      }
      catch (CoreException e) {
        throw new RuntimeException("An unexpected error occured while creating the report design file", e);
      }
    }

    // register folder in build properties
    if (autoCreate && !folder.getProjectRelativePath().toPortableString().contains("build")) {
      try {
        PluginModelHelper h = new PluginModelHelper(folder.getProject());
        h.BuildProperties.addBinaryBuildEntry(folder);
        h.save();
      }
      catch (CoreException e) {
        JaxWsSdk.logError("failed to register folder in build.properties", e);
      }
    }
  }

  /**
   * Creates an import directive in the compilation unit for the given {@link IType}.
   * The directive is only created if necessary.
   * 
   * @param declaringType
   *          the type the directive is to be created in
   * @param typeForImportDirective
   *          the type the directive is to be created for
   */
  public static void createImportDirective(IType declaringType, IType typeForImportDirective) {
    try {
      String resolveTypeName = JaxWsSdkUtility.resolveTypeName(declaringType, typeForImportDirective);
      if (resolveTypeName == null) {
        return;
      }
      if (typeForImportDirective.getFullyQualifiedName().equals(resolveTypeName)) {
        return; // no import directive necessary, as type must be used fully qualified
      }
      declaringType.getCompilationUnit().createImport(typeForImportDirective.getFullyQualifiedName().replaceAll("\\$", "."), null, new NullProgressMonitor());
    }
    catch (Exception e) {
      // nop
    }
  }

  /**
   * To obtain the fully qualified name
   * 
   * @param declaringType
   *          the type which contains possible import directives
   * @param signature
   *          the signature obtained by {@link IField#getTypeSignature()} or {@link IMethod#getReturnType()},
   *          respectively
   * @return the fully qualified name
   */
  public static String getFullyQualifiedNameFromSignature(IType declaringType, String signature) {
    return getFullyQualifiedNameFromName(declaringType, StringUtility.join(".", Signature.getSignatureQualifier(signature), Signature.getSignatureSimpleName(signature)));
  }

  /**
   * To obtain the fully qualified name
   * 
   * @param declaringType
   *          the type which contains possible import directives
   * @param name
   *          the name as in declaring type
   * @return the fully qualified name
   */
  public static String getFullyQualifiedNameFromName(IType declaringType, String name) {
    try {
      String[][] fullyQualifiedSignature = declaringType.resolveType(name);
      if (fullyQualifiedSignature != null && fullyQualifiedSignature.length > 0) {
        if (!StringUtility.isNullOrEmpty(fullyQualifiedSignature[0][0])) {
          return fullyQualifiedSignature[0][0] + "." + fullyQualifiedSignature[0][1];
        }
        else {
          return fullyQualifiedSignature[0][1];
        }
      }
    }
    catch (Exception e) {
      JaxWsSdk.logError(e);
    }
    return null;
  }

  public static String getFullyQualifiedSignature(IType declaringType, String signature) {
    return Signature.createTypeSignature(JaxWsSdkUtility.getFullyQualifiedNameFromSignature(declaringType, signature), true);
  }

  public static void organizeImports(IType type) {
    try {
      CodeGenerationSettings settings = JavaPreferencesSettings.getCodeGenerationSettings(type.getJavaProject());
      CompilationUnit astRoot = SharedASTProvider.getAST(type.getCompilationUnit(), SharedASTProvider.WAIT_ACTIVE_ONLY, null);

      IChooseImportQuery chooseImportQuery = new IChooseImportQuery() {
        @Override
        public TypeNameMatch[] chooseImports(TypeNameMatch[][] openChoices, ISourceRange[] ranges) {
          return new TypeNameMatch[0];
        }
      };

      OrganizeImportsOperation op = new OrganizeImportsOperation(type.getCompilationUnit(), astRoot, settings.importIgnoreLowercase, !type.getCompilationUnit().isWorkingCopy(), true, chooseImportQuery);
      op.run(new NullProgressMonitor());
    }
    catch (Throwable e) {
      JaxWsSdk.logError(e);
    }
  }

  public static String getFileNameWithoutExtension(IFile file) {
    if (file.getFileExtension() != null) {
      return file.getName().substring(0, file.getName().length() - file.getFileExtension().length() - 1);
    }
    else {
      return file.getName();
    }
  }

  public static String toStartWithLowerCase(String property) {
    if (!StringUtility.hasText(property)) {
      return null;
    }
    if (property.length() == 1) {
      return property.toLowerCase();
    }

    return property.substring(0, 1).toLowerCase() + property.substring(1);
  }

  public static String toStartWithUpperCase(String property) {
    if (!StringUtility.hasText(property)) {
      return null;
    }
    if (property.length() == 1) {
      return property.toUpperCase();
    }

    return property.substring(0, 1).toUpperCase() + property.substring(1);
  }

  public static String normalizePath(String path, SeparatorType separatorType) {
    if (path == null) {
      return null;
    }
    if (separatorType == SeparatorType.BothType || separatorType == SeparatorType.LeadingType) {
      if (!path.startsWith("/")) {
        path = "/" + path;
      }
    }
    else {
      if (path.startsWith("/")) {
        path = path.substring(1);
      }
    }

    if (separatorType == SeparatorType.BothType || separatorType == SeparatorType.TrailingType) {
      if (!path.endsWith("/")) {
        path += "/";
      }
    }
    else {
      if (path.endsWith("/")) {
        path = path.substring(0, path.length() - 1);
      }
    }
    return path;
  }

  /**
   * Excludes the composite from the layout manager if it does not contain any children and triggers to relayout the
   * composite.
   * 
   * @param composite
   */
  public static void doLayout(Composite composite) {
    if (composite != null && !composite.isDisposed()) {
      if (composite.getLayoutData() instanceof GridData) {
        if (composite.getChildren().length == 0) {
//          ((GridData) composite.getLayoutData()).exclude = true; // exclude does not work properly
          ((GridData) composite.getLayoutData()).heightHint = 0; // therefore this workaround is used, but as a drawback, the section has to collapsed and expanded
        }
        else {
//          ((GridData) composite.getLayoutData()).exclude = false; // exclude does not work properly
          ((GridData) composite.getLayoutData()).heightHint = SWT.DEFAULT; // therefore this workaround is used, but as a drawback, the section has to collapsed and expanded
        }
      }
      composite.layout(true, true);
    }
  }

  /**
   * workaround for proper redraw of sections which contain composites to be excluded / included depending one some
   * conditions.
   * This must take place when getForm()#redraw=true!
   * 
   * @param section
   */
  public static void doLayoutSection(ISection section) {
    if (section.isExpanded()) {
      section.setExpanded(false);
      section.setExpanded(true);
    }
  }

  public static void disposeChildControls(Composite composite) {
    if (composite != null && !composite.isDisposed()) {
      for (Control child : composite.getChildren()) {
        child.dispose();
      }
    }
  }

  public static void setView(Composite composite, boolean enabled) {
    if (composite != null && !composite.isDisposed()) {
      composite.setEnabled(enabled);
      for (Control child : composite.getChildren()) {
        if (child instanceof Composite) {
          setView((Composite) child, enabled);
        }
        else {
          child.setEnabled(enabled);
        }
      }
    }
  }

  public static Set<IResource> createResourceSet(IResource... resources) {
    Set<IResource> resourceSet = new HashSet<IResource>();
    for (IResource resource : resources) {
      if (resource != null) {
        resourceSet.add(resource);
      }
    }
    return resourceSet;
  }

  public static PortType getPortType(Definition wsdlDefinition, QName serviceQName, String portName) {
    if (wsdlDefinition == null || serviceQName == null || portName == null) {
      return null;
    }

    portName = QName.valueOf(portName).getLocalPart();

    Service service = wsdlDefinition.getService(serviceQName);
    if (service == null) {
      return null;
    }
    Port port = service.getPort(portName);
    if (port == null) {
      return null;
    }
    Binding binding = port.getBinding();
    if (binding == null) {
      return null;
    }
    return port.getBinding().getPortType();
  }

  /**
   * Resolves the requested PortType interface type located in the given jar file
   * 
   * @param portTypeQName
   *          the PortType to be resolved or null to get all PortTypes
   * @param jarFile
   *          the jar file the PortType interface type to be searched in
   * @return
   */
  public static IType resolvePortTypeInterfaceType(final QName portTypeQName, IFile jarFile) {
    if (portTypeQName == null) {
      return null;
    }
    IType[] types = resolvePortTypeInterfaceTypes(portTypeQName, jarFile);
    if (types.length == 0) {
      return null;
    }
    else if (types.length > 1) {
      JaxWsSdk.logWarning("Multiple PortType interface types found for port type '" + portTypeQName + "'");
    }
    return types[0];
  }

  /**
   * Resolves PortType interface types located in the given jar file
   * 
   * @param portTypeQName
   *          the PortType to be resolved or null to get all PortTypes
   * @param jarFile
   *          the jar file the PortType interface type to be searched in
   * @return
   */
  public static IType[] resolvePortTypeInterfaceTypes(final QName portTypeQName, IFile jarFile) {
    if (jarFile == null) {
      return new IType[0];
    }
    final Set<IType> types = new HashSet<IType>();
    try {
      new SearchEngine().search(
          SearchPattern.createPattern("*", IJavaSearchConstants.INTERFACE, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH),
          new SearchParticipant[]{SearchEngine.getDefaultSearchParticipant()},
          new JarFileSearchScope(jarFile), //SearchEngine.createWorkspaceScope(),
          new SearchRequestor() {

            @Override
            public final void acceptSearchMatch(SearchMatch match) throws CoreException {
              if (!(match instanceof TypeDeclarationMatch)) {
                return;
              }
              IType candidate = (IType) match.getElement();
              if (!TypeUtility.exists(candidate) || !candidate.isBinary()) {
                // type must be binary
                return;
              }
              // candidates must be annotated WebService annotation
              IAnnotation annotation = JaxWsSdkUtility.getAnnotation(candidate, WebService.class.getName(), false);
              if (!TypeUtility.exists(annotation)) {
                return;
              }
              if (portTypeQName == null) {
                types.add(candidate);
                return;
              }
              // candidate must match the port type
              IMemberValuePair[] properties = annotation.getMemberValuePairs();
              for (IMemberValuePair property : properties) {
                if (property.getMemberName().equals("name") && property.getValue().equals(portTypeQName.getLocalPart())) {
                  types.add(candidate);
                  return;
                }
              }
            }
          },
          null
          );
    }
    catch (Exception e) {
      JaxWsSdk.logError("Failed to resolve portType interface type", e);
    }
    return types.toArray(new IType[types.size()]);
  }

  /**
   * Resolves the requested service type located in the given jar file
   * 
   * @param serviceQName
   * @param jarFile
   * @return
   */
  public static IType resolveServiceType(final QName serviceQName, IFile jarFile) {
    if (serviceQName == null) {
      return null;
    }
    IType[] types = resolveServiceTypes(serviceQName, jarFile);
    if (types.length == 0) {
      return null;
    }
    else if (types.length > 1) {
      JaxWsSdk.logWarning("Multiple service types found for service '" + serviceQName + "'");
    }
    return types[0];
  }

  /**
   * Resolves service types located in the given jar file
   * 
   * @param serviceQName
   *          the service to be resolved or null to get all service types
   * @param jarFile
   *          the jar file the service type to be searched in
   * @return
   */
  public static IType[] resolveServiceTypes(final QName serviceQName, IFile jarFile) {
    final Set<IType> types = new HashSet<IType>();
    try {
      new SearchEngine().search(
          SearchPattern.createPattern("*", IJavaSearchConstants.TYPE, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH),
          new SearchParticipant[]{SearchEngine.getDefaultSearchParticipant()},
          new JarFileSearchScope(jarFile), //SearchEngine.createWorkspaceScope(),
          new SearchRequestor() {

            @Override
            public final void acceptSearchMatch(SearchMatch match) throws CoreException {
              if (!(match instanceof TypeDeclarationMatch)) {
                return;
              }
              IType candidate = (IType) match.getElement();
              if (!TypeUtility.exists(candidate) || !candidate.isBinary()) {
                // candidate must be binary
                return;
              }

              // candidate must be a concrete type
              if (!candidate.isClass() || Flags.isAbstract(candidate.getFlags())) {
                return;
              }

              // candidate must be of the type 'javax.xml.ws.Service'
              if (!JaxWsSdkUtility.isJdtSubType(javax.xml.ws.Service.class.getName(), candidate)) {
                return;
              }
              // candidates must be annotated WebServiceClient annotation
              IAnnotation annotation = JaxWsSdkUtility.getAnnotation(candidate, WebServiceClient.class.getName(), false);
              if (!TypeUtility.exists(annotation)) {
                return;
              }
              if (serviceQName == null) {
                types.add(candidate);
                return;
              }
              // candidate must match the service type
              IMemberValuePair[] properties = annotation.getMemberValuePairs();
              for (IMemberValuePair property : properties) {
                if (property.getMemberName().equals("name") && property.getValue().equals(serviceQName.getLocalPart())) {
                  types.add(candidate);
                  return;
                }
              }
            }
          },
          null
          );
    }
    catch (Exception e) {
      JaxWsSdk.logError("Failed to resolve portType interface type", e);
    }
    return types.toArray(new IType[types.size()]);
  }

  public static boolean isProviderAuthenticationSet(String fqn) {
    if (!StringUtility.hasText(fqn)) {
      return false;
    }
    fqn = fqn.replaceAll("\\$", "\\.");
    String noneAuthFqn = TypeUtility.getType(JaxWsRuntimeClasses.NullAuthenticationHandlerProvider).getFullyQualifiedName().replaceAll("\\$", "\\.");
    return TypeUtility.existsType(fqn) && !fqn.equals(noneAuthFqn);
  }

  private static class TypeEntry {
    private IType m_sourceType;
    private IType m_binaryType;

    public IType getSourceType() {
      return m_sourceType;
    }

    public void setSourceType(IType sourceType) {
      m_sourceType = sourceType;
    }

    public IType getBinaryType() {
      return m_binaryType;
    }

    public void setBinaryType(IType binaryType) {
      m_binaryType = binaryType;
    }
  }

  public static IType extractGenericSuperType(IType type, int index) {
    try {
      if (!TypeUtility.exists(type)) {
        return null;
      }
      String superTypeSignature = type.getSuperclassTypeSignature();
      if (superTypeSignature == null) {
        return null;
      }
      String[] typeArguments = Signature.getTypeArguments(superTypeSignature);
      if (typeArguments.length == 0 || index >= typeArguments.length) {
        return null;
      }
      String signature = typeArguments[index];
      String fullyQualifiedName = JaxWsSdkUtility.getFullyQualifiedNameFromSignature(type, signature);

      if (TypeUtility.existsType(fullyQualifiedName)) {
        return TypeUtility.getType(fullyQualifiedName);
      }
      return null;
    }
    catch (JavaModelException e) {
      JaxWsSdk.logError("could not extract generic super type", e);
    }
    return null;
  }

  public static QName extractServiceQNameFromWsClient(IType webserviceClientType) {
    IType serviceType = extractGenericSuperType(webserviceClientType, JaxWsConstants.GENERICS_WEBSERVICE_CLIENT_SERVICE_INDEX);
    if (!TypeUtility.exists(serviceType)) {
      return null;
    }

    // ensure service to be a subtype of {@link Service}
    if (!JaxWsSdkUtility.isJdtSubType(javax.xml.ws.Service.class.getName(), serviceType)) {
      return null;
    }

    IAnnotation annotation = JaxWsSdkUtility.getAnnotation(serviceType, WebServiceClient.class.getName(), false);
    return extractQNameFromAnnotation(annotation);
  }

  public static QName extractPortTypeQNameFromWsClient(IType webserviceClientType) {
    IType portTypeInterfaceType = extractGenericSuperType(webserviceClientType, JaxWsConstants.GENERICS_WEBSERVICE_CLIENT_PORT_TYPE_INDEX);
    if (!TypeUtility.exists(portTypeInterfaceType)) {
      return null;
    }

    IAnnotation annotation = JaxWsSdkUtility.getAnnotation(portTypeInterfaceType, WebService.class.getName(), false);
    return extractQNameFromAnnotation(annotation);
  }

  private static QName extractQNameFromAnnotation(IAnnotation annotation) {
    if (annotation == null || !annotation.exists()) {
      return null;
    }

    String localPart = null;
    String namespaceURI = null;
    try {
      for (IMemberValuePair pair : annotation.getMemberValuePairs()) {
        if (pair.getMemberName().equals("name")) {
          localPart = (String) pair.getValue();
        }
        else if (pair.getMemberName().equals("targetNamespace")) {
          namespaceURI = (String) pair.getValue();
        }
        if (namespaceURI != null && localPart != null) {
          break;
        }
      }

      QName qname = null;
      if (namespaceURI != null && localPart != null) {
        qname = new QName(namespaceURI, localPart);
      }
      else if (localPart != null) {
        qname = new QName(localPart);
      }

      if (qname != null) {
        return qname;
      }
    }
    catch (Exception e) {
      JaxWsSdk.logError("could not extract QName from annotation '" + annotation.getElementName() + "'", e);
    }
    return null;
  }

  public static boolean hasPackageElements(IScoutBundle bundle, String sourceFolder, String packageName) {
    if (!isValidSourceFolder(bundle, sourceFolder) || packageName == null) {
      return false;
    }

    try {
      IPath rootPath = bundle.getProject().getFullPath().append(sourceFolder);

      IPackageFragmentRoot root = bundle.getJavaProject().findPackageFragmentRoot(rootPath);
      if (root == null || !root.exists()) {
        return false;
      }
      IPackageFragment packageFragment = root.getPackageFragment(StringUtility.nvl(packageName, "")); // "" for default package
      return packageFragment != null && packageFragment.exists() && (packageFragment.hasChildren() || packageFragment.hasSubpackages());
    }
    catch (JavaModelException e) {
      return false;
    }
  }

  public static IPackageFragment toPackageFragment(IScoutBundle bundle, String sourceFolder, String packageName) {
    try {
      if (!isValidSourceFolder(bundle, sourceFolder)) {
        return null;
      }

      IPath rootPath = bundle.getProject().getFullPath().append(sourceFolder);

      IPackageFragmentRoot root = bundle.getJavaProject().findPackageFragmentRoot(rootPath);
      if (root == null || !root.exists()) {
        return null;
      }
      IPackageFragment packageFragment = root.getPackageFragment(StringUtility.nvl(packageName, "")); // "" for default package
      if (packageFragment != null && packageFragment.exists()) {
        return packageFragment;
      }
    }
    catch (JavaModelException e) {
      JaxWsSdk.logError("could not obtain package fragment", e);
    }
    return null;
  }

  public static void clearPackage(IScoutBundle bundle, String sourceFolder, String packageName) {
    try {
      IPackageFragment packageFragment = toPackageFragment(bundle, sourceFolder, packageName);
      if (packageFragment != null && packageFragment.exists()) {
        packageFragment.delete(true, new NullProgressMonitor());
      }
    }
    catch (JavaModelException e) {
      JaxWsSdk.logError("could not clear package", e);
    }
  }

  public static void createSourceFolder(IScoutBundle bundle, String sourceFolder) throws JavaModelException {
    List<IClasspathEntry> list = new LinkedList<IClasspathEntry>();
    IClasspathEntry[] entries = bundle.getJavaProject().getRawClasspath();
    for (IClasspathEntry entry : entries) {
      if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
        if (JaxWsSdkUtility.getFolder(bundle, sourceFolder, false).getFullPath().equals(entry.getPath())) {
          // source folder already exists
          return;
        }
      }
      list.add(entry);
    }

    IFolder srcFolder = JaxWsSdkUtility.getFolder(bundle, "/" + sourceFolder, true);
    IClasspathEntry newEntry = JavaCore.newSourceEntry(srcFolder.getFullPath());
    list.add(newEntry);
    bundle.getJavaProject().setRawClasspath(list.toArray(new IClasspathEntry[0]), bundle.getJavaProject().getOutputLocation(), new NullProgressMonitor());
  }

  public static boolean isValidSourceFolder(IScoutBundle bundle, String sourceFolder) {
    if (sourceFolder == null) {
      return false;
    }

    try {
      for (IClasspathEntry classpathEntry : bundle.getJavaProject().getRawClasspath()) {
        if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE && sourceFolder.equals(classpathEntry.getPath().lastSegment())) {
          return true;
        }
      }
    }
    catch (JavaModelException e) {
      JaxWsSdk.logError("Failed to validate source folder.", e);
    }
    return false;
  }

  public static String getPlainPortTypeName(String portTypeName) {
    if (portTypeName == null) {
      return null;
    }
    while (true) {
      if (portTypeName.toLowerCase().endsWith("porttype")) {
        portTypeName = portTypeName.substring(0, portTypeName.length() - "porttype".length());
        continue;
      }
      if (portTypeName.toLowerCase().endsWith("webservice")) {
        portTypeName = portTypeName.substring(0, portTypeName.length() - "webservice".length());
        continue;
      }
      if (portTypeName.toLowerCase().endsWith("service")) {
        portTypeName = portTypeName.substring(0, portTypeName.length() - "service".length());
        continue;
      }
      return portTypeName;
    }
  }

  public static String getRecommendedProviderImplPackageName(IScoutBundle bundle) {
    return StringUtility.join(".", bundle.getBundleName(), "services", "ws", "provider");
  }

  public static String getRecommendedHandlerPackageName(IScoutBundle bundle) {
    return StringUtility.join(".", bundle.getBundleName(), "services", "ws", "handler");
  }

  public static String getRecommendedConsumerImplPackageName(IScoutBundle bundle) {
    return StringUtility.join(".", bundle.getBundleName(), "services", "ws", "consumer");
  }

  public static String getRecommendedProviderSecurityPackageName(IScoutBundle bundle) {
    return StringUtility.join(".", bundle.getBundleName(), "services", "ws", "provider", "security");
  }

  public static String getRecommendedConsumerSecurityPackageName(IScoutBundle bundle) {
    return StringUtility.join(".", bundle.getBundleName(), "services", "ws", "consumer", "security");
  }

  public static String getRecommendedSessionPackageName(IScoutBundle bundle) {
    return StringUtility.join(".", bundle.getBundleName(), "services", "ws", "session");
  }

  public static String getRecommendedTargetNamespace(IScoutBundle bundle, String serviceName) {
    String[] segments = bundle.getBundleName().split("\\.");
    String projectSuffex = null;
    for (int i = segments.length - 1; i >= 0; i--) {
      String segment = segments[i];
      // exclude node segment
      if (segment.toLowerCase().equals("server") ||
          segment.toLowerCase().equals("online") ||
          segment.toLowerCase().equals("offline")) {
        continue;
      }
      projectSuffex = StringUtility.join(".", projectSuffex, segments[i]);
    }

    return "http://ws.services." + projectSuffex + "/" + serviceName + "/"; //trailing slash is required
  }

  /**
   * @param buildProperties
   *          to primary evaluate -p option of build properties. If null, JAX-WS mechanism is used to resolve package
   *          name
   * @param wsdlDefinition
   *          WSDL definition to resolve package name
   * @return
   */
  public static String resolveStubPackageName(Map<String, List<String>> buildProperties, Definition wsdlDefinition) {
    // global package specified by -p option in build properties
    String globalPackageName = JaxWsSdkUtility.getBuildProperty(buildProperties, JaxWsConstants.OPTION_PACKAGE);
    if (!StringUtility.isNullOrEmpty(globalPackageName)) {
      return globalPackageName;
    }

    if (wsdlDefinition == null) {
      return null;
    }

    // global package binding in WSDL file
    globalPackageName = getWsdlBindingPackageName(wsdlDefinition);
    if (!StringUtility.isNullOrEmpty(globalPackageName)) {
      return globalPackageName;
    }

    String targetNamespace = wsdlDefinition.getTargetNamespace();
    return JaxWsSdkUtility.targetNamespaceToPackageName(targetNamespace);
  }

  private static String getWsdlBindingPackageName(Definition definition) {
    if (definition == null) {
      return null;
    }
    for (Object e : definition.getExtensibilityElements()) {
      if (e instanceof UnknownExtensibilityElement) {
        UnknownExtensibilityElement uee = (UnknownExtensibilityElement) e;
        if (uee.getElementType().equals(new QName("http://java.sun.com/xml/ns/jaxws", "bindings"))) {
          Element element = uee.getElement();
          NodeList nodes = element.getElementsByTagNameNS("http://java.sun.com/xml/ns/jaxws", "package");
          if (nodes.getLength() > 0) {
            Element globalPackageBindingElement = (Element) nodes.item(0);
            return globalPackageBindingElement.getAttribute("name");
          }
        }
      }
    }
    return null;
  }

  public static String targetNamespaceToPackageName(String targetNamespace) {
    if (targetNamespace == null) {
      return null;
    }

    NameConverter nameConverter = NameConverter.standard;
    try {
      return nameConverter.toPackageName(targetNamespace); // same mechanism as JAX-WS uses. See @{link WSDLModeler#getJavaPackage} and @{link XJC#getDefaultPackageName()}
    }
    catch (Exception e) {
      JaxWsSdk.logError("failed to convert targetNamespace into package name");
    }
    return null;
  }

  public static Binding getBinding(Definition wsdlDefinition, QName serviceQName, String portName) {
    if (wsdlDefinition == null || serviceQName == null || portName == null) {
      return null;
    }

    portName = QName.valueOf(portName).getLocalPart();

    Service service = wsdlDefinition.getService(serviceQName);
    if (service == null) {
      return null;
    }
    Port port = service.getPort(portName);
    if (port == null) {
      return null;
    }
    return port.getBinding();
  }

  /**
   * To get an annotation on the given type. This is just a workaround as {@link IType#getAnnotation(String)} does not
   * work properly (changes are not reflected, e.g. after removing the annotation, it is still returned)
   * 
   * @param declaringType
   * @param annotationName
   * @return
   */
  public static IAnnotation getAnnotation(IType declaringType, String fqnAnnotationName, boolean recursively) {
    try {
      if (!TypeUtility.exists(declaringType)) {
        return null;
      }
      IAnnotation[] annotations = declaringType.getAnnotations();
      for (IAnnotation annotation : annotations) {
        if (declaringType.isBinary()) {
          // annotation name is always fully qualified name if coming from a class file
          if (annotation.getElementName().equals(fqnAnnotationName)) {
            return annotation;
          }
        }
        else {
          if (annotation.getElementName().equals(fqnAnnotationName) || annotation.getElementName().equals(Signature.getSimpleName(fqnAnnotationName))) {
            return annotation;
          }
        }
      }

      if (recursively) {
        IType superType = declaringType.newSupertypeHierarchy(new NullProgressMonitor()).getSuperclass(declaringType);
        return getAnnotation(superType, fqnAnnotationName, recursively);
      }
    }
    catch (JavaModelException e) {
      JaxWsSdk.logError("failed to resolve annotations", e);
    }
    return null;
  }

  public static boolean isAnnotationOnDeclaringType(IType declaringType, IAnnotation annotation) {
    if (annotation == null || declaringType == null) {
      return false;
    }
    IJavaElement parent = annotation.getParent();
    if (parent.getElementType() != IJavaElement.TYPE) {
      return false;
    }
    IType candidateType = (IType) parent;
    return candidateType.getFullyQualifiedName().equals(declaringType.getFullyQualifiedName());
  }

  public static Map<String, List<String>> getDefaultBuildProperties() {
    Map<String, List<String>> map = new HashMap<String, List<String>>();
    map.put("Xdebug", null);
    map.put("keep", null);
    map.put("verbose", null);

    List<String> values = new LinkedList<String>();
    values.add("2.0");
    map.put("target", values);
    return map;
  }

  public static IFile[] getBindingFiles(IScoutBundle bundle, Map<String, List<String>> buildProperties) {
    if (buildProperties == null || buildProperties.size() == 0) {
      return new IFile[0];
    }

    List<IFile> bindingFiles = new LinkedList<IFile>();
    for (Entry<String, List<String>> property : buildProperties.entrySet()) {
      if (property.getKey() == null || !property.getKey().equals(JaxWsConstants.OPTION_BINDING_FILE) || property.getValue() == null || property.getValue().size() == 0) {
        continue;
      }

      for (String bindingFileRaw : property.getValue()) {
        IFile bindingFile = JaxWsSdkUtility.getFile(bundle, bindingFileRaw, false);
        bindingFiles.add(bindingFile);
      }
    }
    return bindingFiles.toArray(new IFile[bindingFiles.size()]);
  }

  public static void addBuildProperty(Map<String, List<String>> buildProperties, String propertyName, String propertyValue) {
    if (!buildProperties.containsKey(propertyName)) {
      buildProperties.put(propertyName, new LinkedList<String>());
    }

    buildProperties.get(propertyName).add(propertyValue);
  }

  public static String getBuildProperty(Map<String, List<String>> buildProperties, String propertyName) {
    if (buildProperties == null || buildProperties.size() == 0) {
      return null;
    }

    for (Entry<String, List<String>> property : buildProperties.entrySet()) {
      if (CompareUtility.equals(property.getKey(), propertyName)) {
        List<String> values = property.getValue();
        if (values != null && values.size() > 0) {
          return values.get(0);
        }
      }
    }

    return null;
  }

  /**
   * To append an index to the markerGroupUUI
   * 
   * @param markerGroupUUID
   * @param index
   * @return
   */
  public static String toMarkerGroupUUID(String markerGroupUUID, int index) {
    return StringUtility.join("_", markerGroupUUID, String.valueOf(index));
  }

  /**
   * To get a unique binding file name path within the build path
   * 
   * @param bundle
   * @param alias
   * @return
   */
  public static String createUniqueBindingFileNamePath(IScoutBundle bundle, String alias, String schemaTargetNamespace) {
    String filename = StringUtility.join("-", alias, schemaTargetNamespace, "bindings");
    filename = JaxWsSdkUtility.toValidFileName(filename);

    String bindingFileName = JaxWsSdkUtility.normalizePath(JaxWsConstants.PATH_BUILD, SeparatorType.TrailingType) + filename;
    String candiate = bindingFileName;

    IFile file = JaxWsSdkUtility.getFile(bundle, candiate + ".xml", false);
    int i = 0;
    while (file != null && file.exists()) {
      i++;
      candiate = bindingFileName + " (" + i + ")";
      file = JaxWsSdkUtility.getFile(bundle, candiate + ".xml", false);
    }

    return candiate + ".xml";
  }

  public static Color getColorLightGray() {
    Color color = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry().get("lightGray");
    if (color == null) {
      PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry().put("lightGray", new RGB(245, 245, 245));
      color = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry().get("lightGray");
    }
    return color;
  }

  public static AnnotationProperty parseAnnotationTypeValue(IType declaringType, IAnnotation annotation, String property) {
    AnnotationProperty propertyValue = new AnnotationProperty();
    if (!TypeUtility.exists(declaringType)) {
      return propertyValue;
    }

    if (!TypeUtility.exists(annotation)) {
      return propertyValue;
    }

    try {
      for (IMemberValuePair pair : annotation.getMemberValuePairs()) {
        if (pair.getMemberName().equals(property)) {
          String propertySignature = Signature.createTypeSignature((String) pair.getValue(), true);
          String fullyQualifiedName = JaxWsSdkUtility.getFullyQualifiedNameFromSignature(declaringType, propertySignature);

          propertyValue.setInherited(false);
          propertyValue.setFullyQualifiedName(fullyQualifiedName);
          return propertyValue;
        }
      }

      // get default value
      propertyValue.setInherited(true);

      String fqnAnnotationType = getFullyQualifiedNameFromName(declaringType, annotation.getElementName());
      IType type = TypeUtility.getType(fqnAnnotationType);
      if (TypeUtility.exists(type)) {
        propertyValue.setFullyQualifiedName((String) type.getMethod(property, new String[0]).getDefaultValue().getValue());
      }
      return propertyValue;
    }
    catch (JavaModelException e) {
      JaxWsSdk.logError("failed to parse annotation property value", e);
    }
    return propertyValue;
  }

  /**
   * Supports SuperTypes to be at multiple locations
   * 
   * @param bundle
   * @param superType
   * @return
   */
  public static IType[] getJdtSubTypes(IScoutBundle bundle, String fqnSuperType, boolean includeInterfaces, boolean includeAbstractTypes, boolean includeFinalTypes, boolean sameProject) {
    List<IType> types = new LinkedList<IType>();
    try {
      IType[] superTypes = TypeUtility.getTypes(fqnSuperType);
      for (IType superType : superTypes) {
        ITypeHierarchy hierarchy = superType.newTypeHierarchy(new NullProgressMonitor());
        IType[] candidates = hierarchy.getAllSubtypes(superType);
        for (IType candidate : candidates) {
          if (TypeUtility.exists(candidate)) {
            if (!includeInterfaces && Flags.isInterface(candidate.getFlags())) {
              continue;
            }
            if (!includeAbstractTypes && Flags.isAbstract(candidate.getFlags())) {
              continue;
            }
            if (!includeFinalTypes && Flags.isFinal(candidate.getFlags())) {
              continue;
            }
            if (sameProject && !bundle.getJavaProject().equals(candidate.getJavaProject())) {
              continue;
            }
            if (TypeUtility.isOnClasspath(candidate, bundle.getJavaProject())) {
              types.add(candidate);
            }
          }
        }
      }
    }
    catch (JavaModelException e) {
      JaxWsSdk.logError("failed to get subclasses of '" + fqnSuperType + "'", e);
    }

    JaxWsSdkUtility.sortTypesByName(types, true);
    return types.toArray(new IType[types.size()]);
  }

  /**
   * Supports SuperTypes to be at multiple locations.
   * E.g. JAX-WS classes (i.e. javax.xml.ws.Service) which is defined in JRE but also might be defined in a WLS specific
   * library fragment.
   * 
   * @param candidateToCheck
   * @param fqnSuperType
   * @return
   */
  public static boolean isJdtSubType(String fqnSuperType, IType candidateToCheck) {
    if (candidateToCheck == null) {
      return false;
    }
    IType[] superTypes = TypeUtility.getTypes(fqnSuperType);
    try {
      ITypeHierarchy superTypeHierarchy = candidateToCheck.newSupertypeHierarchy(new NullProgressMonitor());
      for (IType superType : superTypes) {
        if (superTypeHierarchy.contains(superType)) {
          return true;
        }
      }
    }
    catch (JavaModelException e) {
      JaxWsSdk.logError(e);
    }
    return false;
  }

  public static String resolveTypeName(IType declaringType, IType typeToBeResolved) throws JavaModelException {
    String typeSignature = Signature.createTypeSignature(typeToBeResolved.getFullyQualifiedName(), true);
    CompilationUnitImportValidator validator = new CompilationUnitImportValidator(declaringType.getCompilationUnit());
    return SignatureUtility.getTypeReference(typeSignature, declaringType, validator);
  }

  public static String toValidFileName(String name) {
    return name.replaceAll("[\\\\/\\:\\*\\?\\<\\>\"]", "");
  }

  public static boolean containsGlobalBindingSection(IScoutBundle bundle, Map<String, List<String>> propertiers, boolean checkForMultipleOccurences) {
    IFile[] bindingFiles = JaxWsSdkUtility.getBindingFiles(bundle, propertiers);

    List<XmlResource> bindingFileResources = new LinkedList<XmlResource>();
    for (IFile bindingFile : bindingFiles) {
      XmlResource xmlResource = new XmlResource(bundle);
      xmlResource.setFile(bindingFile);
      bindingFileResources.add(xmlResource);
    }

    return containsGlobalBindingSection(bindingFileResources.toArray(new XmlResource[bindingFileResources.size()]), checkForMultipleOccurences);
  }

  public static boolean containsGlobalBindingSection(XmlResource[] bindingFileResources, boolean checkForMultipleOccurences) {
    int count = 0;
    try {
      for (XmlResource bindingFileResource : bindingFileResources) {
        ScoutXmlDocument xmlBindingFile = bindingFileResource.loadXml();

        List<ScoutXmlElement> candidates = xmlBindingFile.getRoot().getDescendants("*:globalBindings");
        for (ScoutXmlElement candidate : candidates) {
          String prefix = candidate.getNamePrefix();
          String namespace = candidate.getNamespace(prefix);
          if (namespace.equals("http://java.sun.com/xml/ns/jaxb")) {
            count++;
            if (checkForMultipleOccurences) {
              if (count > 1) {
                return true;
              }
            }
            else {
              return true;
            }
            break;
          }
        }
      }
    }
    catch (Exception e) {
      // nop
    }
    return false;
  }

  private static String getStubJarFilePath(String jarFileName) {
    if (jarFileName == null) {
      return null;
    }
    // ensure no file extension set
    jarFileName = new Path(jarFileName).removeFileExtension().lastSegment();
    // ensure valid filename
    jarFileName = JaxWsSdkUtility.toValidFileName(jarFileName);
    String folder = JaxWsSdkUtility.normalizePath(JaxWsConstants.STUB_FOLDER, SeparatorType.BothType);
    return StringUtility.join("/", folder, jarFileName + ".jar");
  }

  public static IFile getStubJarFile(IScoutBundle bundle, BuildJaxWsBean buildJaxWsBean, String wsdlFileName) {
    Map<String, List<String>> buildProperties = null;
    if (buildJaxWsBean != null) {
      buildProperties = buildJaxWsBean.getPropertiers();
    }
    return JaxWsSdkUtility.getStubJarFile(bundle, buildProperties, wsdlFileName);
  }

  /**
   * <p>
   * To get the stub file for a provider or consumer. The stub file is resolved as follows:
   * </p>
   * <ol>
   * <li>build properties are looked for a {@link JaxWsConstants#OPTION_JAR} entry</li>
   * <li>JAR file name is derived from WSDL file name</li>
   * </ol>
   * 
   * @param bundle
   * @param buildProperties
   * @param wsdlFileName
   * @return
   */
  public static IFile getStubJarFile(IScoutBundle bundle, Map<String, List<String>> buildProperties, String wsdlFileName) {
    String jarFileName = null;
    if (buildProperties != null) {
      // custom JAR name specified by -jar option in build properties
      String customJarFileName = JaxWsSdkUtility.getBuildProperty(buildProperties, JaxWsConstants.OPTION_JAR);
      if (StringUtility.hasText(customJarFileName)) {
        jarFileName = new Path(customJarFileName).removeFileExtension().lastSegment();
      }
    }
    // default jar name derived from WSDL file name
    if (jarFileName == null && wsdlFileName != null) {
      jarFileName = new Path(wsdlFileName).removeFileExtension().lastSegment();
    }
    if (jarFileName == null) {
      JaxWsSdk.logWarning("Failed to derive stub JAR file name. Ensure WSDL file to exist or specify the build property '" + JaxWsConstants.OPTION_JAR + "' with the JAR file name as its value");
      return null;
    }

    String path = JaxWsSdkUtility.getStubJarFilePath(jarFileName);
    return JaxWsSdkUtility.getFile(bundle, path, false);
  }

  public static IScoutBundle getRootBundle(IScoutBundle serverBundle) {
    if (serverBundle.getType() != IScoutElement.BUNDLE_SERVER) {
      return null;
    }
    IScoutBundle bundle = serverBundle;

    while (bundle.getScoutProject().getParentProject() != null) {
      IScoutBundle candidate = bundle.getScoutProject().getParentProject().getServerBundle();
      if (candidate == null || !serverBundle.isOnClasspath(candidate)) {
        break;
      }
      bundle = bundle.getScoutProject().getParentProject().getServerBundle();
    }
    return bundle;
  }

  public static boolean registerJarLib(IScoutBundle bundle, IFile jarFile, boolean remove, IProgressMonitor monitor) {
    boolean success = true;
    JaxWsSdkUtility.refreshLocal(jarFile, IResource.DEPTH_ONE);

    String jarFilePath = JaxWsSdkUtility.normalizePath(jarFile.getProjectRelativePath().toPortableString(), SeparatorType.None);
    IJavaProject javaProject = bundle.getJavaProject();
    IProject project = bundle.getProject();

    // update Java class path in .classpath file
    try {
      List<IClasspathEntry> cpeList = new ArrayList<IClasspathEntry>();
      for (IClasspathEntry cpe : javaProject.getRawClasspath()) {
        if (cpe.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
          if (!cpe.getPath().equals(project.getFullPath().append(jarFilePath))) {
            cpeList.add(cpe);
          }
        }
        else {
          cpeList.add(cpe);
        }
      }
      if (!remove) {
        cpeList.add(JavaCore.newLibraryEntry(project.getFullPath().append(jarFilePath), null, null, true));
      }
      javaProject.setRawClasspath(cpeList.toArray(new IClasspathEntry[cpeList.size()]), monitor);
    }
    catch (Exception e) {
      JaxWsSdk.logError("could not update Java class path in .classpath file", e);
    }

    // update Bundle-ClassPath in MANIFEST.MF
    PluginModelHelper h = new PluginModelHelper(project);
    try {
      if (remove) {
        h.Manifest.removeClasspathEntry(jarFile);
      }
      else {
        h.Manifest.addClasspathEntry(jarFile);
      }
      h.Manifest.addClasspathDefaultEntry();
    }
    catch (Exception e) {
      JaxWsSdk.logError("could not update Bundle-ClassPath in MANIFEST.MF", e);
      success = false;
    }

    // update bin.includes in build.properties
    try {
      // remove JAR file registration as folder is registered anyway
      h.BuildProperties.removeBinaryBuildEntry(jarFile);
      if (!remove) {
        // register folder, not file
        h.BuildProperties.addBinaryBuildEntry(JaxWsSdkUtility.getParentFolder(bundle, jarFile));
      }
    }
    catch (Exception e) {
      JaxWsSdk.logError("could not update bin.includes in build.properties", e);
      success = false;
    }
    h.save();

    return success;
  }

  public static void overrideUnimplementedMethodsAsync(IType type) {
    OverrideUnimplementedMethodsOperation op = new OverrideUnimplementedMethodsOperation();
    op.setType(type);
    new OperationJob(op).schedule();
  }

  public static <T> void removeDuplicateEntries(List<T> list) {
    Set<T> elementsVisited = new HashSet<T>();
    Iterator<T> iterator = list.iterator();
    while (iterator.hasNext()) {
      T element = iterator.next();
      if (elementsVisited.contains(element)) {
        iterator.remove();
      }
      elementsVisited.add(element);
    }
  }

  public static void sortTypesByName(List<IType> list, boolean removeDuplicates) {
    if (removeDuplicates) {
      JaxWsSdkUtility.removeDuplicateEntries(list);
    }

    Collections.sort(list, new Comparator<IType>() {

      @Override
      public int compare(IType type1, IType type2) {
        return CompareUtility.compareTo(type1.getElementName(), type2.getElementName());
      }
    });
  }

  public static IFolder getParentFolder(IScoutBundle bundle, IFile file) {
    if (file == null) {
      return null;
    }
    IPath parentFolderPath = file.getProjectRelativePath().removeLastSegments(1);
    if (parentFolderPath.segmentCount() == 0) {
      return null;
    }
    return JaxWsSdkUtility.getFolder(bundle, parentFolderPath.toPortableString(), false);
  }

  public static IFolder openProjectFolderDialog(IScoutBundle bundle, ViewerFilter filter, String title, String description, IFolder rootFolder, IFolder initialFolder) {
    if (!JaxWsSdkUtility.exists(rootFolder)) {
      rootFolder = JaxWsSdkUtility.getFolder(bundle, rootFolder.getProjectRelativePath().toPortableString(), true);
    }
    ILabelProvider labelProvider = new WorkbenchLabelProvider();
    ITreeContentProvider contentProvider = new WorkbenchContentProvider();
    FolderSelectionDialog dialog = new FolderSelectionDialog(ScoutSdkUi.getShell(), labelProvider, contentProvider);
    dialog.setTitle(title);
    dialog.setMessage(description);
    dialog.addFilter(filter);
    dialog.setHelpAvailable(false);
    dialog.setAllowMultiple(false);
    if (initialFolder != null) {
      dialog.setInitialSelection(initialFolder);
    }
    String parentFolderPath = rootFolder.getProjectRelativePath().removeLastSegments(1).toPortableString();
    dialog.setInput(JaxWsSdkUtility.getFolder(bundle, parentFolderPath, true));
    dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));

    if (dialog.open() == Window.OK) {
      return (IFolder) dialog.getFirstResult();
    }
    return null;
  }

  public static enum SeparatorType {
    LeadingType, TrailingType, BothType, None;
  }

  private static class JarFileSearchScope implements IJavaSearchScope {

    private IFile m_jarFile;

    public JarFileSearchScope(IFile jarFile) {
      m_jarFile = jarFile;
    }

    @Override
    public boolean encloses(String resourcePath) {
      return true;
    }

    @Override
    public boolean encloses(IJavaElement element) {
      return (element.getElementType() == IJavaElement.TYPE);
    }

    @Override
    public IPath[] enclosingProjectsAndJars() {
      return new IPath[]{m_jarFile.getFullPath()};
    }

    @SuppressWarnings("deprecation")
    @Override
    public boolean includesBinaries() {
      return true;
    }

    @SuppressWarnings("deprecation")
    @Override
    public boolean includesClasspaths() {
      return false;
    }

    @SuppressWarnings("deprecation")
    @Override
    public void setIncludesBinaries(boolean includesBinaries) {
    }

    @SuppressWarnings("deprecation")
    @Override
    public void setIncludesClasspaths(boolean includesClasspaths) {
    }

  }
}
