[88679] Refactor Web Services Explorer from component jst.ws to wst.ws
diff --git a/bundles/org.eclipse.wst.ws/plugin.xml b/bundles/org.eclipse.wst.ws/plugin.xml
index 4c7e85b..525a0cd 100644
--- a/bundles/org.eclipse.wst.ws/plugin.xml
+++ b/bundles/org.eclipse.wst.ws/plugin.xml
@@ -16,6 +16,10 @@
 
    <requires>
       <import plugin="org.eclipse.core.runtime"/>
+      <import plugin="org.eclipse.wst.command.env.core"/>
+      <import plugin="org.eclipse.wst.wsdl"/>
+      <import plugin="org.eclipse.wst.ws.parser"/>
+      <import plugin="org.eclipse.wst.ws.apache.wsil"/>
    </requires>
 
 </plugin>
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicConnection.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicConnection.java
new file mode 100644
index 0000000..538caa2
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicConnection.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+public class BasicConnection implements Connection
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  private Rel fRel;
+  private Element fElement;
+  private Connection fOpposingConnection;
+
+  public static final int OUTBOUND = 0;
+  public static final int INBOUND = 1;
+
+  public static Connection[] createPair ( Rel outboundRel, Element targetElement, Rel inboundRel, Element sourceElement )
+  {
+    BasicConnection outboundConnection = new BasicConnection(outboundRel,targetElement);
+    BasicConnection inboundConnection = new BasicConnection(inboundRel,sourceElement);
+    outboundConnection.fOpposingConnection = inboundConnection;
+    inboundConnection.fOpposingConnection = outboundConnection;
+    return new Connection[] {outboundConnection,inboundConnection};
+  }
+
+  public BasicConnection ( Rel rel, Element element )
+  {
+    fRel = rel;
+    fElement = element;
+    fOpposingConnection = null;
+  }
+
+  public Rel getRel ()
+  {
+    return fRel;
+  }
+
+  public Element getElement ()
+  {
+    return fElement;
+  }
+
+  public Connection getOpposingConnection ()
+  {
+    return fOpposingConnection;
+  }
+
+  public String toString ()
+  {
+    return fElement.getName();
+  }
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicElement.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicElement.java
new file mode 100644
index 0000000..72d08f0
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicElement.java
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+public class BasicElement implements Element
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  private String fName;
+  private String fMUID;
+  private Model fModel;
+  private Hashtable fRels;
+  private Hashtable fProperties;
+  private Vector fListeners;
+
+  public BasicElement ( String name, Model model )
+  {
+    fName = name;
+    setMUID(model.makeMUID(name));
+    model.addElement(this);
+    fModel = model;
+    fRels = new Hashtable();
+    fListeners = new Vector();
+    fProperties = new Hashtable();
+    fProperties.put(Property.NAME,new BasicProperty(Property.NAME,fName));
+  }
+
+  public BasicElement ( String name, Element element, String outboundRelName, String inboundRelName )
+  {
+    this(name,element.getModel());
+    connect(element,outboundRelName,inboundRelName);
+  }
+
+  /**
+  * Returns a clone of this <code>Element</code>
+  * of the same class and with the same name and model,
+  * but with no Properties, Rels or Listeners except for
+  * the {@link Property#NAME NAME} property.
+  * @return Object A new Element.
+  */
+  public Element shallowClone ()
+  {
+    return new BasicElement(fName,fModel);
+  }
+
+  /**
+  * Returns a clone of this <code>Element</code>
+  * of the same class and with the same name and model
+  * and with a copy of the original Element's Properties.
+  * The Rels and Listeners are not cloned.
+  * @return Element A new Element.
+  */
+  public final Element deepClone ()
+  {
+    Element newElement = shallowClone();
+    Enumeration e = getProperties();
+    while (e.hasMoreElements())
+    {
+      Property property = (Property)e.nextElement();
+      Property newProperty = (Property)property.shallowClone();
+      newElement.setProperty(newProperty);
+    }
+    return newElement;
+  }
+
+  /**
+  * Model-View-Controller: All property changes to the model
+  * (such as those made by a wizard in the role of a Controller)
+  * should yield events to which an interested party can listen
+  * (such as a wizard in the role of a Viewer).
+  * @param tml The listener to add.
+  */
+  public void addListener ( ElementListener listener )
+  {
+    fListeners.add(listener);
+  }
+
+  public Model getModel ()
+  {
+    return fModel;
+  }
+
+  public boolean isValid ()
+  {
+    return (fModel != null && fModel.containsElement(this));
+  }
+
+  public boolean remove ()
+  {
+    return fModel.removeElement(this);
+  }
+
+  public void setName ( String name )
+  {
+    fName = name;
+    fProperties.put(Property.NAME,new BasicProperty(Property.NAME,fName));
+  }
+
+  public String getName ()
+  {
+    return fName;
+  }
+
+  /*
+  * The getter for the MUID
+  * The MUID is the Model Unique Identifier, made from the name and an
+  * appended unique number 
+  * @return String a unique id for this element within the context of the model 
+  */
+  public String getMUID()
+  {
+    return fMUID;
+  }
+
+  /*
+  *
+  *
+  */
+  public int getNumberID()
+  {
+    String number = getMUID().substring(getName().length());  
+    return Integer.parseInt(number);
+  }
+
+  /*
+  * Set the MUID which was made by the model
+  * Should only be settable within this element
+  * Set once upon creation, you can change the name
+  * but the id will remain constant.
+  */
+  private void setMUID(String MUID)
+  {
+    fMUID = MUID;
+  }
+ 
+  public void setProperty ( Property property )
+  {
+    String propertyName = property.getName();
+    Property oldProperty = getProperty(propertyName);
+    fProperties.put(propertyName,property);
+    if (oldProperty == null)
+    {
+      PropertyAddEvent event = new PropertyAddEvent(this,property);
+      Enumeration e = fListeners.elements();
+      while (e.hasMoreElements())
+      {
+        ((ElementListener)e.nextElement()).propertyAdded(event);
+      }
+    }
+    else
+    {
+      Object oldValue = oldProperty.getValue();
+      Object newValue = property.getValue();
+      if (oldValue != newValue)
+      {
+        if (oldValue == null || newValue == null || (!oldValue.equals(newValue)))
+        {
+          PropertyChangeEvent event = new PropertyChangeEvent(this,property,oldProperty);
+          Enumeration e = fListeners.elements();
+          while (e.hasMoreElements())
+          {
+            ((ElementListener)e.nextElement()).propertyChanged(event);
+          }
+        }
+      }
+    }
+    if (propertyName.equals(Property.NAME)) fName = property.getValue().toString();
+  }
+
+  public void setPropertyAsObject ( String name, Object value )
+  {
+    setProperty(new BasicProperty(name,value));
+  }
+
+  public void setPropertyAsString ( String name, String value )
+  {
+    setProperty(new BasicProperty(name,value));
+  }
+
+  public Property getProperty ( String name )
+  {
+    return (Property)fProperties.get(name);
+  }
+
+  public Object getPropertyAsObject ( String name )
+  {
+    Property property = getProperty(name);
+    return (property == null ? null : property.getValue());
+  }
+
+  public String getPropertyAsString ( String name )
+  {
+    Property property = getProperty(name);
+    return (property == null ? null : property.getValueAsString());
+  }
+
+  public Enumeration getProperties ()
+  {
+    return fProperties.elements();
+  }
+
+  public boolean connect ( Element targetElement, String outboundRelName, String inboundRelName )
+  {
+    if (fModel == null || fModel != targetElement.getModel()) return false;
+
+    Element sourceElement = this;
+    Rel outboundRel = sourceElement.getRel(outboundRelName);
+    Rel inboundRel = targetElement.getRel(inboundRelName);
+    Connection[] pair = BasicConnection.createPair(outboundRel,targetElement,inboundRel,sourceElement);
+    outboundRel.addConnection(pair[BasicConnection.OUTBOUND]);
+    inboundRel.addConnection(pair[BasicConnection.INBOUND]);
+    RelAddEvent event = new RelAddEvent(pair);
+    Enumeration eSource = getListeners();
+    Enumeration eTarget = targetElement.getListeners();
+    while (eSource.hasMoreElements())
+    {
+      ((ElementListener)eSource.nextElement()).relAdded(event);
+    }
+
+    while (eTarget.hasMoreElements())
+    {
+      ((ElementListener)eTarget.nextElement()).relAdded(event);
+    }
+
+
+    return true;
+  }
+
+  public boolean disconnect ( Element targetElement, String outboundRelName )
+  {
+    return disconnect(targetElement,getRel(outboundRelName));
+  }
+
+  public boolean disconnectRel ( String outboundRelName )
+  {
+    return disconnectRel(getRel(outboundRelName));
+  }
+
+  public boolean disconnectAll ()
+  {
+    if (fModel == null) return false;
+    Enumeration e = fRels.elements();
+    while (e.hasMoreElements())
+    {
+      Rel rel = (Rel)e.nextElement();
+      disconnectRel(rel);
+    }
+    return true;
+  }
+
+  public Enumeration getElements ( String relName )
+  {
+    return getRel(relName).getTargetElements();
+  }
+
+  public int getNumberOfElements ( String relName )
+  {
+    return getRel(relName).getNumberOfTargetElements();
+  }
+
+  public Rel getRel ( String relName )
+  {
+    Rel rel = (Rel)fRels.get(relName);
+    if (rel == null)
+    {
+      rel = new BasicRel(relName,this);
+      fRels.put(relName,rel);
+    }
+    return rel;
+  }
+
+  public Enumeration getRels ()
+  {
+    return fRels.elements();
+  }
+
+  public Enumeration getListeners()
+  {
+    return fListeners.elements();
+  }
+
+  protected boolean disconnect ( Element targetElement, Rel outboundRel )
+  {
+    if (fModel == null || fModel != targetElement.getModel() || outboundRel == null) return false;
+    Connection outboundConnection = outboundRel.getConnectionTo(targetElement);
+    if (outboundConnection == null) return false;
+    Connection inboundConnection = outboundConnection.getOpposingConnection();
+    RelRemoveEvent event = new RelRemoveEvent(new Connection [] {outboundConnection,inboundConnection});
+      Enumeration e = fListeners.elements();
+      while (e.hasMoreElements())
+      {
+        ((ElementListener)e.nextElement()).relRemoved(event);
+      }
+
+    Enumeration eTarget = targetElement.getListeners();
+    while (eTarget.hasMoreElements())
+    {
+      ((ElementListener)eTarget.nextElement()).relRemoved(event);
+    }
+
+    Rel inboundRel = inboundConnection.getRel();
+    boolean done = outboundRel.removeConnection(outboundConnection);
+    inboundRel.removeConnection(inboundConnection);
+    return done;
+  }
+
+  protected boolean disconnectRel ( Rel outboundRel )
+  {
+    if (fModel == null || outboundRel == null) return false;
+    Element[] elements = new Element[outboundRel.getNumberOfTargetElements()];
+    int i = 0;
+    Enumeration e = outboundRel.getTargetElements();
+    while (e.hasMoreElements())
+    {
+      elements[i++] = (Element)e.nextElement();
+    }
+    while (i-- > 0)
+    {
+      disconnect(elements[i],outboundRel);
+    }
+    return true;
+  }
+
+  public String toString ()
+  {
+    return getName();
+  }
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicModel.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicModel.java
new file mode 100644
index 0000000..3b3b435
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicModel.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+public class BasicModel implements Model
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  private String fName;
+  private Hashtable fElements;
+  private Element fRoot;
+  //This is used by the MUID
+  private int fUniqueNumberCounter;
+
+  public BasicModel ( String name )
+  {
+    fName = name;
+    fElements = new Hashtable();
+    fRoot = null;
+    fUniqueNumberCounter = 0;
+  }
+
+  public void setName ( String name )
+  {
+    fName = name;
+  }
+
+  public String getName ()
+  {
+    return fName;
+  }
+
+
+  /*
+  * simple counter that increments each call 
+  */
+  public int getUniqueNumber()
+  {
+    fUniqueNumberCounter++;
+    return fUniqueNumberCounter;
+  }
+
+  /*
+  * This will use a unique number and append it to the end of the name 
+  * @param String name of the element
+  * @return String MUID
+  */
+  public String makeMUID(String name)
+  {
+    String num = String.valueOf(getUniqueNumber());
+    String muid = name + num;
+    return muid;
+  }
+
+
+  public boolean setRootElement ( Element root )
+  {
+    if (root.getModel() == null)
+      addElement(root);
+    else if (root.getModel() != this)
+      return false;
+    fRoot = root;
+    return true;
+  }
+
+  public Element getRootElement ()
+  {
+    if (fRoot == null) fRoot = getFirstElement();
+    return fRoot;
+  }
+
+
+  /**
+  * Get the elements that have this name
+  * @param String name the name of the element 
+  * @return Vector a vector of elements that have this name
+  * These elements may be of different types
+  **/
+
+  public Vector getElementsByName(String name)
+  {
+    Vector vector = new Vector();
+    Enumeration e = fElements.keys();
+    while (e.hasMoreElements()){
+       Element element = (Element)e.nextElement();
+       if (element.getName().equals(name)) vector.addElement(element);
+    }
+    return vector;
+  }
+
+ 
+
+  public boolean addElement ( Element element )
+  {
+    if (element.getModel() != null) return false;
+    fElements.put(element,element);
+    return true;
+  }
+
+  public boolean removeElement ( Element element )
+  {
+    if (element.getModel() != this) return false;
+    element.disconnectAll();
+    if (fRoot == element) fRoot = null;
+    return (fElements.remove(element) == element);
+  }
+
+  public Enumeration getElements ()
+  {
+    return fElements.elements();
+  }
+
+  public int getNumberOfElements ()
+  {
+    return fElements.size();
+  }
+
+  public boolean containsElement ( Element element )
+  {
+    return fElements.contains(element);
+  }
+
+  private Element getFirstElement ()
+  {
+    Enumeration e = getElements();
+    return (e.hasMoreElements() ? (Element)e.nextElement() : null);
+  }
+
+  public String toString ()
+  {
+    return getName();
+  }
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicProperty.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicProperty.java
new file mode 100644
index 0000000..6661a82
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicProperty.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+public class BasicProperty implements Property
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  private String fName;
+  private Object fValue;
+
+  public BasicProperty ( String name )
+  {
+    fName = name;
+  }
+
+  public BasicProperty ( String name, Object value )
+  {
+    fName = name;
+    fValue = value;
+  }
+
+  /**
+  * Returns a shallow clone of this <code>Property</code>.
+  * Property key and value references are cloned,
+  * but the value objects themselves are not cloned.
+  * @return Property A new Property.
+  */
+  public Property shallowClone ()
+  {
+    return new BasicProperty(fName,fValue);
+  }
+
+  public String getName ()
+  {
+    return fName;
+  }
+
+  public void setValue ( Object value )
+  {
+    fValue = value;
+  }
+
+  public Object getValue ()
+  {
+    return fValue;
+  }
+
+  public void setValueAsString ( String value )
+  {
+    fValue = value;
+  }
+
+  public String getValueAsString ()
+  {
+    return (fValue != null ? fValue.toString() : null);
+  }
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicRel.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicRel.java
new file mode 100644
index 0000000..41336fb
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/BasicRel.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+public class BasicRel implements Rel
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  private String fName;
+  private Element fSourceElement;
+  private Vector fConnections;
+
+  public BasicRel ( String name, Element sourceElement )
+  {
+    fName = name;
+    fSourceElement = sourceElement;
+    fConnections = new Vector();
+  }
+
+  public String getName ()
+  {
+    return fName;
+  }
+
+  public Element getSourceElement ()
+  {
+    return fSourceElement;
+  }
+
+  public Enumeration getTargetElements ()
+  {
+    return new ElementEnumeration(fConnections.elements());
+  }
+
+  public int getNumberOfTargetElements ()
+  {
+    return fConnections.size();
+  }
+
+  public void addConnection ( Connection connection )
+  {
+    fConnections.addElement(connection);
+  }
+
+  public boolean removeConnection ( Connection connection )
+  {
+    return fConnections.removeElement(connection);
+  }
+
+  public Connection getConnectionTo ( Element targetElement )
+  {
+    Enumeration e = fConnections.elements();
+    while (e.hasMoreElements())
+    {
+      Connection c = (Connection)e.nextElement();
+      if (c.getElement() == targetElement) return c;
+    }
+    return null;
+  }
+
+  public String toString ()
+  {
+    return getName();
+  }
+
+  private class ElementEnumeration implements Enumeration
+  {
+    private Enumeration fConnectionEnumeration;
+
+    public ElementEnumeration ( Enumeration connectionEnumeration )
+    {
+      fConnectionEnumeration = connectionEnumeration;
+    }
+
+    public boolean hasMoreElements ()
+    {
+      return fConnectionEnumeration.hasMoreElements();
+    }
+
+    public Object nextElement ()
+    {
+      return ((Connection)fConnectionEnumeration.nextElement()).getElement();
+    }
+  }
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Connection.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Connection.java
new file mode 100644
index 0000000..8d6270c
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Connection.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+/**
+* This is the abstract class for a connection that ties a Rel to a Node.
+* Normally Connection objects are manufactured and managed within the
+* derived classes of the Model framework, and are not manipulated by
+* the caller directly.
+*/
+public interface Connection
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  /**
+  * Returns the Rel that owns this connection.
+  * @return Rel The Rel that owns this connection.
+  * This method never returns null, that is, a Connection
+  * cannot exist without a Rel to own it.
+  */
+  public Rel getRel ();
+
+  /**
+  * Returns the Node that this connection points to.
+  * @return Node The Node this connection points to.
+  * This method never returns null, that is, a Connection
+  * cannot exist without a Node to point to.
+  */
+  public Element getElement ();
+
+  /**
+  * Returns the opposing connection to this connection.
+  * Connection objects always exist in pairs, that is,
+  * if node "Parent" has a relationship named "Children"
+  * containing a connection to node "Child", then there
+  * must exist an opposing connection from "Child" to
+  * "Parent" in some relationship of "Child" (for example,
+  * in a relationship called "Parents").
+  * @return Connection The opposing connection.
+  * As a general rule, this method should never return null.
+  * It may only return null during construction of the pair
+  * of connections.
+  */
+  public Connection getOpposingConnection ();
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Element.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Element.java
new file mode 100644
index 0000000..c23721b
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Element.java
@@ -0,0 +1,265 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+import java.util.Enumeration;
+
+/**
+* This is the abstract class for elements that can be managed by a Model.
+* Every element has a name, a set of properties, and a set of relationships
+* to other elements.
+*/
+public interface Element
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  /**
+  * Returns a clone of this <code>Element</code>
+  * of the same class and with the same name and model,
+  * but with no Properties, Rels or Listeners except for
+  * the {@link Property#NAME NAME} property.
+  * @return Object A new Element.
+  */
+  public Element shallowClone ();
+
+  /**
+  * Returns a clone of this <code>Element</code>
+  * of the same class and with the same name and model
+  * and with a copy of the original Element's Properties.
+  * The Rels and Listeners are not cloned.
+  * @return Element A new Element.
+  */
+  public Element deepClone ();
+
+  /**
+  * Returns the model this element belongs to, or null if the element
+  * has not been added to a model. See also {@link #isValid isValid()}.
+  * @return Model The model this element belongs to, or null if none.
+  */
+  public Model getModel ();
+
+  /**
+  * Returns true if and only if this element belongs to a model.
+  * See also {@link #getModel getModel()}.
+  * @return boolean True if and only if this element belongs to a model.
+  */
+  public boolean isValid ();
+
+  /**
+  * Removes this element from the model to which it currently belongs.
+  * After calling this method, {@link #getModel getModel()} will return
+  * null and {@link #isValid isValid()} will return false.
+  * @return boolean True if the element was successfully removed from
+  * its model. This method returns false if the element does not belong
+  * to any model.
+  */
+  public boolean remove ();
+
+  /**
+  * Sets the name of this element and updates the "name" property.
+  * Every element includes a property called "name" (see Property.NAME)
+  * whose value is the same string as passed into setName().
+  * @param name The name of this element.
+  */
+  public void setName ( String name );
+
+  /**
+  *
+  */
+  public void addListener ( ElementListener listener );
+
+  /**
+  * Returns the name of this element.
+  * @return String The name of this element.
+  */
+  public String getName ();
+
+  /**
+  * Adds or sets a property of this element.
+  * Properties set using this method can be retrieved using either
+  * {@link #getProperty getProperty()} or
+  * {@link #getPropertyAsObject getPropertyAsObject()}.
+  * Every element includes a property called "name" (see Property.NAME)
+  * whose value is the same string as passed into {@link #setName setName()}.
+  * Any previous property with the same name is replaced.
+  * @param property The property to set.
+  */
+  public void setProperty ( Property property );
+
+  /**
+  * Adds or sets a property of this element.
+  * Properties set using this method can be retrieved using either
+  * {@link #getProperty getProperty()} or
+  * {@link #getPropertyAsObject getPropertyAsObject()}.
+  * Every element includes a property called "name" (see Property.NAME)
+  * whose value is the same string as passed into {@link #setName setName()}.
+  * Any previous property with the same name is replaced.
+  * @param name The name of the property to set.
+  * @param value The Object value of the property to set.
+  */
+  public void setPropertyAsObject ( String name, Object value );
+
+  /**
+  * Adds or sets a String property of this element.
+  * Properties set using this method can be retrieved using either
+  * {@link #getProperty getProperty()},
+  * {@link #getPropertyAsObject getPropertyAsObject()} or
+  * {@link #getPropertyAsString getPropertyAsString()}.
+  * Every element includes a property called "name" (see Property.NAME)
+  * whose value is the same string as passed into {@link #setName setName()}.
+  * Any previous property with the same name is replaced.
+  * @param name The name of the property to set.
+  * @param value The String value of the property to set.
+  */
+  public void setPropertyAsString ( String name, String value );
+
+  /**
+  * Returns a property of the given name or null if there is none.
+  * Every element includes a property called "name" (see Property.NAME)
+  * whose value is the same string as passed into {@link #setName setName()}.
+  * @param name The name of the property to return.
+  * @return Property The property, or null if none.
+  */
+  public Property getProperty ( String name );
+
+  /**
+  * Returns the Object value of a property of the given name or null
+  * if there is none.
+  * Every element includes a property called "name" (see Property.NAME)
+  * whose value is the same string as passed into {@link #setName setName()}.
+  * @param name The name of the property to return.
+  * @return Object The property value as an Object, or null if none.
+  */
+  public Object getPropertyAsObject ( String name );
+
+  /**
+  * Returns the String value of a property of the given name or null
+  * if there is none.
+  * Every element includes a property called "name" (see Property.NAME)
+  * whose value is the same string as passed into {@link #setName setName()}.
+  * @param name The name of the property to return.
+  * @return String The property value as a String, or null if none.
+  */
+  public String getPropertyAsString ( String name );
+
+  /**
+  * Returns an enumeration of all properties of this element.
+  * There is always at least one property that carries the
+  * name of this element (see {@link #setName setName()}).
+  * @return Enumeration An enumeration of all properties of this element.
+  */
+  public Enumeration getProperties ();
+
+  /**
+  * Creates a bidirectional relationship between this element and another.
+  * Both relationships are identified by names. The names of all the
+  * outbound relationships of a element must be mutually unique.
+  * @param element The element to connect to.
+  * @param outboundRelName The name of the relationship to contain the
+  * connection to the element.
+  * @param inboundRelName The name of the relationship to contain the
+  * inverse connection back to this element.
+  * @return boolean True if the connection is created successfully.
+  * Both elements must belong to the same model, other false is returned.
+  */
+  public boolean connect ( Element element, String outboundRelName, String inboundRelName );
+
+  /**
+  * Dismantles the connection to another element in a given relationship.
+  * The inverse connection is also automatically dismantled.
+  * @param element The element to disconnect from.
+  * @param outboundRelName The name of the relationship containing
+  * the connection to the element.
+  * @return boolean True if the connection is removed successfully.
+  * Both elements must belong to the same model, other false is returned.
+  * If the elements are not connected through the given relationship, then
+  * false is returned.
+  */
+  public boolean disconnect ( Element element, String outboundRelName );
+
+  /**
+  * Dismantles the connection to all elements in the given relationship.
+  * The inverse connections are also automatically dismantled.
+  * @param outboundRelName The name of the relationship.
+  * @return boolean True if all connections are removed successfully.
+  * This method returns false if the element does not belong to a model.
+  */
+  public boolean disconnectRel ( String outboundRelName );
+
+  /**
+  * Dismantles all connections from this element.
+  * @return boolean True if all connections are removed successfully.
+  * This method returns false if the element does not belong to a model.
+  */
+  public boolean disconnectAll ();
+
+  /**
+  * Returns an enumeration of all elements
+  * connected thru the given relationship.
+  * @param relName The name of the relationship.
+  * @return Enumeration The elements in the relationship.
+  * This method never returns null.
+  */
+  public Enumeration getElements ( String relName );
+
+  /**
+  * Returns the number of elements in the given relationship.
+  * @param relName The name of the relationship.
+  * @return int The number of elements in the relationship.
+  * This method never returns a negative value.
+  */
+
+  public Enumeration getListeners();
+
+  public int getNumberOfElements ( String relName );
+
+  /**
+  * Returns the relationship object of the given name.
+  * @param relName The name of the relationship.
+  * @return int The relationship. This method never returns null.
+  * In other words, any reference to a relationship name automatically
+  * brings a corresponding Rel object into existence. Careless naming
+  * may result in the {@link #getRels getRels()} method returning an enumeration of
+  * more relationships than would be meaningful, efficient or useful.
+  */
+  public Rel getRel ( String relName );
+
+  /**
+  * Returns an enumeration of all known relationships.
+  * @return Enumeration The outbound relationships of the element.
+  * This method never returns null.
+  */
+  public Enumeration getRels ();
+
+
+  /*
+  * There is a need sometimes for each element in a model to have a unique identifier.
+  * Normally this would be left to a name, but since the element maker gives it its name
+  * there is a chance that a model could have two elements with the same name. If they 
+  * are the same element type then there would be no way to differenciate between the two.
+  * The following getter and setter will provide a unique identifier. This identifier will be known 
+  * as the muid or Model Unique Identifier. Unlike a uuid it will only be assured uniqueness 
+  * within its own model. The intention is to use a unique number appended to the end 
+  * of the name.
+  * The following is the getter
+  * @return String the unique identifier
+  */
+
+  public String getMUID();
+  
+  
+
+
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/ElementAdapter.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/ElementAdapter.java
new file mode 100644
index 0000000..ec0cfd8
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/ElementAdapter.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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.ws.internal.datamodel;
+
+/**
+* This is where we store all the state data that various UIs
+* (such as the NewWSDLCreationWizard) capture from the user
+* and then need to process.
+*/
+public class ElementAdapter implements ElementListener
+{
+  /**
+  * Called when a property is added to the model.
+  * @param event The event containing the model, property and value.
+  */
+  public void propertyAdded ( PropertyAddEvent event )
+  {
+  }
+
+  /**
+  * Called when a property in the model changes.
+  * @param event The event containing the model, property, old value
+  * and new value.
+  */
+  public void propertyChanged ( PropertyChangeEvent event )
+  {
+  }
+
+  /**
+  * Called when a property in the model is removed.
+  * @param event The event containing the model, property and old value.
+  */
+  public void propertyRemoved ( PropertyRemoveEvent event )
+  {
+  }
+
+  /**
+  * Called when a property is added to the model.
+  * @param event The event containing the model, property and value.
+  */
+  public void relAdded ( RelAddEvent event )
+  {
+  }
+
+  /**
+  * Called when a property is added to the model.
+  * @param event The event containing the model, property and value.
+  */
+  public void relRemoved ( RelRemoveEvent event )
+  {
+  }
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/ElementListener.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/ElementListener.java
new file mode 100644
index 0000000..44819e3
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/ElementListener.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+/**
+* This is where we store all the state data that various UIs
+* (such as the NewWSDLCreationWizard) capture from the user
+* and then need to process.
+*/
+public interface ElementListener
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  /**
+  * Called when a property is added to the model.
+  * @param event The event containing the model, property and value.
+  */
+  public void propertyAdded ( PropertyAddEvent event );
+
+  /**
+  * Called when a property in the model changes.
+  * @param event The event containing the model, property, old value
+  * and new value.
+  */
+  public void propertyChanged ( PropertyChangeEvent event );
+
+  /**
+  * Called when a property in the model is removed.
+  * @param event The event containing the model, property and old value.
+  */
+  public void propertyRemoved ( PropertyRemoveEvent event );
+
+  /**
+  * Called when a property is added to the model.
+  * @param event The event containing the model, property and value.
+  */
+  public void relAdded ( RelAddEvent event );
+
+  /**
+  * Called when a property is added to the model.
+  * @param event The event containing the model, property and value.
+  */
+  public void relRemoved ( RelRemoveEvent event );
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Model.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Model.java
new file mode 100644
index 0000000..72f297a
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Model.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+* This is the abstract class for a simple data model consisting of
+* a network of named nodes (class Node). Every node carries a set
+* of named properties (class Property). Nodes are interrelated by
+* relationships (class Rel) and connections (class Connection).
+* Each Model keeps a registry of all of its nodes, and keeps a
+* reference to one "root" node that can be used as a starting
+* point for navigation.
+*/
+public interface Model
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  /**
+  * Sets the name of the model.
+  * @param name The name of the model.
+  */
+  public void setName ( String name );
+
+  /**
+  * Gets the name of the model.
+  * @return String The name of the model. This must not be null.
+  */
+  public String getName ();
+
+  /**
+  * Sets a node as the root of the model. If the node does not
+  * belong to a model, then it is added automatically. If the
+  * node already belongs to another model, then the root node
+  * is not set and method returns false.
+  * @param root The node to set as the root. The node must
+  * belong either to this model or to no model. This must
+  * not be null.
+  * @return boolean True if the node was set as the root.
+  * This method returns false if the given node already belongs
+  * to another model.
+  */
+  public boolean setRootElement ( Element root );
+
+  /**
+  * Returns the root node. This method always returns a node
+  * except on an empty Model. If setRootNode() has not been
+  * called, or if the last root node was removed from the model,
+  * then the method will select and return an arbitrary node as
+  * the root. This method will consistently return the same node
+  * until either
+  * (a) setRootNode() is called with a different node or
+  * (b) removeNode() is called to remove the node from the model.
+  * @return Node The current root node, or null if the model is empty.
+  */
+
+  public Element getRootElement ();
+
+  /**
+  * Get the elements that have this name
+  * @param String name the name of the element 
+  * @return Vector a vector of elements that have this name
+  * These elements may be of different types
+  **/
+
+  public Vector getElementsByName(String name);
+
+  /**
+  * Adds a node to the model. If the node already belongs to another
+  * model then it will not be added.
+  * @param node The node to add. This must not be null.
+  * @return boolean True if the node was added successfully.
+  * This method returns false if the given node already belongs to
+  * the current model or to another model.
+  */
+  public boolean addElement ( Element element );
+
+  /**
+  * Removes a node from the model.
+  * @param node The node to remove. This must not be null.
+  * @return boolean True if the node was removed successfully.
+  * This method returns false if the given node does not belong
+  * to this model.
+  */
+  public boolean removeElement ( Element element );
+
+  /**
+  * Returns an enumeration of all nodes in the model and in no
+  * particular order,
+  * @return Enumeration An enumeration of all nodes in the model.
+  * This method never returns null.
+  */
+  public Enumeration getElements ();
+
+  /**
+  * Returns the number of nodes in the model.
+  * @return int The number of nodes in the model.
+  * This method never returns a negative value.
+  */
+  public int getNumberOfElements ();
+
+  /**
+  * Determines if this model contains the given node.
+  * @param node The node to check for. This must not be null.
+  * @return boolean True if and only if the model contains the node.
+  */
+  public boolean containsElement ( Element element );
+
+  /*
+  * This function will provide the next number in the queue for the MUID
+  *
+  */
+  public int getUniqueNumber();
+
+  /*
+  * heres what we call from the element
+  */
+  public String makeMUID(String name);
+
+
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Property.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Property.java
new file mode 100644
index 0000000..8e793ba
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Property.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+/**
+* This is the abstract class for properties of a Node.
+* Every property has an immutable name and a value of type Object.
+*/
+public interface Property
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  /**
+  * Every Node has a property called "name" that is equivalent
+  * to and kept synchronized with Node.getName() and Node.setName().
+  */
+  public static final String NAME = "name";
+
+  /**
+  * Returns a shallow clone of this <code>Property</code>.
+  * Property key and value references are cloned,
+  * but the value objects themselves are not cloned.
+  * @return Property A new Property.
+  */
+  public Property shallowClone ();
+
+  /**
+  * Returns the name of this node.
+  * @return String The name of this node.
+  */
+  public String getName ();
+
+  /**
+  * Sets the value of this property.
+  * @param value The value to set. Any previous value is replaced.
+  */
+  public void setValue ( Object value );
+
+  /**
+  * Returns the value of this property.
+  * @return Object The value of this property, possibly null.
+  */
+  public Object getValue ();
+
+  /**
+  * Sets the value of this property as a string.
+  * @param value The string to set. Any previous value is replaced.
+  * The type of the previous value, if any, is of no consequence.
+  */
+  public void setValueAsString ( String value );
+
+  /**
+  * Returns the value of this property as a string.
+  * @return String the value of this property as a string, possibly null.
+  * If the set value is an arbitrary Object, then Object.toString() is
+  * returned.
+  */
+  public String getValueAsString ();
+}
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/PropertyAddEvent.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/PropertyAddEvent.java
new file mode 100644
index 0000000..62fc058
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/PropertyAddEvent.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+/**
+* Carries data relevant to when a property is added to the model.
+*/
+public class PropertyAddEvent
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  /**
+  * The model the changed.
+  */
+  protected BasicElement fElement;
+
+  /**
+  * The property that was added.
+  */
+  protected Property fProperty;
+
+ 
+  /**
+   * Constructor.
+   * @param model The model that changed.
+   * @param property The property that was added.
+   * @param value The property's value.
+   */
+  public PropertyAddEvent ( BasicElement element, Property property)
+  {
+    fElement = element;
+    fProperty = property;
+  }
+
+  /**
+   * Returns the model that changed (that produced this event).
+   * @return TinyModel The model that changed.
+   */
+  public BasicElement getElement ()
+  {
+    return fElement;
+  }
+
+  /**
+   * Returns the model property that was added.
+   * @return TinyModel The property that was added.
+   */
+  public Property getProperty ()
+  {
+    return fProperty;
+  }
+
+  
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/PropertyChangeEvent.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/PropertyChangeEvent.java
new file mode 100644
index 0000000..0ade7cb
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/PropertyChangeEvent.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+/**
+* Carries data relevant to when a property is changed in the model.
+*/
+public class PropertyChangeEvent
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  /**
+  * The model the changed.
+  */
+  protected BasicElement fElement;
+
+  /**
+  * The property that changed.
+  */
+  protected Property fProperty;
+
+  /**
+  * The property's old value.
+  */
+  protected Property fOldProperty;
+
+   /**
+   * Constructor.
+   * @param model The model that changed.
+   * @param property The property that changed.
+   * @param oldValue The property's old value.
+   * @param newValue The property's new value.
+   */
+  public PropertyChangeEvent ( BasicElement element , Property property, Property oldProperty )
+  {
+    fElement = element;
+    fProperty = property;
+    fOldProperty = oldProperty;
+  }
+
+  /**
+   * Returns the model that changed (that produced this event).
+   * @return TinyModel The model that changed.
+   */
+  public BasicElement getElement ()
+  {
+    return fElement;
+  }
+
+  /**
+   * Returns the model property that changed.
+   * @return TinyModel The property that changed.
+   */
+  public Property getProperty ()
+  {
+    return fProperty;
+  }
+
+  /**
+   * Returns the model property's old value.
+   * @return TinyModel The property's old value.
+   */
+  public Property getOldProperty ()
+  {
+    return fOldProperty;
+  }
+
+  
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/PropertyRemoveEvent.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/PropertyRemoveEvent.java
new file mode 100644
index 0000000..be468da
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/PropertyRemoveEvent.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+/**
+* Carries data relevant to when a property is removed from the model.
+*/
+public class PropertyRemoveEvent
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  /**
+  * The model the changed.
+  */
+  protected BasicElement fElement;
+
+  /**
+  * The property that was removed.
+  */
+  protected Property fProperty;
+
+  /**
+   * Constructor.
+   * @param model The model that changed.
+   * @param property The property that was removed.
+   * @param value The property's value.
+   */
+  public PropertyRemoveEvent ( BasicElement element, Property property)
+  {
+    fElement = element;
+    fProperty = property;
+  }
+
+  /**
+   * Returns the model that changed (that produced this event).
+   * @return TinyModel The model that changed.
+   */
+  public BasicElement getElement ()
+  {
+    return fElement;
+  }
+
+  /**
+   * Returns the model property that was removed.
+   * @return TinyModel The property that was removed.
+   */
+  public Property getProperty ()
+  {
+    return fProperty;
+  }
+
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Rel.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Rel.java
new file mode 100644
index 0000000..661a6df
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/Rel.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+import java.util.Enumeration;
+
+/**
+* This is the abstract class for relationships in a Model.
+*/
+public interface Rel
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  /**
+  * Returns the name of this relationship. Relationship names
+  * cannot be changed.
+  * @return String The name of the relationship.
+  */
+  public String getName ();
+
+  /**
+  * Returns the node that owns this relationship.
+  * @return Node The node that owns this relationship.
+  * This method never returns null, that is, relationships
+  * cannot exist in the absence of a node.
+  */
+  public Element getSourceElement();
+
+  /**
+  * Returns an enumeration of all nodes in this relationship.
+  * @return Enumeration The nodes in this relationship.
+  * This method never returns null.
+  */
+  public Enumeration getTargetElements ();
+
+  /**
+  * Returns the number of nodes in this relationship.
+  * @return int The number of nodes in this relationship.
+  * This method never returns a negative value.
+  */
+  public int getNumberOfTargetElements ();
+
+  /**
+  * Adds a connection to this relationship. This method is
+  * intended for use by derivations of the Model framework,
+  * not by users of the framework. Connection objects should
+  * only be constructed, added, removed and retrieved by
+  * implementations of the Node and Rel interfaces.
+  * @param connection The connection to add.
+  */
+  public void addConnection ( Connection connection );
+
+  /**
+  * Removes a connection from this relationship. This method is
+  * intended for use by derivations of the Model framework,
+  * not by users of the framework. Connection objects should
+  * only be constructed, added, removed and retrieved by
+  * implementations of the Node and Rel interfaces.
+  * @param connection The connection to remove.
+  * @return boolean True if the connection was found and removed.
+  */
+  public boolean removeConnection ( Connection connection );
+
+  /**
+  * Returns the Connection object for the given target node.
+  * This method is intended for use by derivations of the Model
+  * framework, not by users of the framework. Connection objects
+  * should only be constructed, added, removed and retrieved by
+  * implementations of the Node and Rel interfaces.
+  * @param targetNode The node to find the Connection to.
+  * @return Connection The connection, or null if none.
+  */
+  public Connection getConnectionTo ( Element targetElement );
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/RelAddEvent.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/RelAddEvent.java
new file mode 100644
index 0000000..41a10f7
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/RelAddEvent.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+/**
+* Carries data relevant to when a property is added to the model.
+*/
+public class RelAddEvent
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  /**
+  * The model the changed.
+  */
+  protected Connection fOutBound;
+
+  /**
+  * The model the changed.
+  */
+  protected Connection fInBound;
+
+  /**
+  * The property that was added.
+  */
+  protected Property fProperty;
+
+ 
+  /**
+   * Constructor.
+   * @param model The model that changed.
+   * @param property The property that was added.
+   * @param value The property's value.
+   */
+  public RelAddEvent (Connection[] pair)
+  {
+     fOutBound = pair[BasicConnection.OUTBOUND];
+     fInBound = pair[BasicConnection.INBOUND];
+  }
+
+  /**
+   * Returns the outbound connection that changed 
+  **/
+  public Connection getOutBoundConnection ()
+  {
+    return fOutBound;
+  }
+
+  /**
+   * Returns the changed rel name 
+  **/
+  public String getOutBoundRelName()
+  {
+    return fOutBound.getRel().getName();
+  }
+
+  /**
+   * Returns the changed rel
+  **/
+  public Rel getOutBoundRel()
+  {
+    return fOutBound.getRel();
+  }
+
+  /**
+   * Returns the changed rel name 
+  **/
+  public String getInBoundRelName()
+  {
+    return fInBound.getRel().getName();
+  }
+
+  /**
+   * Returns the changed rel
+  **/
+  public Rel getInBoundRel()
+  {
+    return fInBound.getRel();
+  }
+
+  /**
+   * Returns the outbound element that changed 
+  **/
+  public Element getParentElement ()
+  {
+    return fOutBound.getElement();
+  }
+
+  
+  /**
+   * Returns the inbound connection that changed 
+  **/
+  public Element getChildElement ()
+  {
+    return fInBound.getElement();
+  }
+
+  
+}
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/RelRemoveEvent.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/RelRemoveEvent.java
new file mode 100644
index 0000000..d8fa4f7
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/datamodel/RelRemoveEvent.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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.ws.internal.datamodel;
+
+/**
+* Carries data relevant to when a property is added to the model.
+*/
+public class RelRemoveEvent
+{
+
+  // Copyright
+  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";
+
+  /**
+  * The model the changed.
+  */
+  protected Connection fOutBound;
+
+  /**
+  * The model the changed.
+  */
+  protected Connection fInBound;
+
+  /**
+  * The property that was added.
+  */
+  protected Property fProperty;
+
+ 
+  /**
+   * Constructor.
+   * @param model The model that changed.
+   * @param property The property that was added.
+   * @param value The property's value.
+   */
+  public RelRemoveEvent (Connection[] pair)
+  {
+     fOutBound = pair[BasicConnection.OUTBOUND];
+     fInBound = pair[BasicConnection.INBOUND];
+  }
+
+  /**
+   * Returns the model that changed (that produced this event).
+   * @return TinyModel The model that changed.
+   */
+  public Connection getOutBound ()
+  {
+    return fOutBound;
+  }
+
+  /**
+   * Returns the model property that was added.
+   * @return TinyModel The property that was added.
+   */
+  public Connection getInBound ()
+  {
+    return fInBound;
+  }
+
+  /**
+   * Returns the changed rel name 
+  **/
+  public String getOutBoundRelName()
+  {
+    return fOutBound.getRel().getName();
+  }
+
+  /**
+   * Returns the changed rel
+  **/
+  public Rel getOutBoundRel()
+  {
+    return fOutBound.getRel();
+  }
+
+  /**
+   * Returns the changed rel name 
+  **/
+  public String getInBoundRelName()
+  {
+    return fInBound.getRel().getName();
+  }
+
+  /**
+   * Returns the changed rel
+  **/
+  public Rel getInBoundRel()
+  {
+    return fInBound.getRel();
+  }
+  
+
+  /**
+   * Returns the outbound element that changed 
+  **/
+  public Element getOutBoundElement ()
+  {
+    return fOutBound.getElement();
+  }
+
+  
+  /**
+   * Returns the inbound connection that changed 
+  **/
+  public Element getInboundElement ()
+  {
+    return fInBound.getElement();
+  }
+  
+
+  
+}
+
+
diff --git a/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/wsil/AddWSDLToWSILCommand.java b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/wsil/AddWSDLToWSILCommand.java
new file mode 100644
index 0000000..c51875c
--- /dev/null
+++ b/bundles/org.eclipse.wst.ws/src/org/eclipse/wst/ws/internal/wsil/AddWSDLToWSILCommand.java
@@ -0,0 +1,540 @@
+/*******************************************************************************
+ * Copyright (c) 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.ws.internal.wsil;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import javax.wsdl.Definition;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.wsil.Abstract;
+import org.apache.wsil.Description;
+import org.apache.wsil.Inspection;
+import org.apache.wsil.QName;
+import org.apache.wsil.Service;
+import org.apache.wsil.WSILDocument;
+import org.apache.wsil.WSILException;
+import org.apache.wsil.extension.ExtensionBuilder;
+import org.apache.wsil.extension.wsdl.ImplementedBinding;
+import org.apache.wsil.extension.wsdl.Reference;
+import org.apache.wsil.extension.wsdl.ReferencedService;
+import org.apache.wsil.extension.wsdl.WSDLConstants;
+import org.apache.wsil.xml.XMLWriter;
+import org.eclipse.wst.command.env.core.SimpleCommand;
+import org.eclipse.wst.command.env.core.common.Environment;
+import org.eclipse.wst.command.env.core.common.SimpleStatus;
+import org.eclipse.wst.command.env.core.common.Status;
+import org.eclipse.wst.command.env.core.uri.URIException;
+import org.eclipse.wst.command.env.core.uri.URIFactory;
+import org.eclipse.wst.ws.parser.wsil.IllegalArgumentsException;
+import org.eclipse.wst.ws.parser.wsil.WWWAuthenticationException;
+import org.eclipse.wst.ws.parser.wsil.WWWAuthenticationHandler;
+import org.eclipse.wst.ws.parser.wsil.WebServicesParser;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+public class AddWSDLToWSILCommand extends SimpleCommand
+{
+  public static final String ARG_WSIL = "-wsil";
+  public static final String ARG_WSDL = "-wsdl";
+  public static final String ARG_RESOLVE_WSDL = "-resolvewsdl";
+  public static final String ARG_HTTP_BASIC_AUTH_USERNAME = "-httpusername";
+  public static final String ARG_HTTP_BASIC_AUTH_PASSWORD = "-httppassword";
+  private final String id = "org.eclipse.wst.ws.parser.wsil.AddWSDLToWSILCommand";
+  private ResourceBundle resBundle_;
+  private WWWAuthenticationHandler wwwAuthHandler_;
+  private String[] args_;
+  private String wsil_;
+  private ArrayList wsdls_;
+  private boolean resolveWSDL_;
+  private String httpUsername_;
+  private String httpPassword_;
+
+  public AddWSDLToWSILCommand()
+  {
+    super("org.eclipse.wst.ws.parser.wsil.AddWSDLToWSILCommand", "org.eclipse.wst.ws.parser.wsil.AddWSDLToWSILCommand");
+    resBundle_ = ResourceBundle.getBundle("org.eclipse.wst.ws.parser.wsil.wsil");
+    wwwAuthHandler_ = null;
+    args_ = new String[0];
+    clearParsedArgs();
+  }
+
+  private void clearParsedArgs()
+  {
+    wsil_ = null;
+    if (wsdls_ == null)
+      wsdls_ = new ArrayList();
+    else
+      wsdls_.clear();
+    resolveWSDL_ = false;
+    httpUsername_ = null;
+    httpPassword_ = null;
+  }
+
+  /**
+   * Executes the Command.
+   * 
+   * @param environment
+   *            The environment. Must not be null.
+   * @return A <code>Status</code> object indicating the degree to which the
+   *         <code>execute</code> method was successful. A valud of <code>null</code>,
+   *         or a Status with a severity of less than <code>Status.ERROR</code>
+   *         signifies success.
+   */
+  public Status execute(Environment environment)
+  {
+    URIFactory uriFactory = environment.getURIFactory();
+    // Parse arguments
+    try
+    {
+      parseArguments();
+    }
+    catch (IllegalArgumentsException iae)
+    {
+      return new SimpleStatus(id, resBundle_.getString("MSG_ERROR_ILLEGAL_ARGUMENTS"), Status.ERROR, iae);
+    }
+    catch (ArrayIndexOutOfBoundsException e)
+    {
+      return new SimpleStatus(id, resBundle_.getString("MSG_ERROR_INVALID_ARGUMENTS"), Status.ERROR, e);
+    }
+    // Create new WSIL document
+    WSILDocument wsilDocument = null;
+    URL wsilURL = null;
+    try
+    {
+      wsilDocument = WSILDocument.newInstance();
+      wsilURL = new URL(wsil_);
+    }
+    catch (MalformedURLException murle)
+    {
+      Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_INVALID_WSIL_URI"), Status.ERROR, murle);
+      environment.getStatusHandler().reportError(status);
+      return status;
+    }
+    catch (WSILException wsile)
+    {
+      Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_UNEXPECTED_EXCEPTION"), Status.ERROR, wsile);
+      environment.getStatusHandler().reportError(status);
+      return status;
+    }
+    // Read WSIL
+    try
+    {
+      InputStream is = uriFactory.newURI(wsilURL).getInputStream();
+      if (is != null)
+      {
+        wsilDocument.read(new InputStreamReader(is));
+        is.close();
+      }
+    }
+    catch (URIException urie)
+    {
+      Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_UNEXPECTED_EXCEPTION"), Status.ERROR, urie);
+      environment.getStatusHandler().reportError(status);
+      return status;
+    }
+    catch (IOException ioe)
+    {
+      Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_UNEXPECTED_EXCEPTION"), Status.ERROR, ioe);
+      environment.getStatusHandler().reportError(status);
+      return status;
+    }
+    catch (WSILException wsile)
+    {
+      Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_UNEXPECTED_EXCEPTION"), Status.ERROR, wsile);
+      environment.getStatusHandler().reportError(status);
+      return status;
+    }
+    // internalExecute
+    String httpUsername = null;
+    String httpPassword = null;
+    if (wsdls_.size() == 1 && httpUsername_ != null && httpPassword_ != null)
+    {
+      httpUsername = httpUsername_;
+      httpPassword = httpPassword_;
+    }
+    for (Iterator it = wsdls_.iterator(); it.hasNext();)
+    {
+      String wsdl = (String) it.next();
+      Status status = null;
+      try
+      {
+        status = internalExecute(environment, wsilDocument, platform2File(uriFactory, wsil_), wsdl, httpUsername, httpPassword);
+      }
+      catch (WWWAuthenticationException wwwae)
+      {
+        if (wwwAuthHandler_ != null && httpUsername == null && httpPassword == null)
+        {
+          wwwAuthHandler_.handleWWWAuthentication(wwwae);
+          String handlerUsername = wwwAuthHandler_.getUsername();
+          String handlerPassword = wwwAuthHandler_.getPassword();
+          if (handlerUsername != null && handlerPassword != null)
+          {
+            try
+            {
+              status = internalExecute(environment, wsilDocument, platform2File(uriFactory, wsil_), wsdl, handlerUsername, handlerPassword);
+            }
+            catch (WWWAuthenticationException wwwae2)
+            {
+              Status wwwaeStatus = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_UNRESOLVABLE_WSDL"), Status.ERROR, wwwae2.getIOException());
+              environment.getStatusHandler().reportError(wwwaeStatus);
+              return wwwaeStatus;
+            }
+          }
+        }
+        if (status == null)
+        {
+          Status s = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_UNRESOLVABLE_WSDL"), Status.ERROR, wwwae.getIOException());
+          environment.getStatusHandler().reportError(s);
+          return s;
+        }
+      }
+      if (status.getSeverity() != Status.OK)
+        return status;
+    }
+    // Write WSIL
+    try
+    {
+      XMLWriter xmlWriter = new XMLWriter();
+      OutputStream os = uriFactory.newURI(wsilURL).getOutputStream();
+      if (os != null)
+        xmlWriter.writeDocument(wsilDocument, os);
+      else
+        throw new IOException();
+      os.close();
+    }
+    catch (URIException urie)
+    {
+      Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_WRITE_WSIL"), Status.ERROR, urie);
+      environment.getStatusHandler().reportError(status);
+      return status;
+    }
+    catch (IOException ioe)
+    {
+      Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_WRITE_WSIL"), Status.ERROR, ioe);
+      environment.getStatusHandler().reportError(status);
+      return status;
+    }
+    catch (WSILException wsile)
+    {
+      Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_WRITE_WSIL"), Status.ERROR, wsile);
+      environment.getStatusHandler().reportError(status);
+      return status;
+    }
+    return new SimpleStatus(id, "", Status.OK, null);
+  }
+
+  private Status internalExecute(Environment environment, WSILDocument wsilDocument, String wsil, String wsdl, String httpUsername, String httpPassword) throws WWWAuthenticationException
+  {
+    Definition definition = null;
+    ArrayList wsdlService = new ArrayList();
+    ArrayList wsdlBinding = new ArrayList();
+    if (resolveWSDL_)
+    {
+      // Parse WSDL
+      try
+      {
+        definition = parseWSDL(wsdl, wsdlService, wsdlBinding, httpUsername, httpPassword);
+      }
+      catch (MalformedURLException murle)
+      {
+        Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_INVALID_WSDL_URI"), Status.ERROR, murle);
+        environment.getStatusHandler().reportError(status);
+        return status;
+      }
+      catch (IOException ioe)
+      {
+        Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_UNRESOLVABLE_WSDL"), Status.ERROR, ioe);
+        environment.getStatusHandler().reportError(status);
+        return status;
+      }
+      catch (ParserConfigurationException pce)
+      {
+        Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_UNEXPECTED_EXCEPTION"), Status.ERROR, pce);
+        environment.getStatusHandler().reportError(status);
+        return status;
+      }
+      catch (SAXException saxe)
+      {
+        Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_MALFORMED_WSDL"), Status.ERROR, saxe);
+        environment.getStatusHandler().reportError(status);
+        return status;
+      }
+    }
+    // Add WSDL to WSIL
+    try
+    {
+      Inspection inspection = wsilDocument.getInspection();
+      Service service = wsilDocument.createService();
+      if (definition != null)
+      {
+        Element documentation = definition.getDocumentationElement();
+        Abstract serviceAbstract = wsilDocument.createAbstract();
+        serviceAbstract.setText(Element2String(documentation));
+        service.addAbstract(serviceAbstract);
+      }
+      Description desc = wsilDocument.createDescription();
+      desc.setReferencedNamespace(WSDLConstants.NS_URI_WSDL);
+      desc.setLocation(getRelativeURI(wsil, wsdl));
+      ExtensionBuilder extBuilder = wsilDocument.getExtensionRegistry().getBuilder(WSDLConstants.NS_URI_WSIL_WSDL);
+      if (definition == null || endpointPresent(definition))
+      {
+        for (Iterator it = wsdlService.iterator(); it.hasNext();)
+        {
+          Reference reference = (Reference) extBuilder.createElement(new QName(WSDLConstants.NS_URI_WSIL_WSDL, WSDLConstants.ELEM_REFERENCE));
+          reference.setEndpointPresent(new Boolean(true));
+          ReferencedService refService = (ReferencedService) extBuilder.createElement(new QName(WSDLConstants.NS_URI_WSIL_WSDL, WSDLConstants.ELEM_REF_SERVICE));
+          refService.setReferencedServiceName((QName) it.next());
+          reference.setReferencedService(refService);
+          desc.setExtensionElement(reference);
+        }
+      }
+      else
+      {
+        Reference reference = (Reference) extBuilder.createElement(new QName(WSDLConstants.NS_URI_WSIL_WSDL, WSDLConstants.ELEM_REFERENCE));
+        reference.setEndpointPresent(new Boolean(false));
+        for (Iterator it = wsdlBinding.iterator(); it.hasNext();)
+        {
+          ImplementedBinding binding = (ImplementedBinding) extBuilder.createElement(new QName(WSDLConstants.NS_URI_WSIL_WSDL, WSDLConstants.ELEM_IMPL_BINDING));
+          binding.setBindingName((QName) it.next());
+          reference.addImplementedBinding(binding);
+        }
+      }
+      service.addDescription(desc);
+      inspection.addService(service);
+    }
+    catch (WSILException wsile)
+    {
+      Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_UNEXPECTED_EXCEPTION"), Status.ERROR, wsile);
+      environment.getStatusHandler().reportError(status);
+      return status;
+    }
+    catch (Throwable t)
+    {
+      Status status = new SimpleStatus(id, resBundle_.getString("MSG_ERROR_UNEXPECTED_EXCEPTION"), Status.ERROR, t);
+      environment.getStatusHandler().reportError(status);
+      return status;
+    }
+    return new SimpleStatus(id, "", Status.OK, null);
+  }
+
+  /**
+   * Returns <code>true</code> if, and only if, the Command's <code>undo</code>
+   * method is supported.
+   * 
+   * @return True if the Command supports being undone.
+   */
+  public boolean isUndoable()
+  {
+    return false;
+  }
+
+  /**
+   * Undoes the Command.
+   * 
+   * @param environment
+   *            The environment. Must not be null.
+   * @return A <code>Status</code> object indicating the degree to which the
+   *         <code>undo</code> method was successful. A valud of <code>null</code>,
+   *         or a Status with a severity of less than <code>Status.ERROR</code>
+   *         signifies success.
+   */
+  public Status undo(Environment environment)
+  {
+    return new SimpleStatus(id, "", Status.OK, null);
+  }
+
+  /**
+   * Re-executes the Command.
+   * 
+   * @param environment
+   *            The environment. Must not be null.
+   * @return A <code>Status</code> object indicating the degree to which the
+   *         <code>redo</code> method was successful. A value of <code>null</code>,
+   *         or a Status with a severity of less then <code>Status.ERROR</code>
+   *         signifies success.
+   */
+  public Status redo(Environment environment)
+  {
+    return execute(environment);
+  }
+
+  private Definition parseWSDL(String wsdl, ArrayList wsdlService, ArrayList wsdlBinding, String httpUsername, String httpPassword) throws MalformedURLException, IOException, ParserConfigurationException, SAXException, WWWAuthenticationException
+  {
+    WebServicesParser wsParser = new WebServicesParser(wsdl);
+    if (httpUsername != null && httpPassword != null)
+    {
+      wsParser.setHTTPBasicAuthUsername(httpUsername);
+      wsParser.setHTTPBasicAuthPassword(httpPassword);
+    }
+    wsParser.parse(WebServicesParser.PARSE_NONE);
+    Definition definition = wsParser.getWSDLDefinition(wsdl);
+    if (definition != null)
+    {
+      Map services = definition.getServices();
+      for (Iterator it = services.keySet().iterator(); it.hasNext();)
+        wsdlService.add(parseQName((javax.xml.namespace.QName) it.next()));
+      Map bindings = definition.getBindings();
+      for (Iterator it = bindings.keySet().iterator(); it.hasNext();)
+        wsdlBinding.add(parseQName((javax.xml.namespace.QName) it.next()));
+    }
+    return definition;
+  }
+
+  private boolean endpointPresent(Definition definition)
+  {
+    return (definition.getServices().size() > 0);
+  }
+
+  public String[] getArguments()
+  {
+    return args_;
+  }
+
+  public void setArguments(String[] args)
+  {
+    args_ = args;
+  }
+
+  public WWWAuthenticationHandler getWWWAuthenticationHandler()
+  {
+    return wwwAuthHandler_;
+  }
+
+  public void setWWWAuthenticationHandler(WWWAuthenticationHandler wwwAuthHandler)
+  {
+    wwwAuthHandler_ = wwwAuthHandler;
+  }
+
+  private void parseArguments() throws IllegalArgumentsException
+  {
+    clearParsedArgs();
+    for (int i = 0; i < args_.length; i++)
+    {
+      if (ARG_WSIL.equals(args_[i]))
+        wsil_ = args_[++i];
+      else if (ARG_WSDL.equals(args_[i]))
+        wsdls_.add(args_[++i]);
+      else if (ARG_RESOLVE_WSDL.equals(args_[i]))
+        resolveWSDL_ = true;
+      else if (ARG_HTTP_BASIC_AUTH_USERNAME.equals(args_[i]))
+        httpUsername_ = args_[++i];
+      else if (ARG_HTTP_BASIC_AUTH_PASSWORD.equals(args_[i]))
+        httpPassword_ = args_[++i];
+      else
+        throw new IllegalArgumentsException(args_[i]);
+    }
+  }
+
+  private QName parseQName(String qnameString)
+  {
+    int colonIndex = qnameString.indexOf(':');
+    String ns = (colonIndex != -1) ? qnameString.substring(0, colonIndex) : "";
+    String localpart = (colonIndex != -1) ? qnameString.substring(colonIndex + 1, qnameString.length()) : qnameString;
+    return new QName(ns, localpart);
+  }
+
+  private QName parseQName(javax.xml.namespace.QName qname)
+  {
+    return new QName(qname.getNamespaceURI(), qname.getLocalPart());
+  }
+
+  private String Element2String(Element e) throws TransformerConfigurationException, TransformerException, IOException
+  {
+    byte[] b = new byte[0];
+    if (e != null)
+    {
+      DOMSource domSource = new DOMSource(e);
+      Transformer serializer = TransformerFactory.newInstance().newTransformer();
+      serializer.setOutputProperty(OutputKeys.INDENT, "yes");
+      serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      serializer.transform(domSource, new StreamResult(baos));
+      baos.close();
+      b = baos.toByteArray();
+    }
+    return new String(b);
+  }
+
+  private String platform2File(URIFactory uriFactory, String uri)
+  {
+    try
+    {
+      return uriFactory.newURI(uri).asFile().toURL().toString();
+    }
+    catch (Throwable t)
+    {
+      t.printStackTrace();
+    }
+    return uri;
+  }
+
+  private final char FWD_SLASH = '/';
+  private final char BWD_SLASH = '\\';
+  private final String parentDir = "../";
+
+  private String getRelativeURI(String baseURI, String targetURI)
+  {
+    try
+    {
+      String baseURICopy = baseURI.replace(BWD_SLASH, FWD_SLASH);
+      String targetURICopy = targetURI.replace(BWD_SLASH, FWD_SLASH);
+      int matchingIndex = -1;
+      int index = targetURICopy.indexOf(FWD_SLASH);
+      while (index != -1)
+      {
+        if (baseURICopy.startsWith(targetURICopy.substring(0, index + 1)))
+        {
+          matchingIndex = index;
+          index = targetURICopy.indexOf(FWD_SLASH, index + 1);
+        }
+        else
+          break;
+      }
+      if (matchingIndex != -1)
+      {
+        int slashCount = -1;
+        int fromIndex = matchingIndex;
+        while (fromIndex != -1)
+        {
+          slashCount++;
+          fromIndex = baseURICopy.indexOf(FWD_SLASH, fromIndex + 1);
+        }
+        StringBuffer relativeURI = new StringBuffer();
+        for (int i = 0; i < slashCount; i++)
+          relativeURI.append(parentDir);
+        relativeURI.append(targetURI.substring(matchingIndex + 1, targetURI.length()));
+        return relativeURI.toString();
+      }
+    }
+    catch (Throwable t)
+    {
+    }
+    return targetURI;
+  }
+}
\ No newline at end of file