/*******************************************************************************
 * 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.ui.internal.model;
        
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import javax.wsdl.OperationType;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.swt.graphics.Image;
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.ExtensibleElement;
import org.eclipse.wst.wsdl.Fault;
import org.eclipse.wst.wsdl.Import;
import org.eclipse.wst.wsdl.Input;
import org.eclipse.wst.wsdl.Message;
import org.eclipse.wst.wsdl.Operation;
import org.eclipse.wst.wsdl.Output;
import org.eclipse.wst.wsdl.Part;
import org.eclipse.wst.wsdl.Port;
import org.eclipse.wst.wsdl.PortType;
import org.eclipse.wst.wsdl.Service;
import org.eclipse.wst.wsdl.Types;
import org.eclipse.wst.wsdl.UnknownExtensibilityElement;
import org.eclipse.wst.wsdl.WSDLElement;
import org.eclipse.wst.wsdl.internal.impl.OperationImpl;
import org.eclipse.wst.wsdl.internal.util.WSDLSwitch;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditorPlugin;
import org.eclipse.wst.wsdl.ui.internal.extension.ITreeChildProvider;
import org.eclipse.wst.wsdl.ui.internal.util.WSDLEditorUtil;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class WSDLModelAdapterFactory implements ModelAdapterFactory
{                                      
  protected static WSDLModelAdapterFactory wsdlModelAdapterFactoryInstance;

  public AdapterFactory adapterFactory;
                       
  public WSDLModelAdapterFactory()
  {
    adapterFactory = createAdapterFactory();
  }   
                                                 
  protected boolean isExtensibilityElementConsideredChild()
  {
    return true;
  }

  protected void addExtensiblityElementChildren(List list, ExtensibleElement extensibleElement)
  {
    if (isExtensibilityElementConsideredChild())
    {
      //list.addAll(WSDLEditorUtil.getInstance().getExtensibilityElementNodes(extensibleElement));
      list.addAll(WSDLEditorUtil.getInstance().getExtensibilityElementNodes(extensibleElement));
    }
  }

  public static WSDLModelAdapterFactory getWSDLModelAdapterFactory()
  {                
    if (wsdlModelAdapterFactoryInstance == null)
    {
      wsdlModelAdapterFactoryInstance = new WSDLModelAdapterFactory();
    }
    return wsdlModelAdapterFactoryInstance;
  }  
    

  protected AdapterFactory createAdapterFactory()
  {
    return new WSDLAdapterFactoryImpl();
  }            


  public ModelAdapter getAdapter(Object o)
  {                             
    ModelAdapter adapter = null;
    if (o instanceof WSDLElement)                     
    {
      adapter = (ModelAdapter)adapterFactory.adapt((WSDLElement)o, adapterFactory);
    }
    else if (o instanceof WSDLGroupObject)
    {           
      adapter = (WSDLGroupObject)o;
    }
    return adapter;
  }                                    

  //
  //
  //
  public class WSDLAdapterFactoryImpl extends AdapterFactoryImpl
  {                     
    public Adapter createAdapter(Notifier target)
    {                     
      WSDLSwitch wsdlSwitch = new WSDLSwitch()
      {                   
      	public Object caseWSDLElement(WSDLElement wsdlElement)
        {   
          // note that the WSDLSwitch doesn't handle 
          // caseExtensibilityElement when the object
          // comes from another package... that why
          // we have an instanceof check here
		  if (wsdlElement instanceof ExtensibilityElement)
		  {	
			return createExtensibilityElementAdapter();  
		  }
		  else
		  {	  
            return createWSDLElementAdapter();
		  }	
	    }   

      	public Object caseBinding(Binding binding)
        {   
          return createBindingAdapter();
	      } 

      	public Object caseBindingFault(BindingFault bindingFault)
        {   
          return createBindingFaultAdapter();
	      } 

      	public Object caseBindingInput(BindingInput bindingInput)
        {   
          return createBindingInputAdapter();
	      } 

      	public Object caseBindingOutput(BindingOutput bindingOutput)
        {   
          return createBindingOutputAdapter();
	      } 
                           
      	public Object caseBindingOperation(BindingOperation bindingOperation)
        {   
          return createBindingOperationAdapter();
	      } 
 
      	public Object caseDefinition(Definition definition)
        {   
          return createDefinitionAdapter();
	      }           

      	public Object caseFault(Fault fault)
        {   
          return createFaultAdapter();
	      } 

      	public Object caseImport(Import i)
        {   
          return createImportAdapter();
	      } 

      	public Object caseInput(Input input)
        {   
          return createInputAdapter();
	      } 	

      	public Object caseOutput(Output output)
        {   
          return createOutputAdapter();
	      } 

      	public Object caseMessage(Message message)
        {   
          return createMessageAdapter();
	      }       

      	public Object caseOperation(Operation operation)
        {   
          return createOperationAdapter();
	      } 

      	public Object casePart(Part part)
        {   
          return createPartAdapter();
	      }  

      	public Object casePort(Port port)
        {   
          return createPortAdapter();
	      }  

      	public Object casePortType(PortType portType)
        {   
          return createPortTypeAdapter();
	      }  

      	public Object caseService(Service service)
        {   
          return createServiceAdapter();
	      }  

      	public Object caseTypes(Types types)
        {   
          return createTypesAdapter();
	    } 
        
		public Object defaultCase(EObject object)
		{
		  // note that the WSDLSwitch doesn't handle 
          // caseExtensibilityElement when the object
          // comes from another package... that why
          // we have an instanceof check here
		   if (object instanceof ExtensibilityElement)
		   {	   
	         return createExtensibilityElementAdapter();
		   }
		   else
		   {
			 return null;
		   }	   
        }
      };   

      Object o = wsdlSwitch.doSwitch((EObject)target);


      Adapter result = null;
      if (o instanceof Adapter)
      {
        result  = (Adapter)o;
      }
      else
      {          
        System.out.println("did not create adapter for target : " + target);
        Thread.dumpStack();
      }                   
      return result;
    }      
                               
  
    public Adapter createWSDLElementAdapter()
    {
      return new WSDLElementAdapter();
    }

  	public Adapter createBindingAdapter()
    {
      return new BindingAdapter();
    }   

 	  public Adapter createBindingFaultAdapter()
    {                                      
      return new BindingFaultAdapter();
    }           

 	  public Adapter createBindingInputAdapter()
    {                                      
      return new BindingInputAdapter();
    }

    public Adapter createBindingOutputAdapter()
    {
      return new BindingOutputAdapter();
	  } 
                
    public Adapter createBindingOperationAdapter()
    {     
      return new BindingOperationAdapter();
    }
          
  	public Adapter createDefinitionAdapter() 
    {
		  return new DefinitionAdapter();
	  }

  	public Adapter createFaultAdapter() 
    {
		  return new FaultAdapter();
	  }

  	public Adapter createImportAdapter() 
    {
		  return new ImportAdapter();
	  }

  	public Adapter createInputAdapter() 
    {
		  return new InputAdapter();
	  }

  	public Adapter createMessageAdapter() 
    {
		  return new MessageAdapter();
	  }


  	public Adapter createOperationAdapter() 
    {
		  return new OperationAdapter();
	  }

  	public Adapter createOutputAdapter() 
    {
		  return new OutputAdapter();
	  }

  	public Adapter createPartAdapter() 
    {
		  return new PartAdapter();
	  }

  	public Adapter createPortAdapter() 
    {
		  return new PortAdapter();
	  }

  	public Adapter createPortTypeAdapter() 
    {
		  return new PortTypeAdapter();
	  }

  	public Adapter createServiceAdapter() 
    {                    
		  return new ServiceAdapter();
	  } 

  	public Adapter createTypesAdapter() 
    {                    
		  return new TypesAdapter();
	  } 
    
    public Adapter createExtensibilityElementAdapter()
    {
      return new ExtensibilityElementAdapter();
    }

	
    // convenience method
    //
    public Adapter adapt(Notifier target)
    {
      return adapt(target, this);
    }
  }
    
  //
  //
  //
  protected class WSDLElementAdapter extends AdapterImpl implements ModelAdapter
  {   
    protected List listenerList = new ArrayList();


    public WSDLElementAdapter()
    {
    }  
                                 
    public boolean isAdapterForType(Object type)
    {
      return type == adapterFactory;
    }                                             

    public void addListener(ModelAdapterListener listener)
    {
      if (!listenerList.contains(listener))
      {
        listenerList.add(listener);
      }  
    }  

    public void removeListener(ModelAdapterListener listener)
    {
      if (listenerList.contains(listener))
      {
        listenerList.remove(listener);
      }
    } 

    public void firePropertyChanged(Object notifier, String property)
    {         
      List list = new ArrayList();
      list.addAll(listenerList);               
      for (Iterator i = list.iterator(); i.hasNext(); )
      {
        ModelAdapterListener listener = (ModelAdapterListener)i.next();
        listener.propertyChanged(getTarget(), property);
      }
    }   

    public void notifyChanged(Notification msg)
    {                        
      if (msg.getEventType() != Notification.RESOLVE)
      {        
        firePropertyChanged(msg.getNotifier(), null);
      }
    }  

       
    public Object getProperty(Object modelObject, String propertyName)
    {           
      Object result = null;
      if (propertyName.equals(CHILDREN_PROPERTY))
      {
        result = getChildren();      
      }                    
      else if (propertyName.equals(LABEL_PROPERTY))
      {
        result = getLabel();      
      }                    
      else if (propertyName.equals(IMAGE_PROPERTY))
      {
        result = getImage();
      } 
      else if (propertyName.equals("extensibilityElements"))
      { 
        if (modelObject instanceof ExtensibleElement)
        {
          result = WSDLEditorUtil.getInstance().getExtensibilityElementNodes((ExtensibleElement)modelObject);
        }
      } 
      else if (propertyName.equals("isReadOnly"))
      {
      	Element element = WSDLEditorUtil.getInstance().getElementForObject(target); 
     	  result = (element instanceof IDOMNode) ? Boolean.FALSE : Boolean.TRUE;    
      }
      return result;
    } 

    protected List getChildren()
    {
      return Collections.EMPTY_LIST;
    }                        

    protected String getLabel()
    {  
      return "todo";
    }

    protected Image getImage()
    {
      return null;
    }                       
  }                     
  

  protected class BindingAdapter extends WSDLElementAdapter
  {                
    protected Binding binding;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.binding = (Binding)newTarget;
    }
                                                      
    protected List getChildren()
    {                  
      List list = new ArrayList();                 
      addExtensiblityElementChildren(list, binding);
      List operationsList = binding.getEBindingOperations();
      List tempList = new ArrayList();
      tempList.addAll(operationsList);
      
      Collections.sort(tempList, new Comparator() {
    	public int compare(Object o1, Object o2) {
    		String s1 = ((BindingOperation) o1).getName();
    		String s2 = ((BindingOperation) o2).getName();
    		
    		if (s1 == null) {
    			s1 = "";
    		}
    		if (s2 == null) {
    			s2 = "";
    		}
    		
    		boolean boo = true;
      		return s1.compareToIgnoreCase(s2);
      	}
      });
      
      list.addAll(tempList);
      
      return list;
    }     

    protected String getLabel()
    {  
      return binding.getQName().getLocalPart();
    }

    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/binding_obj.gif");
    }                             
  }  
    

  protected class BindingFaultAdapter extends WSDLElementAdapter
  {                
    protected BindingFault bindingFault;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.bindingFault = (BindingFault)newTarget;
    }
                                                      
    protected List getChildren()
    {                  
      List list = new ArrayList();    
      addExtensiblityElementChildren(list, bindingFault);
      return list;
    }     

    protected String getLabel()
    {  
      return bindingFault.getName();
    }

    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/fault_obj.gif");
    }               
  } 


  protected class BindingInputAdapter extends WSDLElementAdapter
  {                
    protected BindingInput bindingInput;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.bindingInput = (BindingInput)newTarget;
    }
                                                      
    protected List getChildren()
    {                  
      List list = new ArrayList();    
      addExtensiblityElementChildren(list, bindingInput);
      return list;
    }     

    protected String getLabel()
    {  
      return "input";
    }

    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/input_obj.gif");
    }                             
  }  

 
  protected class BindingOutputAdapter extends WSDLElementAdapter
  {                
    protected BindingOutput bindingOutput;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.bindingOutput = (BindingOutput)newTarget;
    }
                                                      
    protected List getChildren()
    {                  
      List list = new ArrayList();    
      addExtensiblityElementChildren(list, bindingOutput);
      return list;
    }     

    protected String getLabel()
    {  
      return "output";
    }

    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/output_obj.gif");
    }    
  }  
                              

  protected class BindingOperationAdapter extends WSDLElementAdapter
  {                
    protected BindingOperation bindingOperation;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.bindingOperation = (BindingOperation)newTarget;
    }
                                                      
    protected List getChildren()
    {                  
      List list = new ArrayList();         
                  
      addExtensiblityElementChildren(list, bindingOperation); 

      if (bindingOperation.getBindingInput() != null)
      {
        list.add(bindingOperation.getBindingInput());
      }
      if (bindingOperation.getBindingOutput() != null)
      {
        list.add(bindingOperation.getBindingOutput());
      }                             
      list.addAll(bindingOperation.getEBindingFaults());
      
      return list;
    }        
                

    protected String getLabel()
    {  
      return bindingOperation.getName();
    }

    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/operationbinding_obj.gif");
    }               
  }  

  //
  //
  //
  protected class DefinitionAdapter extends WSDLElementAdapter implements ModelAdapterListener
  {                
    protected List permanentWSDLGroupObjectList;
    protected Definition definition;

    protected WSDLGroupObject typesGroup;
    protected WSDLGroupObject extensibilityElementsGroup;
    protected Types types; 
     
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.definition = (Definition)newTarget;
     
      // this group is added and removed from the child list dynamically
      // dependant on the presence of an 'actual' types element
      //
      typesGroup = new WSDLGroupObject(definition, WSDLGroupObject.TYPES_GROUP, getModelAdapterFactory());
                                                          
      // these groups always exist in the child list      
      //
      permanentWSDLGroupObjectList = new ArrayList();       
      permanentWSDLGroupObjectList.add(new WSDLGroupObject(definition, WSDLGroupObject.IMPORTS_GROUP));
      permanentWSDLGroupObjectList.add(typesGroup);  
      permanentWSDLGroupObjectList.add(new WSDLGroupObject(definition, WSDLGroupObject.MESSAGES_GROUP));
      permanentWSDLGroupObjectList.add(new WSDLGroupObject(definition, WSDLGroupObject.PORT_TYPES_GROUP));
      permanentWSDLGroupObjectList.add(new WSDLGroupObject(definition, WSDLGroupObject.BINDINGS_GROUP));
      permanentWSDLGroupObjectList.add(new WSDLGroupObject(definition, WSDLGroupObject.SERVICES_GROUP));
      // we only add this group when it has content
      //
      extensibilityElementsGroup = new WSDLGroupObject(definition, WSDLGroupObject.EXTENSIBILITY_ELEMENTS_GROUP);

      updateTypes();
    }
                                                      
    protected List getChildren()
    {       
      List list = new ArrayList();
      list.addAll(permanentWSDLGroupObjectList);   
      //if (extensibilityElementsGroup.getChildren().size() > 0)
      //{
      list.add(extensibilityElementsGroup);
      //}
      return list;
    }

    public void notifyChanged(Notification msg)
    {     
      if (msg.getEventType() != Notification.RESOLVE)
      {                           
        updateTypes();
        firePropertyChangedHelper();   
      }
    }        

    protected void updateTypes()
    {
      if (types != definition.getETypes())
      {
        if (types != null)
        {
          removeModelAdapterListener(types, this);
        }                                         
        types = definition.getETypes();
        if (types != null)
        {
          addModelAdapterListener(types, this);
        }
      }  
    }

    protected void firePropertyChangedHelper()
    {                        
      firePropertyChanged(getTarget(), null);

      for (Iterator i = getChildren().iterator(); i.hasNext(); )
      {                                                                              
        ModelAdapter adapter = getAdapter(i.next());
        adapter.firePropertyChanged(adapter, null);
      }                                             
    } 

    // propagate changes to 'types' object
    //
    public void propertyChanged(Object object, String property)
    {
      typesGroup.firePropertyChanged(typesGroup, property);
    } 

    protected ModelAdapterFactory getModelAdapterFactory()
    {
      return getWSDLModelAdapterFactory();
    }
    
    protected String getLabel()
    {  
      return definition.getQName().getLocalPart();
    }

    protected Image getImage()
    {
      return null;
    }                       
  }

 

  protected class FaultAdapter extends WSDLElementAdapter
  {                
    protected Fault fault;
                                    
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.fault = (Fault)newTarget;
    }
                                                      
    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/fault_obj.gif");
    }   

    protected String getLabel()
    {  
      return fault.getName();
    }               
  }   
      

  //
  //
  //
  protected class ImportAdapter extends WSDLElementAdapter
  {                
    protected Import theImport;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.theImport = (Import)newTarget;
    }
                                                       
    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/import_obj.gif");
    }   

    protected String getLabel()
    {  
      String result = theImport.getLocationURI();
      if (result == null || result.length() == 0)
      {
      	result = WSDLEditorPlugin.getWSDLString("_UI_NO_IMPORT_SPECIFIED");
      }
      return result;
    }               
  } 


  //
  //
  //
  protected class InputAdapter extends WSDLElementAdapter
  {                
    protected Input input;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.input = (Input)newTarget;
    }
                                                       
    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/input_obj.gif");
    }   

    protected String getLabel()
    {  
      return "input";
    }               
  }    

   
 
  //
  //
  //
  protected class MessageAdapter extends WSDLElementAdapter
  {                
    protected Message message;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.message = (Message)newTarget;
    }
                                                      
    protected List getChildren()
    {
      List list = new ArrayList();
      list.addAll(message.getEParts());
      return list;
    }                        

    protected String getLabel()
    {  
      if (message.getQName() == null) return ""; // revisit...it shouldn't be null 
      return message.getQName().getLocalPart();
    
    }

    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/message_obj.gif");
    }
  }


  //
  //
  //
  protected class OutputAdapter extends WSDLElementAdapter
  {                
    protected Output output;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.output = (Output)newTarget;
    }                     
        
    protected String getLabel()
    {  
      return "output";
    }

    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/output_obj.gif");
    }                                                        
  }  

  //
  //
  //
  protected class OperationAdapter extends WSDLElementAdapter
  {                
    protected Operation operation;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.operation = (Operation)newTarget;
    }
                                                      
    protected List getChildren()
    {                  
      List list = new ArrayList();
      Input input = operation.getEInput();
      Output output = operation.getEOutput();
      
      OperationType operationType = ((OperationImpl) operation).getStyle();
      if (operationType != null) {
      	if (operationType.equals(OperationType.REQUEST_RESPONSE) && input != null && output != null) {
      		// Input, Output
      		list.add(input);
      		list.add(output);
      	}
      	else if (operationType.equals(OperationType.SOLICIT_RESPONSE) && input != null && output != null) {
      		// Output, Input
      		list.add(output);
      		list.add(input);
      	}
      	else if (operationType.equals(OperationType.ONE_WAY) && input != null) {
      		// Input
      		list.add(input);
      	}
      	else if (operationType.equals(OperationType.NOTIFICATION) && output != null) {
      		//Output
      		list.add(output);
      	}
      }
      list.addAll(operation.getFaults().values());
      
      return list;
    }
      
	private int getNodeIndex(NodeList nodeList, Node node) {
		int index = 0;
		while (index < nodeList.getLength() && !(nodeList.item(index).equals(node))) {
			index++;
		}
		
		if (index >= nodeList.getLength()) {
			index = -1;
		}
		
		return index;
	}

    protected String getLabel()
    {  
      return operation.getName();
    }

    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/operation_obj.gif");
    }               
  }  
   

  //
  //
  //
  protected class PartAdapter extends WSDLElementAdapter
  {                
    protected Part part;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.part = (Part)newTarget;
    }                                                       

    protected String getLabel()
    {
      return part.getName();
    }

    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/part_obj.gif");
    }                             
  }     

  //
  //
  //
  protected class PortAdapter extends WSDLElementAdapter implements ModelAdapterListener
  {                
    protected Port port;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.port = (Port)newTarget;
    }
                                                                             
    protected String getLabel()
    {  
      return port.getName();
    }

    protected Image getImage()
    {                                
      return WSDLEditorPlugin.getInstance().getImage("icons/port_obj.gif");
    }    

    protected List getChildren()
    {
      return WSDLEditorUtil.getInstance().getExtensibilityElementNodes(port);  
    }
    // propagate changes to the binding object
    //
    public void propertyChanged(Object object, String property)
    {
      firePropertyChanged(port, property);
    }
  } 
     
  protected class ExtensibilityElementAdapter extends WSDLElementAdapter implements ModelAdapterListener
  {                
    protected ExtensibilityElement ee;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.ee = (ExtensibilityElement)newTarget;
    }
                                                                             
    protected String getLabel()
    {  
      String result = null;
      Node node = (Node) ee.getElement();

      ILabelProvider labelProvider = getExtensibilityLabelProvider(node);
      if (labelProvider != null)
      {
        result = labelProvider.getText(node);
      }

      if (result == null)
      {
        result = node.getNodeName();
      }
      return result;
    }

    protected Image getImage()
    {                                
      Image image = null;
      Node node = (Node) ee.getElement();

      ILabelProvider labelProvider = getExtensibilityLabelProvider(node);
      if (labelProvider != null)
      {
        image = labelProvider.getImage(node);
      }

      if (image == null)
      {
        image = WSDLEditorPlugin.getInstance().getImage("icons/element_obj.gif");
      }
      return image;
    }    

    protected List getChildren()
    {
      List list = null;	  
	  //TODO... we need to push getChildren down the ExtensiblityElement
	  // for now let's just cast to UnkownExtensiblityElement
	  if (ee instanceof UnknownExtensibilityElement)
      {
        list = ((UnknownExtensibilityElement)ee).getChildren();
      }
      return list; 
    }

    public void propertyChanged(Object object, String property)
    {
      firePropertyChanged(ee, property);
    }
    
    protected ILabelProvider getExtensibilityLabelProvider(Node node)
    {
      ILabelProvider result = null;
      String namespaceURI = node.getNamespaceURI();
      if (namespaceURI != null)
      {
        result = WSDLEditorPlugin.getInstance().getExtensibilityItemTreeProviderRegistry().getLabelProvider(namespaceURI);
      }
      return result;
    }
    
    protected ITreeChildProvider getExtensibilityContentProvider(Node node)
    {
      ITreeChildProvider result = null;
      String namespaceURI = node.getNamespaceURI();
      if (namespaceURI != null)
      {
        result = WSDLEditorPlugin.getInstance().getExtensibilityItemTreeProviderRegistry().getContentProvider(namespaceURI);
      }
      return result;
    }

    boolean isReadOnly()
    {
      return true;
    }
  } 


  //
  //
  //
  protected class PortTypeAdapter extends WSDLElementAdapter
  {                
    protected PortType portType;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.portType = (PortType)newTarget;
    }
                                                      
    protected List getChildren()
    {                  
      List list = new ArrayList();
      list.addAll(portType.getOperations());
      
      Collections.sort(list, new Comparator()
      {
        public int compare(Object o1, Object o2)
        {
          String o1Name = ((Operation) o1).getName();
          String o2Name = ((Operation) o2).getName();
          if (o1Name == null) o1Name = "";
          if (o2Name == null) o2Name = "";
          return (o1Name.compareToIgnoreCase(o2Name));
        }
      });
      return list; 
    }                    
      
    protected String getLabel()
    {  
      return portType.getQName().getLocalPart();
    }

    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/porttype_obj.gif");
    }
  } 
     

  protected class ServiceAdapter extends WSDLElementAdapter
  {                
    protected Service service;
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.service = (Service)newTarget;
    }
                                                      
    protected List getChildren()
    {                  
      List list = new ArrayList();
      list.addAll(service.getEPorts());
      return list; 
    }                    
      
    protected String getLabel()
    {  
      return service.getQName().getLocalPart();
    }

    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/service_obj.gif");
    }   
  } 
     
  //
  //
  //
  public class TypesAdapter extends WSDLElementAdapter
  {
    protected Types types; 
                         
    public void setTarget(Notifier newTarget) 
    {
      super.setTarget(newTarget);
      this.types = (Types)newTarget;
    }
                                                      
    protected List getChildren()
    {                  
      List list = new ArrayList();  
      list.addAll(WSDLEditorUtil.getInstance().getExtensibilityElementNodes(types));
      return list; 
    }                    
      
    protected String getLabel()
    {  
      return "Types";
    }

    protected Image getImage()
    {
      return WSDLEditorPlugin.getInstance().getImage("icons/types_obj.gif");
    }                                                                                      
  }
  
  public static void addModelAdapterListener(Object modelObject, ModelAdapterListener listener)
  {                                                               
// TODO: port check
    ModelAdapter adapter = getWSDLModelAdapterFactory().getAdapter(modelObject);
//    ModelAdapter adapter = EcoreUtil.getAdapter(getWSDLModelAdapterFactory().eAdapters(),modelObject);
    if (adapter != null)
    {
      adapter.addListener(listener);
    }
  }    

  public static void removeModelAdapterListener(Object modelObject, ModelAdapterListener listener)
  {                                                            
// TODO: port check
    ModelAdapter adapter = getWSDLModelAdapterFactory().getAdapter(modelObject);
//    ModelAdapter adapter = EcoreUtil.getAdapter(getWSDLModelAdapterFactory().eAdapters(),modelObject);
    if (adapter != null)
    {
      adapter.removeListener(listener);
    }
  }            
}