/*******************************************************************************
 * Copyright (c) 2001, 2004 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.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

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.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
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.BindingFault;
import org.eclipse.wst.wsdl.BindingInput;
import org.eclipse.wst.wsdl.BindingOperation;
import org.eclipse.wst.wsdl.BindingOutput;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.ExtensibilityElement;
import org.eclipse.wst.wsdl.Operation;
import org.eclipse.wst.wsdl.PortType;
import org.eclipse.wst.wsdl.WSDLFactory;
import org.eclipse.wst.wsdl.WSDLPackage;
import org.eclipse.wst.wsdl.internal.util.WSDLUtil;
import org.eclipse.wst.wsdl.util.WSDLConstants;
import org.w3c.dom.Element;



/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Binding Operation</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.wsdl.impl.BindingOperationImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.wsdl.impl.BindingOperationImpl#getEOperation <em>EOperation</em>}</li>
 *   <li>{@link org.eclipse.wsdl.impl.BindingOperationImpl#getEBindingInput <em>EBinding Input</em>}</li>
 *   <li>{@link org.eclipse.wsdl.impl.BindingOperationImpl#getEBindingOutput <em>EBinding Output</em>}</li>
 *   <li>{@link org.eclipse.wsdl.impl.BindingOperationImpl#getEBindingFaults <em>EBinding Faults</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class BindingOperationImpl extends ExtensibleElementImpl implements BindingOperation
{
  /**
   * 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 #getName() <em>Name</em>}' attribute.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getName()
   * @generated
   * @ordered
   */
  protected static final String NAME_EDEFAULT = null;

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

  /**
   * The cached value of the '{@link #getEOperation() <em>EOperation</em>}' reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEOperation()
   * @generated
   * @ordered
   */
  protected Operation eOperation = null;

  /**
   * The cached value of the '{@link #getEBindingInput() <em>EBinding Input</em>}' containment reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEBindingInput()
   * @generated
   * @ordered
   */
  protected BindingInput eBindingInput = null;

  /**
   * The cached value of the '{@link #getEBindingOutput() <em>EBinding Output</em>}' containment reference.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEBindingOutput()
   * @generated
   * @ordered
   */
  protected BindingOutput eBindingOutput = null;

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

  private Map bindingFaults;

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

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

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

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setName(String newName)
  {
    String oldName = name;
    name = newName;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.BINDING_OPERATION__NAME, oldName, name));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public Operation getEOperation()
  {
    if (eOperation != null && eOperation.eIsProxy())
    {
      Operation oldEOperation = eOperation;
      eOperation = (Operation)eResolveProxy((InternalEObject)eOperation);
      if (eOperation != oldEOperation)
      {
        if (eNotificationRequired())
          eNotify(new ENotificationImpl(this, Notification.RESOLVE, WSDLPackage.BINDING_OPERATION__EOPERATION, oldEOperation, eOperation));
      }
    }
    return eOperation;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public Operation basicGetEOperation()
  {
    return eOperation;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setEOperation(Operation newEOperation)
  {
    Operation oldEOperation = eOperation;
    eOperation = newEOperation;
    if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.BINDING_OPERATION__EOPERATION, oldEOperation, eOperation));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public BindingInput getEBindingInput()
  {
    return eBindingInput;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public NotificationChain basicSetEBindingInput(BindingInput newEBindingInput, NotificationChain msgs)
  {
    BindingInput oldEBindingInput = eBindingInput;
    eBindingInput = newEBindingInput;
    if (eNotificationRequired())
    {
      ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, WSDLPackage.BINDING_OPERATION__EBINDING_INPUT, oldEBindingInput, newEBindingInput);
      if (msgs == null) msgs = notification; else msgs.add(notification);
    }
    return msgs;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setEBindingInput(BindingInput newEBindingInput)
  {
    if (newEBindingInput != eBindingInput)
    {
      NotificationChain msgs = null;
      if (eBindingInput != null)
        msgs = ((InternalEObject)eBindingInput).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - WSDLPackage.BINDING_OPERATION__EBINDING_INPUT, null, msgs);
      if (newEBindingInput != null)
        msgs = ((InternalEObject)newEBindingInput).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - WSDLPackage.BINDING_OPERATION__EBINDING_INPUT, null, msgs);
      msgs = basicSetEBindingInput(newEBindingInput, msgs);
      if (msgs != null) msgs.dispatch();
    }
    else if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.BINDING_OPERATION__EBINDING_INPUT, newEBindingInput, newEBindingInput));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public BindingOutput getEBindingOutput()
  {
    return eBindingOutput;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public NotificationChain basicSetEBindingOutput(BindingOutput newEBindingOutput, NotificationChain msgs)
  {
    BindingOutput oldEBindingOutput = eBindingOutput;
    eBindingOutput = newEBindingOutput;
    if (eNotificationRequired())
    {
      ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, WSDLPackage.BINDING_OPERATION__EBINDING_OUTPUT, oldEBindingOutput, newEBindingOutput);
      if (msgs == null) msgs = notification; else msgs.add(notification);
    }
    return msgs;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void setEBindingOutput(BindingOutput newEBindingOutput)
  {
    if (newEBindingOutput != eBindingOutput)
    {
      NotificationChain msgs = null;
      if (eBindingOutput != null)
        msgs = ((InternalEObject)eBindingOutput).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - WSDLPackage.BINDING_OPERATION__EBINDING_OUTPUT, null, msgs);
      if (newEBindingOutput != null)
        msgs = ((InternalEObject)newEBindingOutput).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - WSDLPackage.BINDING_OPERATION__EBINDING_OUTPUT, null, msgs);
      msgs = basicSetEBindingOutput(newEBindingOutput, msgs);
      if (msgs != null) msgs.dispatch();
    }
    else if (eNotificationRequired())
      eNotify(new ENotificationImpl(this, Notification.SET, WSDLPackage.BINDING_OPERATION__EBINDING_OUTPUT, newEBindingOutput, newEBindingOutput));
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList getEBindingFaults()
  {
    if (eBindingFaults == null)
    {
      eBindingFaults = new EObjectContainmentEList(BindingFault.class, this, WSDLPackage.BINDING_OPERATION__EBINDING_FAULTS);
    }
    return eBindingFaults;
  }

  /**
   * <!-- begin-user-doc -->
   * Add a fault binding.
   * @param fault the new fault binding
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void addBindingFault(javax.wsdl.BindingFault bindingFault)
  {
    getEBindingFaults().add((BindingFault)bindingFault);
  }

  /**
   * <!-- begin-user-doc -->
   * Get the specified fault binding.
   * @param name the name of the desired fault binding.
   * @return the corresponding fault binding, or null if there wasn't
   * any matching fault binding
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.BindingFault getBindingFault(String name)
  {
    BindingFault result = null;
    for (Iterator i = getEBindingFaults().iterator(); i.hasNext();)
    {
      BindingFault fault = (BindingFault) i.next();
      if (name.equals(fault.getName()))
      {
        result = fault;
        break;
      }
    }
    return result;
  }

  /**
   * <!-- begin-user-doc -->
   * Get all the fault bindings associated with this operation binding.
   * @return names of fault bindings
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public Map getBindingFaults()
  {
    HashMap hashMap = new HashMap();
    for (Iterator i = getEBindingFaults().iterator(); i.hasNext();)
    {
      BindingFault bindingFault = (BindingFault) i.next();
      hashMap.put(bindingFault.getName(), bindingFault);
    }
    return hashMap;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.Operation getOperation()
  {
    return getEOperation();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void setOperation(javax.wsdl.Operation operation)
  {
    setEOperation((Operation) operation);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.BindingInput getBindingInput()
  {
    return getEBindingInput();
  }

  /**
   * <!-- begin-user-doc -->
   * Set the input of this operation binding.
   * @param input the desired input
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void setBindingInput(javax.wsdl.BindingInput bindingInput)
  {
    setEBindingInput((BindingInput) bindingInput);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public javax.wsdl.BindingOutput getBindingOutput()
  {
    return getEBindingOutput();
  }

  /**
   * <!-- begin-user-doc -->
   * Set the output of this operation binding.
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public void setBindingOutput(javax.wsdl.BindingOutput bindingOutput)
  {
    setEBindingOutput((BindingOutput) bindingOutput);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain msgs)
  {
    if (featureID >= 0)
    {
      switch (eDerivedStructuralFeatureID(featureID, baseClass))
      {
        case WSDLPackage.BINDING_OPERATION__EEXTENSIBILITY_ELEMENTS:
          return ((InternalEList)getEExtensibilityElements()).basicRemove(otherEnd, msgs);
        case WSDLPackage.BINDING_OPERATION__EBINDING_INPUT:
          return basicSetEBindingInput(null, msgs);
        case WSDLPackage.BINDING_OPERATION__EBINDING_OUTPUT:
          return basicSetEBindingOutput(null, msgs);
        case WSDLPackage.BINDING_OPERATION__EBINDING_FAULTS:
          return ((InternalEList)getEBindingFaults()).basicRemove(otherEnd, msgs);
        default:
          return eDynamicInverseRemove(otherEnd, featureID, baseClass, msgs);
      }
    }
    return eBasicSetContainer(null, featureID, msgs);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public Object eGet(EStructuralFeature eFeature, boolean resolve)
  {
    switch (eDerivedStructuralFeatureID(eFeature))
    {
      case WSDLPackage.BINDING_OPERATION__DOCUMENTATION_ELEMENT:
        return getDocumentationElement();
      case WSDLPackage.BINDING_OPERATION__ELEMENT:
        return getElement();
      case WSDLPackage.BINDING_OPERATION__EEXTENSIBILITY_ELEMENTS:
        return getEExtensibilityElements();
      case WSDLPackage.BINDING_OPERATION__NAME:
        return getName();
      case WSDLPackage.BINDING_OPERATION__EOPERATION:
        if (resolve) return getEOperation();
        return basicGetEOperation();
      case WSDLPackage.BINDING_OPERATION__EBINDING_INPUT:
        return getEBindingInput();
      case WSDLPackage.BINDING_OPERATION__EBINDING_OUTPUT:
        return getEBindingOutput();
      case WSDLPackage.BINDING_OPERATION__EBINDING_FAULTS:
        return getEBindingFaults();
    }
    return eDynamicGet(eFeature, resolve);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void eSet(EStructuralFeature eFeature, Object newValue)
  {
    switch (eDerivedStructuralFeatureID(eFeature))
    {
      case WSDLPackage.BINDING_OPERATION__DOCUMENTATION_ELEMENT:
        setDocumentationElement((Element)newValue);
        return;
      case WSDLPackage.BINDING_OPERATION__ELEMENT:
        setElement((Element)newValue);
        return;
      case WSDLPackage.BINDING_OPERATION__EEXTENSIBILITY_ELEMENTS:
        getEExtensibilityElements().clear();
        getEExtensibilityElements().addAll((Collection)newValue);
        return;
      case WSDLPackage.BINDING_OPERATION__NAME:
        setName((String)newValue);
        return;
      case WSDLPackage.BINDING_OPERATION__EOPERATION:
        setEOperation((Operation)newValue);
        return;
      case WSDLPackage.BINDING_OPERATION__EBINDING_INPUT:
        setEBindingInput((BindingInput)newValue);
        return;
      case WSDLPackage.BINDING_OPERATION__EBINDING_OUTPUT:
        setEBindingOutput((BindingOutput)newValue);
        return;
      case WSDLPackage.BINDING_OPERATION__EBINDING_FAULTS:
        getEBindingFaults().clear();
        getEBindingFaults().addAll((Collection)newValue);
        return;
    }
    eDynamicSet(eFeature, newValue);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void eUnset(EStructuralFeature eFeature)
  {
    switch (eDerivedStructuralFeatureID(eFeature))
    {
      case WSDLPackage.BINDING_OPERATION__DOCUMENTATION_ELEMENT:
        setDocumentationElement(DOCUMENTATION_ELEMENT_EDEFAULT);
        return;
      case WSDLPackage.BINDING_OPERATION__ELEMENT:
        setElement(ELEMENT_EDEFAULT);
        return;
      case WSDLPackage.BINDING_OPERATION__EEXTENSIBILITY_ELEMENTS:
        getEExtensibilityElements().clear();
        return;
      case WSDLPackage.BINDING_OPERATION__NAME:
        setName(NAME_EDEFAULT);
        return;
      case WSDLPackage.BINDING_OPERATION__EOPERATION:
        setEOperation((Operation)null);
        return;
      case WSDLPackage.BINDING_OPERATION__EBINDING_INPUT:
        setEBindingInput((BindingInput)null);
        return;
      case WSDLPackage.BINDING_OPERATION__EBINDING_OUTPUT:
        setEBindingOutput((BindingOutput)null);
        return;
      case WSDLPackage.BINDING_OPERATION__EBINDING_FAULTS:
        getEBindingFaults().clear();
        return;
    }
    eDynamicUnset(eFeature);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public boolean eIsSet(EStructuralFeature eFeature)
  {
    switch (eDerivedStructuralFeatureID(eFeature))
    {
      case WSDLPackage.BINDING_OPERATION__DOCUMENTATION_ELEMENT:
        return DOCUMENTATION_ELEMENT_EDEFAULT == null ? documentationElement != null : !DOCUMENTATION_ELEMENT_EDEFAULT.equals(documentationElement);
      case WSDLPackage.BINDING_OPERATION__ELEMENT:
        return ELEMENT_EDEFAULT == null ? element != null : !ELEMENT_EDEFAULT.equals(element);
      case WSDLPackage.BINDING_OPERATION__EEXTENSIBILITY_ELEMENTS:
        return eExtensibilityElements != null && !eExtensibilityElements.isEmpty();
      case WSDLPackage.BINDING_OPERATION__NAME:
        return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
      case WSDLPackage.BINDING_OPERATION__EOPERATION:
        return eOperation != null;
      case WSDLPackage.BINDING_OPERATION__EBINDING_INPUT:
        return eBindingInput != null;
      case WSDLPackage.BINDING_OPERATION__EBINDING_OUTPUT:
        return eBindingOutput != null;
      case WSDLPackage.BINDING_OPERATION__EBINDING_FAULTS:
        return eBindingFaults != null && !eBindingFaults.isEmpty();
    }
    return eDynamicIsSet(eFeature);
  }

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

    StringBuffer result = new StringBuffer(super.toString());
    result.append(" (name: ");
    result.append(name);
    result.append(')');
    return result.toString();
  }

  //
  // Reconcile methods
  //

  public void reconcileAttributes(Element changedElement)
  {
    String name = changedElement.getAttribute("name");
    if (name != null)
    {
      setName(name);
    }
  }

  public void handleUnreconciledElement(Element child, Collection remainingModelObjects)
  {
    Definition definition = getEnclosingDefinition();

    switch (WSDLUtil.getInstance().getWSDLType(child))
    {
      case WSDLConstants.INPUT :
      {
        BindingInput input = WSDLFactory.eINSTANCE.createBindingInput();
        input.setEnclosingDefinition(definition);
        input.setElement(child);
        setBindingInput(input);
        break;
      }
      case WSDLConstants.OUTPUT :
      {
        BindingOutput output = WSDLFactory.eINSTANCE.createBindingOutput();
        output.setEnclosingDefinition(definition);
        output.setElement(child);
        setBindingOutput(output);
        break;
      }
      case WSDLConstants.FAULT :
      {
        BindingFault fault = WSDLFactory.eINSTANCE.createBindingFault();
        fault.setEnclosingDefinition(definition);
        fault.setElement(child);
        addBindingFault(fault);
        break;
      }
      default :
      {
        super.handleUnreconciledElement(child,remainingModelObjects);
        break;
      }
    }
  }

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

  protected void remove(Object component, Object modelObject)
  {
    BindingOperation bindingOperation = (BindingOperation) component;
    if (modelObject instanceof BindingInput)
    {
      bindingOperation.setEBindingInput(null);
    }
    else if (modelObject instanceof BindingOutput)
    {
      bindingOperation.setEBindingOutput(null);
    }
    else if (modelObject instanceof BindingFault)
    {
      bindingOperation.getEBindingFaults().remove(modelObject);
    }
    else
    {
      bindingOperation.getEExtensibilityElements().remove(modelObject);
    }
  }

  public Collection getModelObjects(Object component)
  {
    BindingOperation bindingOperation = (BindingOperation) component;

    List list = new ArrayList();

    if (bindingOperation.getEBindingInput() != null)
    {
      list.add(bindingOperation.getEBindingInput());
    }

    if (bindingOperation.getEBindingOutput() != null)
    {
      list.add(bindingOperation.getEBindingOutput());
    }

    list.addAll(bindingOperation.getEBindingFaults());
    list.addAll(bindingOperation.getEExtensibilityElements());

    return list;
  }

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

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

    super.changeAttribute(eAttribute);
    Element theElement = getElement();
    if (theElement != null)
    {
      if (eAttribute == null || eAttribute == WSDLPackage.eINSTANCE.getBindingOperation_Name())
        niceSetAttribute(theElement, WSDLConstants.NAME_ATTRIBUTE, getName());
    }
  }

  public Element createElement()
  {
    Element newElement = createElement(WSDLConstants.OPERATION);
    setElement(newElement);

	Iterator iterator = getExtensibilityElements().iterator();
    while (iterator.hasNext())
    {
      ExtensibilityElement extensibilityElement = (ExtensibilityElement) iterator.next();
      Element child = ((ExtensibilityElementImpl) extensibilityElement).createElement();
      newElement.appendChild(child);
    }
	
    BindingInput input = getEBindingInput();
    if (input != null)
    {
      Element child = ((BindingInputImpl) input).createElement();
      newElement.appendChild(child);
    }

    BindingOutput output = getEBindingOutput();
    if (output != null)
    {
      Element child = ((BindingOutputImpl) output).createElement();
      newElement.appendChild(child);
    }

    iterator = getEBindingFaults().iterator();
    while (iterator.hasNext())
    {
      BindingFault fault = (BindingFault) iterator.next();
      Element child = ((BindingFaultImpl) fault).createElement();
      newElement.appendChild(child);
    }

    return newElement;
  }
  
  // Resolve the reference to Operation
  public void reconcileReferences(boolean deep)
  {
    if (element != null)
    {
      Binding binding = (Binding)getContainer();
      PortType portType = binding.getEPortType();
      if (portType != null)
      {
        setOperation(portType.getOperation(getName(),null,null));
      }
    }
    super.reconcileReferences(deep);
  }
} //BindingOperationImpl
