/*******************************************************************************
 * 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;


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 = "";
    		}

      		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()
    {  
      if (definition.getQName() != null) {
    	  return definition.getQName().getLocalPart();
      }
      return "";
    }

    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);
    }
  }            
}