/*******************************************************************************
 * Copyright (c) 2001, 2007 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
 *******************************************************************************/
package org.eclipse.wst.wsdl.internal.impl;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.wsdl.BindingFault;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Fault;
import javax.wsdl.Input;
import javax.wsdl.Operation;
import javax.wsdl.Output;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.extensions.ExtensionRegistry;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.wst.wsdl.Binding;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.ExtensibilityElement;
import org.eclipse.wst.wsdl.Import;
import org.eclipse.wst.wsdl.Message;
import org.eclipse.wst.wsdl.Namespace;
import org.eclipse.wst.wsdl.PortType;
import org.eclipse.wst.wsdl.Service;
import org.eclipse.wst.wsdl.Types;
import org.eclipse.wst.wsdl.WSDLElement;
import org.eclipse.wst.wsdl.WSDLFactory;
import org.eclipse.wst.wsdl.WSDLPackage;
import org.eclipse.wst.wsdl.WSDLPlugin;
import org.eclipse.wst.wsdl.XSDSchemaExtensibilityElement;
import org.eclipse.wst.wsdl.internal.util.WSDLResourceFactoryImpl;
import org.eclipse.wst.wsdl.internal.util.WSDLUtil;
import org.eclipse.wst.wsdl.util.WSDLConstants;
import org.eclipse.wst.wsdl.util.WSDLResourceImpl;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDImport;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDTypeDefinition;
import org.eclipse.xsd.impl.XSDImportImpl;
import org.eclipse.xsd.impl.XSDSchemaImpl;
import org.eclipse.xsd.util.XSDConstants;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.events.MutationEvent;


/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Definition</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.DefinitionImpl#getTargetNamespace <em>Target Namespace</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.DefinitionImpl#getLocation <em>Location</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.DefinitionImpl#getQName <em>QName</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.DefinitionImpl#getEncoding <em>Encoding</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.DefinitionImpl#getEImports <em>EImports</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.DefinitionImpl#getETypes <em>ETypes</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.DefinitionImpl#getEMessages <em>EMessages</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.DefinitionImpl#getEPortTypes <em>EPort Types</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.DefinitionImpl#getEBindings <em>EBindings</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.DefinitionImpl#getEServices <em>EServices</em>}</li>
 *   <li>{@link org.eclipse.wst.wsdl.internal.impl.DefinitionImpl#getENamespaces <em>ENamespaces</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class DefinitionImpl extends ExtensibleElementImpl implements Definition
{
  private static final String XMLNS = "xmlns"; //$NON-NLS-1$

  /**
   * This class is not intended to be serialized.
   * serialVersionUID is assigned with 1L to avoid
   * compiler warning messages.
   */
  private static final long serialVersionUID = 1L;

  /**
   * The default value of the '{@link #getTargetNamespace() <em>Target Namespace</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getTargetNamespace()
   * @generated
   * @ordered
   */
  protected static final String TARGET_NAMESPACE_EDEFAULT = null;

  /**
   * The cached value of the '{@link #getTargetNamespace() <em>Target Namespace</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getTargetNamespace()
   * @generated
   * @ordered
   */
  protected String targetNamespace = TARGET_NAMESPACE_EDEFAULT;

  /**
   * The default value of the '{@link #getLocation() <em>Location</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getLocation()
   * @generated
   * @ordered
   */
  protected static final String LOCATION_EDEFAULT = null;

  /**
   * The cached value of the '{@link #getLocation() <em>Location</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getLocation()
   * @generated
   * @ordered
   */
  protected String location = LOCATION_EDEFAULT;

  /**
   * The default value of the '{@link #getQName() <em>QName</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getQName()
   * @generated
   * @ordered
   */
  protected static final QName QNAME_EDEFAULT = null;

  /**
   * The cached value of the '{@link #getQName() <em>QName</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getQName()
   * @generated
   * @ordered
   */
  protected QName qName = QNAME_EDEFAULT;

  /**
   * The default value of the '{@link #getEncoding() <em>Encoding</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEncoding()
   * @generated
   * @ordered
   */
  protected static final String ENCODING_EDEFAULT = null;

  /**
   * The cached value of the '{@link #getEncoding() <em>Encoding</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEncoding()
   * @generated
   * @ordered
   */
  protected String encoding = ENCODING_EDEFAULT;

  /**
   * The cached value of the '{@link #getEImports() <em>EImports</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEImports()
   * @generated
   * @ordered
   */
  protected EList eImports = null;

  /**
   * The cached value of the '{@link #getETypes() <em>ETypes</em>}' containment reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getETypes()
   * @generated
   * @ordered
   */
  protected Types eTypes = null;

  /**
   * The cached value of the '{@link #getEMessages() <em>EMessages</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEMessages()
   * @generated
   * @ordered
   */
  protected EList eMessages = null;

  /**
   * The cached value of the '{@link #getEPortTypes() <em>EPort Types</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEPortTypes()
   * @generated
   * @ordered
   */
  protected EList ePortTypes = null;

  /**
   * The cached value of the '{@link #getEBindings() <em>EBindings</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEBindings()
   * @generated
   * @ordered
   */
  protected EList eBindings = null;

  /**
   * The cached value of the '{@link #getEServices() <em>EServices</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEServices()
   * @generated
   * @ordered
   */
  protected EList eServices = null;

  /**
   * The cached value of the '{@link #getENamespaces() <em>ENamespaces</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getENamespaces()
   * @generated
   * @ordered
   */
  protected EList eNamespaces = null;

  private ExtensionRegistry extensionRegistry;

  private Document document;

  private HashMap namespaces = new HashMap();

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  protected DefinitionImpl()
  {
    super();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  protected EClass eStaticClass()
  {
    return WSDLPackage.Literals.DEFINITION;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public String getTargetNamespace()
  {
    return targetNamespace;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setTargetNamespace(String newTargetNamespace)
  {
    String oldTargetNamespace = targetNamespace;
    targetNamespace = newTargetNamespace;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.DEFINITION__TARGET_NAMESPACE, oldTargetNamespace, targetNamespace));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public String getLocation()
  {
    return location;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setLocation(String newLocation)
  {
    String oldLocation = location;
    location = newLocation;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.DEFINITION__LOCATION, oldLocation, location));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public QName getQName()
  {
    return qName;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setQName(QName newQName)
  {
    QName oldQName = qName;
    qName = newQName;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.DEFINITION__QNAME, oldQName, qName));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public String getEncoding()
  {
    return encoding;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setEncoding(String newEncoding)
  {
    String oldEncoding = encoding;
    encoding = newEncoding;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.DEFINITION__ENCODING, oldEncoding, encoding));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList getEMessages()
  {
    if (eMessages == null)
    {
      eMessages = new EObjectContainmentEList(Message.class, this, WSDLPackage.DEFINITION__EMESSAGES);
    }
    return eMessages;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList getEPortTypes()
  {
    if (ePortTypes == null)
    {
      ePortTypes = new EObjectContainmentEList(PortType.class, this, WSDLPackage.DEFINITION__EPORT_TYPES);
    }
    return ePortTypes;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList getEBindings()
  {
    if (eBindings == null)
    {
      eBindings = new EObjectContainmentEList(Binding.class, this, WSDLPackage.DEFINITION__EBINDINGS);
    }
    return eBindings;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList getEServices()
  {
    if (eServices == null)
    {
      eServices = new EObjectContainmentEList(Service.class, this, WSDLPackage.DEFINITION__ESERVICES);
    }
    return eServices;
  }

  /**
   * <!-- begin-user-doc -->
   * @deprecated
   * <!-- end-user-doc -->
   * @generated
   */
  public EList getENamespaces()
  {
    if (eNamespaces == null)
    {
      eNamespaces = new EObjectContainmentEList(Namespace.class, this, WSDLPackage.DEFINITION__ENAMESPACES);
    }
    return eNamespaces;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public Types getETypes()
  {
    return eTypes;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public NotificationChain basicSetETypes(Types newETypes, NotificationChain msgs)
  {
    Types oldETypes = eTypes;
    eTypes = newETypes;
    if (eNotificationRequired())
    {
      ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, WSDLPackage.DEFINITION__ETYPES, oldETypes, newETypes);
      if (msgs == null)
        msgs = notification;
      else
        msgs.add(notification);
    }
    return msgs;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setETypes(Types newETypes)
  {
    if (newETypes != eTypes)
    {
      NotificationChain msgs = null;
      if (eTypes != null)
        msgs = ((InternalEObject)eTypes).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - WSDLPackage.DEFINITION__ETYPES, null, msgs);
      if (newETypes != null)
        msgs = ((InternalEObject)newETypes).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - WSDLPackage.DEFINITION__ETYPES, null, msgs);
      msgs = basicSetETypes(newETypes, msgs);
      if (msgs != null)
        msgs.dispatch();
    }
    else if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.DEFINITION__ETYPES, newETypes, newETypes));
  }

  public void eNotify(Notification msg)
  {
    super.eNotify(msg);

    // cs.. if we've added a Types element, and this definition is already attached to a resource
    // we need to set the schemaLocations for any inline schemaLocations.
    // If not yet attached to a resource, the schemaLocation's will be set via WSDLResourceImpl.attached(EObject o)
    //
    if (msg.getFeature() == WSDLPackage.eINSTANCE.getDefinition_ETypes() && msg.getEventType() == Notification.SET)
    {
      if (eResource() instanceof WSDLResourceImpl && getEnclosingDefinition() != null)
      {
        setInlineSchemaLocations(eResource());
      }
    }
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList getEImports()
  {
    if (eImports == null)
    {
      eImports = new EObjectContainmentEList(Import.class, this, WSDLPackage.DEFINITION__EIMPORTS);
    }
    return eImports;
  }

  /**
   * <!-- begin-user-doc -->
   * Add a binding to this WSDL description.
   * @param binding the binding to be added
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void addBinding(javax.wsdl.Binding binding)
  {
    getEBindings().add((Binding)binding);
  }

  /**
   * <!-- begin-user-doc -->
   * Add an import to this WSDL description.
   * @param importDef the import to be added
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void addImport(javax.wsdl.Import importDef)
  {
    getEImports().add((Import)importDef);
  }

  /**
   * <!-- begin-user-doc -->
   * Add a message to this WSDL description.
   * @param message the message to be added
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void addMessage(javax.wsdl.Message message)
  {
    getEMessages().add((Message)message);
  }

  /**
   * <!-- begin-user-doc -->
   * This is a way to add a namespace association to a definition.
   * It is similar to adding a namespace prefix declaration to the
   * top of a &lt;wsdl:definition&gt; element. This has nothing to do
   * with the &lt;wsdl:import&gt; element; there are separate methods for
   * dealing with information described by &lt;wsdl:import&gt; elements.
   * There is a default namespace association (which can be
   * overridden) between the null prefix and
   * http://schemas.xmlsoap.org/wsdl/.
   * @param prefix the prefix to use for this namespace (when
   * rendering this information as XML). Use null or an empty string
   * to describe the default namespace (i.e. xmlns="...").
   * @param namespaceURI the namespace URI to associate the prefix
   * with. If you use null, the namespace association will be removed.
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void addNamespace(String prefix, String namespaceURI)
  {
    if (prefix == null)
      prefix = "";

    if (namespaceURI != null)
    {
      // First, check if there is this namespace already.
      String existingPrefix = getPrefix(namespaceURI);
      if (existingPrefix != null)
        return;

      // Make sure the prefix is not already used for a different namespace
      Map namespaces = getNamespaces();
      String existingNamespace = (String)namespaces.get(prefix);
      if (existingNamespace == null)
      {
        namespaces.put(prefix, namespaceURI);

        // Support for Namespace
        Namespace ens = WSDLFactory.eINSTANCE.createNamespace();
        ens.setPrefix(prefix);
        ens.setURI(namespaceURI);
        getENamespaces().add(ens);

        return;
      }

      // The prefix is taken already. Make a unique prefix
      if (prefix.endsWith("1"))
        prefix = prefix.substring(0, prefix.length() - 1);

      for (int i = 2;; i++)
      {
        String newPrefix = prefix + i;
        if (!namespaces.containsKey(newPrefix))
        {
          namespaces.put(newPrefix, namespaceURI);

          // Support for Namespace
          Namespace ens = WSDLFactory.eINSTANCE.createNamespace();
          ens.setPrefix(prefix);
          ens.setURI(namespaceURI);
          getENamespaces().add(ens);

          return;
        }
      }
    } // end if (namespaceURI != null)
    else
    {
      getNamespaces().remove(prefix);

      // Support for Namespace
      getENamespaces().remove(prefix);
    }
  }

  /**
   * <!-- begin-user-doc -->
   * Add a portType to this WSDL description.
   * @param portType the portType to be added
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void addPortType(javax.wsdl.PortType portType)
  {
    getEPortTypes().add((PortType)portType);
  }

  /**
   * <!-- begin-user-doc -->
   * Add a service to this WSDL description.
   * @param service the service to be added
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void addService(javax.wsdl.Service service)
  {
    getEServices().add((Service)service);
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new binding fault.
   * @return the newly created binding fault
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public BindingFault createBindingFault()
  {
    javax.wsdl.BindingFault bindingFault = WSDLFactoryImpl.eINSTANCE.createBindingFault();
    return bindingFault;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new binding input.
   * @return the newly created binding input
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public BindingInput createBindingInput()
  {
    javax.wsdl.BindingInput bindingInput = WSDLFactoryImpl.eINSTANCE.createBindingInput();
    return bindingInput;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new binding output.
   * @return the newly created binding output
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public BindingOutput createBindingOutput()
  {
    javax.wsdl.BindingOutput bindingOutput = WSDLFactoryImpl.eINSTANCE.createBindingOutput();
    return bindingOutput;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new binding operation.
   * @return the newly created binding operation
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public BindingOperation createBindingOperation()
  {
    javax.wsdl.BindingOperation bindingOperation = WSDLFactoryImpl.eINSTANCE.createBindingOperation();
    return bindingOperation;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new binding.
   * @return the newly created binding
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Binding createBinding()
  {
    javax.wsdl.Binding binding = WSDLFactoryImpl.eINSTANCE.createBinding();
    binding.setUndefined(true);
    return binding;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new fault.
   * @return the newly created fault
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Fault createFault()
  {
    javax.wsdl.Fault fault = WSDLFactoryImpl.eINSTANCE.createFault();
    return fault;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new import.
   * @return the newly created import
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Import createImport()
  {
    javax.wsdl.Import importDef = WSDLFactoryImpl.eINSTANCE.createImport();
    return importDef;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new input.
   * @return the newly created input
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Input createInput()
  {
    javax.wsdl.Input input = WSDLFactoryImpl.eINSTANCE.createInput();
    return input;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new message.
   * @return the newly created message
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Message createMessage()
  {
    javax.wsdl.Message message = WSDLFactoryImpl.eINSTANCE.createMessage();
    message.setUndefined(true);
    return message;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new operation.
   * @return the newly created operation
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Operation createOperation()
  {
    javax.wsdl.Operation operation = WSDLFactoryImpl.eINSTANCE.createOperation();
    operation.setUndefined(true);
    return operation;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new output.
   * @return the newly created output
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Output createOutput()
  {
    javax.wsdl.Output output = WSDLFactoryImpl.eINSTANCE.createOutput();
    return output;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new part.
   * @return the newly created part
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Part createPart()
  {
    javax.wsdl.Part part = WSDLFactoryImpl.eINSTANCE.createPart();
    return part;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new port.
   * @return the newly created port
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Port createPort()
  {
    javax.wsdl.Port port = WSDLFactoryImpl.eINSTANCE.createPort();
    return port;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new port type.
   * @return the newly created port type
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.PortType createPortType()
  {
    javax.wsdl.PortType portType = WSDLFactoryImpl.eINSTANCE.createPortType();
    portType.setUndefined(true);
    return portType;
  }

  /**
   * <!-- begin-user-doc -->
   * Create a new service.
   * @return the newly created service
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Service createService()
  {
    javax.wsdl.Service service = WSDLFactoryImpl.eINSTANCE.createService();
    return service;
  }

  /**
   * <!-- begin-user-doc -->
   * Get the specified binding. Also checks imported documents.
   * @param name the name of the desired binding.
   * @return the corresponding binding, or null if there wasn't
   * any matching binding
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Binding getBinding(QName name)
  {
    return (javax.wsdl.Binding)resolveWSDLElement(WSDLConstants.BINDING, name, this);
  }

  /**
   * <!-- begin-user-doc -->
   * Get all the bindings defined here.
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Map getBindings()
  {
    return createMap(WSDLConstants.BINDING, getEBindings());
  }

  /**
   * <!-- begin-user-doc -->
   * Get a map of lists containing all the imports defined here.
   * The map's keys are the namespaceURIs, and the map's values
   * are lists. There is one list for each namespaceURI for which
   * imports have been defined.
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Map getImports()
  {
    HashMap map = new HashMap();
    for (Iterator i = getEImports().iterator(); i.hasNext();)
    {
      Import theImport = (Import)i.next();
      String key = theImport.getNamespaceURI();
      if (key == null)
      {
        key = "";
      }

      List list = null;
      if (map.containsKey(key))
      {
        list = (List)map.get(key);
        list.add(theImport);
      }
      else
      {
        list = new ArrayList();
        list.add(theImport);
      }
      map.put(key, list);
    }
    return map;
  }

  /**
   * <!-- begin-user-doc -->
   * Get the list of imports for the specified namespaceURI.
   * @param namespaceURI the namespaceURI associated with the
   * desired imports.
   * @return a list of the corresponding imports
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public List getImports(String namespaceURI)
  {
    List list = new ArrayList();
    for (Iterator i = getEImports().iterator(); i.hasNext();)
    {
      Import theImport = (Import)i.next();
      if (WSDLConstants.isMatchingNamespace(namespaceURI, theImport.getNamespaceURI()))
      {
        list.add(theImport);
      }
    }
    return list;
  }

  /**
   * <!-- begin-user-doc -->
   * Get the specified message. Also checks imported documents.
   * @param name the name of the desired message.
   * @return the corresponding message, or null if there wasn't
   * any matching message
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Message getMessage(QName name)
  {
    return (javax.wsdl.Message)resolveWSDLElement(WSDLConstants.MESSAGE, name, this);
  }

  /**
   * <!-- begin-user-doc -->
   * Get all the messages defined here.
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Map getMessages()
  {
    return createMap(WSDLConstants.MESSAGE, getEMessages());
  }

  /**
   * <!-- begin-user-doc -->
   * Get the namespace URI associated with this prefix. Or null if
   * there is no namespace URI associated with this prefix. This is
   * unrelated to the &lt;wsdl:import&gt; element.
   * @see #addNamespace(String, String)
   * @see #getPrefix(String)
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public String getNamespace(String prefix)
  {
    return (String)getNamespaces().get(prefix);
  }

  /**
   * <!-- begin-user-doc -->
   * Get all namespace associations in this definition. The keys are
   * the prefixes, and the namespace URIs are the values. This is
   * unrelated to the &lt;wsdl:import&gt; element.
   * @see #addNamespace(String, String)
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Map getNamespaces()
  {
    return namespaces;
  }

  /**
   * <!-- begin-user-doc -->
   * Get the specified portType. Also checks imported documents.
   * @param name the name of the desired portType.
   * @return the corresponding portType, or null if there wasn't
   * any matching portType
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.PortType getPortType(QName name)
  {
    return (javax.wsdl.PortType)resolveWSDLElement(WSDLConstants.PORT_TYPE, name, this);
  }

  /**
   * <!-- begin-user-doc -->
   * Get all the portTypes defined here.
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Map getPortTypes()
  {
    return createMap(WSDLConstants.PORT_TYPE, getEPortTypes());
  }

  /**
   * <!-- begin-user-doc -->
   * Get a prefix associated with this namespace URI. Or null if
   * there are no prefixes associated with this namespace URI. This is
   * unrelated to the &lt;wsdl:import&gt; element.
   * @see #addNamespace(String, String)
   * @see #getNamespace(String)
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public String getPrefix(String namespaceURI)
  {
    if (namespaceURI == null)
      return null;

    Iterator entryIterator = getNamespaces().entrySet().iterator();
    while (entryIterator.hasNext())
    {
      Map.Entry entry = (Map.Entry)entryIterator.next();
      String prefix = (String)entry.getKey();
      String assocNamespaceURI = (String)entry.getValue();

      if (namespaceURI.equals(assocNamespaceURI) && prefix != "") // default namespace
        return prefix;
    }
    return null;
  }

  /**
   * <!-- begin-user-doc -->
   * Get the specified service. Also checks imported documents.
   * @param name the name of the desired service.
   * @return the corresponding service, or null if there wasn't
   * any matching service
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Service getService(QName name)
  {
    return (javax.wsdl.Service)resolveWSDLElement(WSDLConstants.SERVICE, name, this);
  }

  /**
   * <!-- begin-user-doc -->
   * Get all the services defined here.
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Map getServices()
  {
    return createMap(WSDLConstants.SERVICE, getEServices());
  }

  /**
   * <!-- begin-user-doc -->
   * Get a reference to the ExtensionRegistry for this Definition.
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public ExtensionRegistry getExtensionRegistry()
  {
    return extensionRegistry;
  }

  /**
   * <!-- begin-user-doc -->
   * Set the ExtensionRegistry for this Definition.
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void setExtensionRegistry(ExtensionRegistry extensionRegistry)
  {
    this.extensionRegistry = extensionRegistry;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public String getDocumentBaseURI()
  {
    return getLocation();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void setDocumentBaseURI(String documentBase)
  {
    setLocation(documentBase);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Types createTypes()
  {
    javax.wsdl.Types types = WSDLFactoryImpl.eINSTANCE.createTypes();
    return types;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Service removeService(QName name)
  {
    return (javax.wsdl.Service)getServices().remove(name);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Binding removeBinding(QName name)
  {
    return (javax.wsdl.Binding)getBindings().remove(name);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.PortType removePortType(QName name)
  {
    return (javax.wsdl.PortType)getPortTypes().remove(name);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Message removeMessage(QName name)
  {
    return (javax.wsdl.Message)getMessages().remove(name);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Types getTypes()
  {
    return getETypes();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void setTypes(javax.wsdl.Types types)
  {
    setETypes((Types)types);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs)
  {
    switch (featureID)
    {
      case WSDLPackage.DEFINITION__EIMPORTS:
      return ((InternalEList)getEImports()).basicRemove(otherEnd, msgs);
      case WSDLPackage.DEFINITION__ETYPES:
      return basicSetETypes(null, msgs);
      case WSDLPackage.DEFINITION__EMESSAGES:
      return ((InternalEList)getEMessages()).basicRemove(otherEnd, msgs);
      case WSDLPackage.DEFINITION__EPORT_TYPES:
      return ((InternalEList)getEPortTypes()).basicRemove(otherEnd, msgs);
      case WSDLPackage.DEFINITION__EBINDINGS:
      return ((InternalEList)getEBindings()).basicRemove(otherEnd, msgs);
      case WSDLPackage.DEFINITION__ESERVICES:
      return ((InternalEList)getEServices()).basicRemove(otherEnd, msgs);
      case WSDLPackage.DEFINITION__ENAMESPACES:
      return ((InternalEList)getENamespaces()).basicRemove(otherEnd, msgs);
    }
    return super.eInverseRemove(otherEnd, featureID, msgs);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public Object eGet(int featureID, boolean resolve, boolean coreType)
  {
    switch (featureID)
    {
      case WSDLPackage.DEFINITION__TARGET_NAMESPACE:
      return getTargetNamespace();
      case WSDLPackage.DEFINITION__LOCATION:
      return getLocation();
      case WSDLPackage.DEFINITION__QNAME:
      return getQName();
      case WSDLPackage.DEFINITION__ENCODING:
      return getEncoding();
      case WSDLPackage.DEFINITION__EIMPORTS:
      return getEImports();
      case WSDLPackage.DEFINITION__ETYPES:
      return getETypes();
      case WSDLPackage.DEFINITION__EMESSAGES:
      return getEMessages();
      case WSDLPackage.DEFINITION__EPORT_TYPES:
      return getEPortTypes();
      case WSDLPackage.DEFINITION__EBINDINGS:
      return getEBindings();
      case WSDLPackage.DEFINITION__ESERVICES:
      return getEServices();
      case WSDLPackage.DEFINITION__ENAMESPACES:
      return getENamespaces();
    }
    return super.eGet(featureID, resolve, coreType);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void eSet(int featureID, Object newValue)
  {
    switch (featureID)
    {
      case WSDLPackage.DEFINITION__TARGET_NAMESPACE:
      setTargetNamespace((String)newValue);
      return;
      case WSDLPackage.DEFINITION__LOCATION:
      setLocation((String)newValue);
      return;
      case WSDLPackage.DEFINITION__QNAME:
      setQName((QName)newValue);
      return;
      case WSDLPackage.DEFINITION__ENCODING:
      setEncoding((String)newValue);
      return;
      case WSDLPackage.DEFINITION__EIMPORTS:
      getEImports().clear();
      getEImports().addAll((Collection)newValue);
      return;
      case WSDLPackage.DEFINITION__ETYPES:
      setETypes((Types)newValue);
      return;
      case WSDLPackage.DEFINITION__EMESSAGES:
      getEMessages().clear();
      getEMessages().addAll((Collection)newValue);
      return;
      case WSDLPackage.DEFINITION__EPORT_TYPES:
      getEPortTypes().clear();
      getEPortTypes().addAll((Collection)newValue);
      return;
      case WSDLPackage.DEFINITION__EBINDINGS:
      getEBindings().clear();
      getEBindings().addAll((Collection)newValue);
      return;
      case WSDLPackage.DEFINITION__ESERVICES:
      getEServices().clear();
      getEServices().addAll((Collection)newValue);
      return;
      case WSDLPackage.DEFINITION__ENAMESPACES:
      getENamespaces().clear();
      getENamespaces().addAll((Collection)newValue);
      return;
    }
    super.eSet(featureID, newValue);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void eUnset(int featureID)
  {
    switch (featureID)
    {
      case WSDLPackage.DEFINITION__TARGET_NAMESPACE:
      setTargetNamespace(TARGET_NAMESPACE_EDEFAULT);
      return;
      case WSDLPackage.DEFINITION__LOCATION:
      setLocation(LOCATION_EDEFAULT);
      return;
      case WSDLPackage.DEFINITION__QNAME:
      setQName(QNAME_EDEFAULT);
      return;
      case WSDLPackage.DEFINITION__ENCODING:
      setEncoding(ENCODING_EDEFAULT);
      return;
      case WSDLPackage.DEFINITION__EIMPORTS:
      getEImports().clear();
      return;
      case WSDLPackage.DEFINITION__ETYPES:
      setETypes((Types)null);
      return;
      case WSDLPackage.DEFINITION__EMESSAGES:
      getEMessages().clear();
      return;
      case WSDLPackage.DEFINITION__EPORT_TYPES:
      getEPortTypes().clear();
      return;
      case WSDLPackage.DEFINITION__EBINDINGS:
      getEBindings().clear();
      return;
      case WSDLPackage.DEFINITION__ESERVICES:
      getEServices().clear();
      return;
      case WSDLPackage.DEFINITION__ENAMESPACES:
      getENamespaces().clear();
      return;
    }
    super.eUnset(featureID);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public boolean eIsSet(int featureID)
  {
    switch (featureID)
    {
      case WSDLPackage.DEFINITION__TARGET_NAMESPACE:
      return TARGET_NAMESPACE_EDEFAULT == null ? targetNamespace != null : !TARGET_NAMESPACE_EDEFAULT.equals(targetNamespace);
      case WSDLPackage.DEFINITION__LOCATION:
      return LOCATION_EDEFAULT == null ? location != null : !LOCATION_EDEFAULT.equals(location);
      case WSDLPackage.DEFINITION__QNAME:
      return QNAME_EDEFAULT == null ? qName != null : !QNAME_EDEFAULT.equals(qName);
      case WSDLPackage.DEFINITION__ENCODING:
      return ENCODING_EDEFAULT == null ? encoding != null : !ENCODING_EDEFAULT.equals(encoding);
      case WSDLPackage.DEFINITION__EIMPORTS:
      return eImports != null && !eImports.isEmpty();
      case WSDLPackage.DEFINITION__ETYPES:
      return eTypes != null;
      case WSDLPackage.DEFINITION__EMESSAGES:
      return eMessages != null && !eMessages.isEmpty();
      case WSDLPackage.DEFINITION__EPORT_TYPES:
      return ePortTypes != null && !ePortTypes.isEmpty();
      case WSDLPackage.DEFINITION__EBINDINGS:
      return eBindings != null && !eBindings.isEmpty();
      case WSDLPackage.DEFINITION__ESERVICES:
      return eServices != null && !eServices.isEmpty();
      case WSDLPackage.DEFINITION__ENAMESPACES:
      return eNamespaces != null && !eNamespaces.isEmpty();
    }
    return super.eIsSet(featureID);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Document getDocument()
  {
    return document;
  }

  /**
   * <!-- begin-user-doc -->
   * Sets the owner document.
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void setDocument(Document document)
  {
    this.document = document;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public String toString()
  {
    if (eIsProxy())
      return super.toString();

    StringBuffer result = new StringBuffer(super.toString());
    result.append(" (targetNamespace: "); //$NON-NLS-1$
    result.append(targetNamespace);
    result.append(", location: "); //$NON-NLS-1$
    result.append(location);
    result.append(", qName: "); //$NON-NLS-1$
    result.append(qName);
    result.append(", encoding: "); //$NON-NLS-1$
    result.append(encoding);
    result.append(')');
    return result.toString();
  }

  //
  // Hand-coded methods
  //

  protected static ResourceSet globalResourceSet;

  public static synchronized ResourceSet getGlobalResourceSet()
  {
    if (globalResourceSet == null)
    {
      globalResourceSet = createResourceSet();
      //String baseURL = WSDLPlugin.INSTANCE.getBaseURL().toString();
      //System.out.println("Base URL is: " + baseURL);
    }

    return globalResourceSet;
  }

  public static ResourceSet createResourceSet()
  {
    ResourceSet result = new ResourceSetImpl();
    result.getResourceFactoryRegistry().getExtensionToFactoryMap().put("wsdl", new WSDLResourceFactoryImpl()); //$NON-NLS-1$
    return result;
  }

  public static Definition createDefinition(Node node)
  {
    return createDefinition(node, null);
  }

  public static Definition createDefinition(Node node, String location)
  {
    return createDefinition(node, location, true);
  }

  public static Definition createDefinition(Node node, String location, boolean useExtensionFactories)
  {
    Definition definition = WSDLFactory.eINSTANCE.createDefinition();
    ((DefinitionImpl)definition).setUseExtensionFactories(useExtensionFactories);
    definition.setElement((Element)node);
    definition.setDocumentBaseURI(location);
    return definition;
  }

  private WSDLElement resolveWSDLElement(int type, List list, QName qname)
  {
    WSDLElement result = null;
    if (qname != null)
    {
      for (Iterator i = list.iterator(); i.hasNext();)
      {
        WSDLElement wsdlElement = (WSDLElement)i.next();
        QName theQName = getQNameForWSDLElement(type, wsdlElement);
        if (qname.equals(theQName))
        {
          result = wsdlElement;
          break;
        }
      }
    }
    return result;
  }

  private HashMap createMap(int type, List list)
  {
    HashMap map = new HashMap();
    for (Iterator i = list.iterator(); i.hasNext();)
    {
      WSDLElement wsdlElement = (WSDLElement)i.next();
      QName theQName = getQNameForWSDLElement(type, wsdlElement);
      if (theQName != null)
      {
        map.put(theQName, wsdlElement);
      }
    }
    return map;
  }

  private QName getQNameForWSDLElement(int type, WSDLElement wsdlElement)
  {
    QName result = null;
    switch (type)
    {
      case WSDLConstants.MESSAGE:
      result = ((Message)wsdlElement).getQName();
        break;
      case WSDLConstants.PORT_TYPE:
      result = ((PortType)wsdlElement).getQName();
        break;
      case WSDLConstants.BINDING:
      result = ((Binding)wsdlElement).getQName();
        break;
      case WSDLConstants.SERVICE:
      result = ((Service)wsdlElement).getQName();
        break;
    }
    return result;
  }

  /**
   * Resolves the element described by type and qname in the context of the
   * given definition. The definition's imported definitions are checked as well.
   * 
   * @param type the element type.
   * @param qname the element's QName. Must not be null.
   * @param definition the context definition. Must not be null.
   * @return the resolved WSDLElement or null if one cannot be found.
   */
  private static WSDLElement resolveWSDLElement(int type, QName qname, DefinitionImpl definition)
  {
    if (qname == null || qname.getNamespaceURI() == null)
    {
      return null;
    }

    List definitions = new ArrayList();
    definitions.add(definition);
    WSDLElement result = resolveWSDLElement(type, qname, definitions, new ArrayList());

    return result;
  }

  /**
   * Resolves the element described by type and qname in the context of the
   * given definitions. The definitions imported definitions are checked as well.
   * 
   * IMPORTANT! This method is recursive. It checks the definitions and all their
   * imported definitions. It also is coded such that it avoids a cyclic import
   * should one be encountered.
   * 
   * @param type the element type.
   * @param qname the element's qName.
   * @param definitions the context definitions
   * @param visitedDefinitions a list with the definitions already visited.
   * @return the resolved WSDLElement or null if one cannot be found.
   */
  private static WSDLElement resolveWSDLElement(int type, QName qname, List definitions, List visitedDefinitions)
  {
    WSDLElement result = null;

    if (definitions.isEmpty())
    {
      return result;
    }

    // In order to preserve the old behaviour which used to check the definition
    // and all first level imports, check the entire list of definitions passed
    // in first.

    Iterator definitionsIterator = definitions.iterator();

    while (definitionsIterator.hasNext())
    {
      DefinitionImpl definition = (DefinitionImpl)definitionsIterator.next();

      result = definition.resolveWSDLElement(type, qname);

      if (result != null)
      {
        return result;
      }
    }

    // Re-iterate over the definitions and recurse into their imports.

    definitionsIterator = definitions.iterator();

    while (definitionsIterator.hasNext())
    {
      DefinitionImpl definition = (DefinitionImpl)definitionsIterator.next();

      if (visitedDefinitions.contains(definition))
      {
        // This might happen if we have a case of cyclic imports. Since we
        // already looked in it, we can and should skip it.

        continue;
      }

      visitedDefinitions.add(definition);

      List importedDefinitions = definition.getImportedDefinitions(qname.getNamespaceURI());

      result = resolveWSDLElement(type, qname, importedDefinitions, visitedDefinitions);

      if (result != null)
      {
        break;
      }
    }

    return result;
  }

  private WSDLElement resolveWSDLElement(int type, QName qname)
  {
    WSDLElement result = null;
    if (qname.getNamespaceURI() != null)
    {
      switch (type)
      {
        case WSDLConstants.MESSAGE:
        result = resolveWSDLElement(type, getEMessages(), qname);
          break;
        case WSDLConstants.PORT_TYPE:
        result = resolveWSDLElement(type, getEPortTypes(), qname);
          break;
        case WSDLConstants.BINDING:
        result = resolveWSDLElement(type, getEBindings(), qname);
          break;
        case WSDLConstants.SERVICE:
        result = resolveWSDLElement(type, getEServices(), qname);
          break;
      }
    }
    return result;
  }

  //
  // Reconciliation methods
  //

  public void setElement(Element element)
  {
    Element oldElement = getElement();
    if (oldElement instanceof EventTarget)
    {
      EventTarget oldEventTarget = ((EventTarget)oldElement);
      oldEventTarget.removeEventListener("DOMNodeInserted", getEventListener(), true); //$NON-NLS-1$
      oldEventTarget.removeEventListener("DOMNodeRemoved", getEventListener(), true); //$NON-NLS-1$
      oldEventTarget.removeEventListener("DOMAttrModified", getEventListener(), true); //$NON-NLS-1$
    }
    super.setElement(element);
    if (element instanceof EventTarget)
    {
      EventTarget eventTarget = ((EventTarget)element);
      eventTarget.addEventListener("DOMNodeInserted", getEventListener(), true); //$NON-NLS-1$
      eventTarget.addEventListener("DOMNodeRemoved", getEventListener(), true); //$NON-NLS-1$
      eventTarget.addEventListener("DOMAttrModified", getEventListener(), true); //$NON-NLS-1$
    }
    if (element != null)
    {
      document = element.getOwnerDocument();
    }
  }

  protected void reconcileAttributes(Element changedElement)
  {
    super.reconcileAttributes(changedElement);

    if (changedElement == getElement())
    {
      if (changedElement.hasAttribute(WSDLConstants.TARGETNAMESPACE_ATTRIBUTE))
        setTargetNamespace(changedElement.getAttribute(WSDLConstants.TARGETNAMESPACE_ATTRIBUTE));
      if (changedElement.hasAttribute(WSDLConstants.NAME_ATTRIBUTE))
        setQName(new QName(WSDLConstants.WSDL_NAMESPACE_URI, changedElement.getAttribute(WSDLConstants.NAME_ATTRIBUTE)));
      getENamespaces().clear();
      getNamespaces().clear();
      //getNamespaces().put("", null);

      NamedNodeMap map = changedElement.getAttributes();
      int mapLength = map.getLength();
      for (int i = 0; i < mapLength; i++)
      {
        Attr attr = (Attr)map.item(i);
        String nsPrefix = null;
        if (XMLNS.equals(attr.getPrefix()))
        {
          nsPrefix = attr.getLocalName();
        }
        else if (XMLNS.equals(attr.getNodeName()))
        {
          nsPrefix = "";
        }

        if (nsPrefix != null)
        {
          getNamespaces().put(nsPrefix, attr.getValue());
        }
      }
    }
  }

  public void handleUnreconciledElement(Element child, Collection remainingModelObjects)
  {
    switch (WSDLUtil.getInstance().getWSDLType(child))
    {
      case WSDLConstants.BINDING:
      {
        Binding binding = WSDLFactory.eINSTANCE.createBinding();
        binding.setEnclosingDefinition(this);
        binding.setElement(child);
        addBinding(binding);
        break;
      }
      case WSDLConstants.DOCUMENTATION:
      {
        // CS: we need to figure out how to unset this element when its removed
        //definition.setDocumentationElement(child);  
        break;
      }
      case WSDLConstants.IMPORT:
      {
        Import i = WSDLFactory.eINSTANCE.createImport();
        i.setEnclosingDefinition(this);
        i.setElement(child);
        addImport(i);
        break;
      }
      case WSDLConstants.MESSAGE:
      {
        Message message = WSDLFactory.eINSTANCE.createMessage();
        message.setEnclosingDefinition(this);
        message.setElement(child);
        addMessage(message);
        break;
      }
      case WSDLConstants.PORT_TYPE:
      {
        PortType portType = WSDLFactory.eINSTANCE.createPortType();
        portType.setEnclosingDefinition(this);
        portType.setElement(child);
        addPortType(portType);
        break;
      }
      case WSDLConstants.SERVICE:
      {
        Service service = WSDLFactoryImpl.eINSTANCE.createService();
        service.setEnclosingDefinition(this);
        service.setElement(child);
        addService(service);
        break;
      }
      case WSDLConstants.TYPES:
      {
        if (getETypes() == null)
        {
          Types types = WSDLFactoryImpl.eINSTANCE.createTypes();
          types.setEnclosingDefinition(this);
          types.setElement(child);
          setETypes(types);
        }
        break;
      }
      default:
      {
        ExtensibilityElement extensibilityElement = getUseExtensionFactories()
          ? ((WSDLFactoryImpl)WSDLFactory.eINSTANCE).createExtensibilityElement(getNamespace(child), getLocalName(child))
          : ((WSDLFactoryImpl)WSDLFactory.eINSTANCE).createUnknownExtensibilityElement();

        extensibilityElement.setEnclosingDefinition(this);
        extensibilityElement.setElement(child);
        getEExtensibilityElements().add(extensibilityElement);
        break;
      }
    }
  }

  protected void handleReconciliation(Collection remainingModelObjects)
  {
    for (Iterator i = remainingModelObjects.iterator(); i.hasNext();)
    {
      remove(this, i.next());
    }
    reconcileReferences(true);
  }

  protected void remove(Object component, Object modelObject)
  {
    if (modelObject instanceof Types)
    {
      Definition definition = (Definition)component;
      if (definition.getETypes() == modelObject)
      {
        definition.setETypes(null);
      }
    }
    else
    {
      List list = getList(component, modelObject);
      if (list != null)
      {
        list.remove(modelObject);
      }
    }
  }

  private List getList(Object component, Object modelObject)
  {
    List result = null;
    Definition definition = (Definition)component;

    // todo... use WSDLSwitch
    //
    if (modelObject instanceof Binding)
    {
      result = definition.getEBindings();
    }
    else if (modelObject instanceof Import)
    {
      result = definition.getEImports();
    }
    else if (modelObject instanceof Message)
    {
      result = definition.getEMessages();
    }
    else if (modelObject instanceof PortType)
    {
      result = definition.getEPortTypes();
    }
    else if (modelObject instanceof Service)
    {
      result = definition.getEServices();
    }
    else if (modelObject instanceof ExtensibilityElement)
    {
      result = definition.getEExtensibilityElements();
    }
    return result;
  }

  public Collection getModelObjects(Object component)
  {
    List list = new ArrayList();
    Definition definition = (Definition)component;
    list.addAll(definition.getEImports());
    list.add(definition.getETypes());
    list.addAll(definition.getEMessages());
    list.addAll(definition.getEPortTypes());
    list.addAll(definition.getEBindings());
    list.addAll(definition.getEServices());
    list.addAll(definition.getEExtensibilityElements());
    return list;
  }

  //
  // For reconciliation: Model -> DOM
  //

  public Document updateDocument()
  {
    document = createDocument();
    return document;
  }

  private Document createDocument()
  {
    try
    {
      DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
      documentBuilderFactory.setNamespaceAware(true);
      documentBuilderFactory.setValidating(false);
      DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
      return documentBuilder.newDocument();
    }
    catch (ParserConfigurationException exception)
    {
      WSDLPlugin.INSTANCE.log(exception);
      return null;
    }
  }

  public Element createElement()
  {
    Element newElement = createElement(WSDLConstants.DEFINITION);
    setElement(newElement);
    addChildElements(newElement, getEExtensibilityElements());

    addChildElements(newElement, getEImports());

    Types types = getETypes();
    if (types != null)
    {
      Element child = ((TypesImpl)types).createElement();
      newElement.appendChild(child);
    }

    addChildElements(newElement, getEMessages());
    addChildElements(newElement, getEPortTypes());
    addChildElements(newElement, getEBindings());
    addChildElements(newElement, getEServices());

    return newElement;
  }

  protected void addChildElements(Element parent, List c)
  {
    for (Iterator iterator = c.iterator(); iterator.hasNext();)
    {
      WSDLElementImpl wsdlElement = (WSDLElementImpl)iterator.next();
      Element child = wsdlElement.createElement();
      parent.appendChild(child);
    }
  }

  protected void changeReference(EReference eReference)
  {
    // Add namespace prefix info
    // TBD - Need to revisit.
    Element theElement = getElement();
    if (eReference == null && theElement != null)
    // We are updating the Definition element.
    {
      Iterator iterator = getNamespaces().entrySet().iterator();
      String prefix = null;
      String uri = null;
      while (iterator.hasNext())
      {
        Map.Entry entry = (Map.Entry)iterator.next();
        prefix = (String)entry.getKey();
        uri = (String)entry.getValue();
        if (prefix != "")
          theElement.setAttributeNS(XSDConstants.XMLNS_URI_2000, "xmlns:" + prefix, uri); //$NON-NLS-1$
        else if (uri != null)
          // Handle default namespace, e.g. xmlns="http://schemas.xmlsoap.org/wsdl/"
          theElement.setAttributeNS(XSDConstants.XMLNS_URI_2000, XMLNS, uri);
      }
    }
  }

  protected void changeAttribute(EAttribute eAttribute)
  {
    if (isReconciling)
      return;

    super.changeAttribute(eAttribute);
    Element theElement = getElement();
    if (theElement != null)
    {
      //if (eAttribute == null || eAttribute == WSDLPackage.eINSTANCE.getDefinition_Encoding())
      //  niceSetAttribute(theElement, WSDLConstants.ENCODING_ATTRIBUTE, getEncoding());
      if (eAttribute == null || eAttribute == WSDLPackage.eINSTANCE.getDefinition_QName())
        if (getQName() != null)
          niceSetAttribute(theElement, WSDLConstants.NAME_ATTRIBUTE, getQName().getLocalPart());
      if (eAttribute == null || eAttribute == WSDLPackage.eINSTANCE.getDefinition_TargetNamespace())
        if (getTargetNamespace() != null)
          niceSetAttribute(theElement, WSDLConstants.TARGETNAMESPACE_ATTRIBUTE, getTargetNamespace());
    }
  }

  private List getImportedDefinitions(String namespace)
  {
    List list = new ArrayList();

    for (Iterator i = getImports(namespace).iterator(); i.hasNext();)
    {
      Import theImport = (Import)i.next();
      ((ImportImpl)theImport).importDefinitionOrSchema();
      Definition importedDefinition = theImport.getEDefinition();
      if (importedDefinition != null && WSDLConstants.isMatchingNamespace(namespace, importedDefinition.getTargetNamespace()))
      {
        list.add(importedDefinition);
      }
    }

    return list;
  }

  public XSDElementDeclaration resolveElementDeclarationURI(String uri)
  {
    XSDElementDeclaration result = null;
    int index = uri.lastIndexOf("#");
    if (index != -1)
    {
      result = resolveElementDeclaration(uri.substring(0, index), uri.substring(index + 1));
    }
    return result;
  }

  private boolean isComponentDefined(XSDConcreteComponent component)
  {
    // note the getContainer() test to eliminate 'synthetic' types
    // that are created by the XMLSchema model when resolution fails   
    return component != null && component.getContainer() != null;
  }

  public XSDElementDeclaration resolveElementDeclaration(String namespace, String localName)
  {
    XSDElementDeclaration result = null;
    for (Iterator i = resolveSchema(namespace).iterator(); i.hasNext();)
    {
      XSDSchema schema = (XSDSchema)i.next();
      result = schema.resolveElementDeclaration(namespace, localName);
      if (isComponentDefined(result))
        return result;
    }

    // Could not resolve. Try against all <import>ed and inlined schemas.
    for (Iterator i = getImportedOrInlinedSchemas().iterator(); i.hasNext();)
    {
      XSDSchema schema = (XSDSchema)i.next();
      result = schema.resolveElementDeclaration(namespace, localName);
      if (isComponentDefined(result))
        return result;
    }

    return result;
  }

  public XSDTypeDefinition resolveTypeDefinitionURI(String uri)
  {
    XSDTypeDefinition result = null;
    int index = uri.lastIndexOf("#");
    if (index != -1)
    {
      result = resolveTypeDefinition(uri.substring(0, index), uri.substring(index + 1));
    }
    return result;
  }

  public XSDTypeDefinition resolveTypeDefinition(String namespace, String localName)
  {
    XSDTypeDefinition result = null;
    for (Iterator i = resolveSchema(namespace).iterator(); i.hasNext();)
    {
      XSDSchema schema = (XSDSchema)i.next();
      result = schema.resolveTypeDefinition(namespace, localName);
      if (isComponentDefined(result))
        return result;
    }

    // Could not resolve. Try against all <import>ed and inlined schemas.
    for (Iterator i = getImportedOrInlinedSchemas().iterator(); i.hasNext();)
    {
      XSDSchema schema = (XSDSchema)i.next();
      result = schema.resolveTypeDefinition(namespace, localName);
      if (isComponentDefined(result))
        return result;
    }

    return result; // Failed to resolve.
  }

  /**
   * This returns set of schemas with the given namespace as it's target namespace.
   */
  public Collection resolveSchema(String namespace)
  {
    if ("".equals(namespace))
    {
      namespace = null;
    }

    if (XSDConstants.isSchemaForSchemaNamespace(namespace))
    {
      return Collections.singleton(XSDSchemaImpl.getSchemaForSchema(namespace));
    }
    else if (XSDConstants.isSchemaInstanceNamespace(namespace))
    {
      return Collections.singleton(XSDSchemaImpl.getSchemaInstance(namespace));
    }
    else
    {
      return getImportedOrInlinedSchemas(namespace);
    }
  }

  protected List getImportedOrInlinedSchemas(String namespace)
  {
    if (namespace == null)
    {
      namespace = "";
    }

    List list = new ArrayList();
    for (Iterator i = getEImports().iterator(); i.hasNext();)
    {
      Import theImport = (Import)i.next();
      if (WSDLConstants.isMatchingNamespace(theImport.getNamespaceURI(), namespace))
      {
        ((ImportImpl)theImport).importDefinitionOrSchema();
        XSDSchema schema = theImport.getESchema();
        if (schema != null && WSDLConstants.isMatchingNamespace(schema.getTargetNamespace(), namespace))
        {
          list.add(schema);
        }
      }
    }
    if (getETypes() != null)
    {
      for (Iterator i = getETypes().getSchemas().iterator(); i.hasNext();)
      {
        XSDSchema schema = (XSDSchema)i.next();
        String targetNamespace = schema.getTargetNamespace();
        if (namespace.equals(targetNamespace))
        {
          list.add(schema);
        }

        for (Iterator j = schema.getContents().iterator(); j.hasNext();)
        {
          Object component = j.next();
          if (component instanceof XSDImport)
          {
            XSDImport theImport = (XSDImport)component;
            if (namespace.equals(theImport.getNamespace()))
            {
              ((XSDImportImpl)theImport).importSchema();
              XSDSchema importedSchema = theImport.getResolvedSchema();
              if (importedSchema != null)
              {
                list.add(importedSchema);
              }
            }
          }
        }

      }
    }
    return list;
  }

  private List getImportedOrInlinedSchemas()
  {
    List list = new ArrayList();
    for (Iterator i = getEImports().iterator(); i.hasNext();)
    {
      Import theImport = (Import)i.next();
      ((ImportImpl)theImport).importDefinitionOrSchema();
      XSDSchema schema = theImport.getESchema();
      if (schema != null)
        list.add(schema);
    }

    if (getETypes() != null)
    {
      list.addAll(getETypes().getSchemas());
    }
    return list;
  }

  protected EventListener eventListener;

  protected Node deletionNode;

  public Node getDeletionNode()
  {
    return deletionNode;
  }

  protected EventListener getEventListener()
  {
    if (eventListener == null)
    {
      eventListener = new EventListener()
        {
          public void handleEvent(Event event)
          {
            if (event instanceof MutationEvent)
            {
              MutationEvent mutationEvent = (MutationEvent)event;
              if (mutationEvent.getTarget() instanceof Node)
              {
                Node node = (Node)mutationEvent.getTarget();
                while (node.getNodeType() != Node.ELEMENT_NODE)
                {
                  node = node.getParentNode();
                }
                if (mutationEvent.getAttrChange() == 0)
                {
                  WSDLElementImpl listener = (WSDLElementImpl)getCorrespondingComponent(node.getParentNode());
                  if (listener != null)
                  {
                    if (event.getType().equals("DOMNodeRemoved")) //$NON-NLS-1$
                    {
                      deletionNode = (Node)event.getTarget();
                    }
                    listener.elementContentsChanged((Element)node.getParentNode());
                    deletionNode = null;
                  }
                }
                else
                {
                  WSDLElementImpl listener = (WSDLElementImpl)getCorrespondingComponent(node);
                  if (listener != null)
                  {
                    listener.elementAttributesChanged((Element)node);
                  }
                }
              }
            }
          }
        };
    }
    return eventListener;
  }

  public WSDLElement getCorrespondingComponent(Node node)
  {
    // We consider all parents so that they can handle other contained nodes that otherwise don't correspond to a component.
    //
    List parents = new ArrayList();

    if (node.getNodeType() == Node.ATTRIBUTE_NODE)
    {
      node = ((Attr)node).getOwnerElement();
    }
    else
    {
      // Skip ahead to an element.
      //
      for (Node scanNode = node; scanNode != null; scanNode = scanNode.getNextSibling())
      {
        if (scanNode.getNodeType() == Node.ELEMENT_NODE)
        {
          node = scanNode;
          break;
        }
      }

      // Skip back to an element.
      //
      for (Node scanNode = node; scanNode != null; scanNode = scanNode.getPreviousSibling())
      {
        if (scanNode.getNodeType() == Node.ELEMENT_NODE)
        {
          node = scanNode;
          break;
        }
      }
    }

    // Navigate out through the elements.
    //
    for (Node parent = node; parent != null; parent = parent.getParentNode())
    {
      if (parent.getNodeType() == Node.ELEMENT_NODE)
      {
        parents.add(parent);
      }
    }

    WSDLElement bestWSDLElement = getBestWSDLElement(parents);
    return bestWSDLElement;
  }

  //
  //
  //
  private boolean useExtensionFactories = true;

  public void setUseExtensionFactories(boolean value)
  {
    useExtensionFactories = value;
  }

  public boolean getUseExtensionFactories()
  {
    return useExtensionFactories;
  }

  // See Bug 5366
  public void removeAll()
  {
    try
    {
      isReconciling = true;
      document = null;
      element = null;
      getEServices().clear();
      getEBindings().clear();
      getEPortTypes().clear();
      getEMessages().clear();
      setETypes(null);
      getEImports().clear();
      getEExtensibilityElements().clear();
    }
    catch (Exception e)
    {

    }
    finally
    {
      isReconciling = false;
    }
  }

  public void setInlineSchemaLocations(Resource resource)
  {
    // Initialize the inline schemas location 
    Types types = this.getETypes();
    if (types != null)
    {
      Iterator iterator = types.getEExtensibilityElements().iterator();
      while(iterator.hasNext())
      {
        ExtensibilityElement extensibilityElement = (ExtensibilityElement)iterator.next();
        if (!(extensibilityElement instanceof XSDSchemaExtensibilityElement))
        {
          continue;
        }
        XSDSchemaExtensibilityElement el = (XSDSchemaExtensibilityElement) extensibilityElement;
        XSDSchema schema = el.getSchema();
        if (schema != null)
        {
          // We need this try-catch block in case we encounter an exception while attempting
          // to resolve the schema.  In the case of the WSDL Editor, we get a
          // 'cannot create part exception'......See eclipse bugzilla bug 89855
          try
          {
            schema.setSchemaLocation(resource.getURI().toString());
          }
          catch (Exception e)
          {

          }
        }
      }
    }
  }

} //DefinitionImpl
