Index: trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentContainer.java
===================================================================
--- trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentContainer.java	(revision 12245)
+++ trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentContainer.java	(revision 12247)
@@ -27,4 +27,14 @@
 package org.greenstone.gatherer.cdm;
 
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import org.greenstone.gatherer.DebugStream;
+import org.greenstone.gatherer.util.StaticStrings;
+import org.w3c.dom.*;
+
 /**************************************************************************************
  * Written:      20/05/02
@@ -37,22 +47,250 @@
  * @version 2.3
  */
-public interface ArgumentContainer {
+abstract public class ArgumentContainer 
+    extends ArrayList 
+    implements Comparable, DOMProxyListEntry, Serializable  {
+
+    // The DOM Element this container is modelled on
+    protected Element element;
+    protected boolean is_abstract = false;
+    protected ArgumentContainer super_container;
+    // should be set by the constructor
+    protected String display_name = "Unknown";
+    protected String description;
+    protected String name;
+
+    /** Constructor used in DOMProxyListModel initializations
+     */
+    public ArgumentContainer() {
+    }
+
+    public ArgumentContainer(Element element, ArgumentContainer base_container) {
+
+	super();
+	this.element = element;
+	this.name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
+
+	// Parse in any argument options for this container, keeping a list of the ones found
+	HashMap known_arguments = new HashMap();
+	NodeList option_elements = element.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
+	int option_elements_length = option_elements.getLength();
+	for(int i = 0; i < option_elements_length; i++) {
+	    Element option_element = (Element) option_elements.item(i);
+	    Argument argument = new Argument(option_element);
+	    ///ystem.err.println("Rebuilding existing argument: " + argument.getName());
+	    known_arguments.put(argument.getName(), argument);
+	}
+	// If a base classifier was given
+	if(base_container != null) {
+	    // Copy the details, and add a reference to whatever the base container's super container is
+	    description = base_container.getDescription();
+	    // Now search through the 'dummy' arguments belonging to the base container. For each found, if it is already assigned, fill out further details such as type. If any are found that are not already assigned for this container, copy them and add them, but without a value.
+	    ArrayList all_arguments = base_container.getArguments();
+	    int argument_count = all_arguments.size();
+	    for(int j = 0; j < argument_count; j++) {
+		Argument base_argument = (Argument) all_arguments.get(j);
+		String base_argument_name = base_argument.getName();
+		///ystem.err.println("Library indicates this container should have an argument: " + base_argument_name);
+		Argument existing_argument = (Argument) known_arguments.get(base_argument_name);
+		// Found an existing argument. Complete its details
+		if(existing_argument != null) {
+		    ///ystem.err.println("Found existing argument. Filling out details.");
+		    known_arguments.remove(base_argument_name);
+		    existing_argument.setDefaultValue(base_argument.getDefaultValue());
+		    existing_argument.setDescription(base_argument.getDescription());
+		    existing_argument.setOptions(base_argument.getOptions());
+		    existing_argument.setRequired(base_argument.isRequired());
+		    existing_argument.setType(base_argument.getType());
+		    existing_argument.setMinimum(base_argument.getMinimum());
+		    existing_argument.setMaximum(base_argument.getMaximum());
+		    existing_argument.setOwner(base_argument.getOwner());
+		    existing_argument.setHiddenGLI(base_argument.isHiddenGLI());
+		    add(existing_argument);
+		}
+		// No existing argument. Copy base_argument and add it, but set its assigned flag to false 
+		else {
+		    ///atherer.println("No such argument. Adding new, unassigned, argument.");
+		    // The trick thing is that we have to create a new element in the DOM as well.
+		    Argument new_argument = base_argument.copy();
+		    Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT);
+		    argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, base_argument_name);
+		    argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
+		    new_argument.setElement(argument_element);
+		    // All done. Add it.
+		    element.appendChild(argument_element);
+		    add(new_argument);
+		}
+	    }
+	}
+	
+	// The first time we do this, the args come from the config file and
+	// may contain invalid args. Here we remove them from the DOM.
+	if (!known_arguments.isEmpty()) {
+	    Set entry_set = known_arguments.entrySet();
+	    Iterator entry_iterator = entry_set.iterator();
+	    while (entry_iterator.hasNext()) {
+		Argument arg = (Argument)((Map.Entry)entry_iterator.next()).getValue();
+		Element e = arg.getElement();
+		element.removeChild(e);
+	    }
+	}
+    }
+
+
+    
+
+    /** Constructor used for the plugins that are in the DOMProxyList */
+    /** Method to add an argument to this container. Only adds the argument if it isn't already present.
+     * @param argument The <strong>Argument</strong> to add.
+     */
+    public void addArgument(Argument argument) {
+	if(element == null && !contains(argument)) {
+	    add(argument);
+	    argument.setOwner(name);
+	}
+    }
+
+    /** Method to compare two containers for ordering.
+     * @param object The container we are comparing to, as an <strong>Object</strong>.
+     * @return An <i>int</i> specifying the container order, using values as set out in String.
+     * @see java.lang.String#compareTo
+     */
+    public int compareTo(Object object) {
+	if(object == null ) {
+	    return -1;
+	}
+	return toString().compareTo(object.toString());
+    }
+
+    /** Method to determine if two containers are equal.
+     * @param object The container to test against, as an <strong>Object</strong>.
+     * @return <i>true</i> if they match (based on the equals method), <i>false</i> otherwise.
+     */
+
+    public boolean equals(Object object) {
+	return (compareTo(object) == 0);
+    }
+
+    abstract public DOMProxyListEntry create(Element element);
+    /** Method to retrieve an argument by its name.
+     * @param name The name of the argument as a <strong>String</strong>.
+     * @return The <strong>Argument</strong> requested, or <i>null</i> if no such argument.
+     */
+    public Argument getArgument(String name) {
+	// The name given may still include the '-'
+	if(name.startsWith("-")) {
+	    name = name.substring(1);
+	}
+	//ArrayList arguments = getArguments(true, true);
+	ArrayList arguments = getArguments();
+	for(int i = 0; i < arguments.size(); i++) {
+	    Argument argument = (Argument)arguments.get(i);
+	    if(argument.getName().equals(name)) {
+		return argument;
+	    }
+	}
+	return null;
+    }
+
     /** Method to retrieve the list of arguments from this container. Note that this method returns both the containers arguments plus its 'supers' arguments if any, and alphabetically orders them.
-     * @param include_normal true to filter so normal arguments are returned
-     * @param include_custom true to filter so custom arguments are returned
      * @return the arguments within a ArrayList
      */
-    public ArrayList getArguments(boolean include_normal, boolean include_custom);
-    /** Method to retrieve this containers custom argument string.
-     * @return the custom arguments as a String
-     */
-    public String getCustom();
+    public ArrayList getArguments() {
+	ArrayList arguments = new ArrayList();
+	arguments.addAll(this);
+	if(super_container != null) {
+	    ArrayList remainder = super_container.getArguments();
+	    remainder.removeAll(arguments);
+	    arguments.addAll(remainder);
+	}
+	return arguments;
+
+    }
+
+    public String getDescription() {
+	return description;
+    }
+
+    public Element getElement() {
+	return element;
+    }
     /** Method to retrieve the name associated with this argument container.
      * @return the name as a String
      */
-    public String getName();
-    /** Method to set the custom arguments string.
-     * @param custom the new custom argument String
-     */
-    public void setCustom(String custom);
+    public String getName() {
+	if(name == null && element != null) {
+	    name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
+	}
+	return name;
+    }
+
+    public boolean isAbstract() {
+	return is_abstract;
+    }
+
+    public boolean isAssigned() {
+	return (element != null && !element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.FALSE_STR));
+    }
+
+    public void setAssigned(boolean assigned) {
+	if(element != null) {
+	    element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (assigned ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR));
+	}
+    }
+
+    public void setDescription(String description) {
+	this.description = description;
+    }
+
+    public void setElement(Element element) {
+	this.element = element;
+    }
+
+    public void setIsAbstract(boolean is_abstract) {
+	this.is_abstract = is_abstract;
+    }
+
+    public void setName(String name) {
+	this.name = name;
+    }
+
+    /** Method to set the value of the super_container.
+     * @param super_container The new value of super_container as a <strong>ArgumentContainer</strong>, or <i>null</i> if this class has no inheritance.
+     */
+    public void setSuper(ArgumentContainer super_container) {
+	this.super_container = super_container;
+    }
+
+    public String toString()
+    {
+	if (element == null) {
+	    return name;
+	}
+
+	if (name == null) {
+	    name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
+	}
+
+	StringBuffer text;
+	if (isAssigned()) {
+	    text = new StringBuffer(display_name);
+	} else {
+	    text = new StringBuffer("#");
+	    text.append(display_name);
+	}
+	text.append(" ");
+	text.append(name);
+
+	ArrayList arguments = getArguments();
+	for (int i = 0; i < arguments.size(); i++) {
+	    Argument argument = (Argument) arguments.get(i);
+	    if (argument.isAssigned()) {
+		text.append(" ");
+		text.append(argument.toString());
+	    }
+	}
+
+	return text.toString();
+    }
+
 }
Index: trunk/gli/src/org/greenstone/gatherer/cdm/Classifier.java
===================================================================
--- trunk/gli/src/org/greenstone/gatherer/cdm/Classifier.java	(revision 12245)
+++ trunk/gli/src/org/greenstone/gatherer/cdm/Classifier.java	(revision 12247)
@@ -43,21 +43,8 @@
  */
 public class Classifier
-    extends ArrayList
-    implements ArgumentContainer, Comparable, DOMProxyListEntry, Serializable {
+    extends ArgumentContainer {
+    
 
     static final public String CLASSIFIER_PREFIX = "CL";
-
-    private boolean is_abstract = false;
-
-    /** A reference to the classifier that this one inherits from. */
-    private Classifier super_classifier = null;
-    /** The element this classifier is based upon. */
-    private Element element;
-    /** A description of this classifier. */
-    private String description = null;
-    /** The name of the classifier as it would appear in the collect.cfg file. */
-    private String name = null;
-    /** This string is filled out the first time this classifier is created, and remains unchanged there-after. It is used to match up with Format commands that may not yet have been instantiated (and thus only have offline references along the lines of 'CL1' to figure out what Classifier they want.) */
-    private String old_position_string = null;
 
     /** Constructor used only in DOMProxyListModel initializations.
@@ -65,98 +52,7 @@
     public Classifier() {
     }
-
+    
     public Classifier(Element element, Classifier base_classifier) {
-	super();
-	this.element = element;
-	this.name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
-	///atherer.println("Establishing Classifier: " + name);
-	// Parse in any argument options for this classifier, keeping a list of the ones found
-	HashMap known_arguments = new HashMap();
-	NodeList option_elements = element.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
-	int option_elements_length = option_elements.getLength();
-	for(int i = 0; i < option_elements_length; i++) {
-	    Element option_element = (Element) option_elements.item(i);
-	    Argument argument = new Argument(option_element);
-	    ///atherer.println("Rebuilding existing argument: " + argument.getName());
-	    argument.setOwner(name);
-	    add(argument);
-	    known_arguments.put(argument.getName(), argument);
-	}
-	// If a base classifier was given
-	if(base_classifier != null) {
-	    // Copy the details, and add a reference to whatever base_classifiers super classifier is.
-	    description = base_classifier.getDescription();
-	    // Now search through the 'dummy' arguments belonging to the base classifier. For each found, if it is already assigned, fill out further details such as type. If any are found that are not already assigned for this classifier, copy them and add them, but without a value.
-	    ArrayList all_arguments = base_classifier.getArguments(true, true);
-	    int argument_count = all_arguments.size();
-	    for(int j = 0; j < argument_count; j++) {
-		Argument base_argument = (Argument) all_arguments.get(j);
-		String base_argument_name = base_argument.getName();
-		///atherer.println("Library indicates this classifier should have an argument: " + base_argument_name);
-		Argument existing_argument = (Argument) known_arguments.get(base_argument_name);
-		// Found an existing argument. Complete its details
-		if(existing_argument != null) {
-		    ///atherer.println("Found existing argument. Filling out details.");
-		    existing_argument.setCustomArgument(false);
-		    existing_argument.setDefaultValue(base_argument.getDefaultValue());
-		    existing_argument.setDescription(base_argument.getDescription());
-		    existing_argument.setOptions(base_argument.getOptions());
-		    existing_argument.setRequired(base_argument.isRequired());
-		    existing_argument.setType(base_argument.getType());
-		    existing_argument.setOwner(base_argument.getOwner());
-		    existing_argument.setHiddenGLI(base_argument.isHiddenGLI());
-		}
-		// No existing argument. Copy base_argument and add it, but do not set its assigned flag. That should be set the first time its changed by the user.
-		else {
-		    ///atherer.println("No such argument. Adding new, unassigned, argument.");
-		    // The trick thing is that we have to create a new element in the DOM as well.
-		    Argument new_argument = base_argument.copy();
-		    //new_argument.setOwner(name);
-		    Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT);
-		    argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, base_argument_name);
-		    argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
-		    argument_element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, StaticStrings.FALSE_STR);
-		    new_argument.setElement(argument_element);
-		    // All done. Add it.
-		    element.appendChild(argument_element);
-		    add(new_argument);
-		}
-	    }
-	}
-	old_position_string = getPositionString();
-    }
-
-    /** Constructor.
-     * @param name The name of this classifier as a <strong>String</strong>.
-     * @param description A description of this classifier as a <strong>String</strong>.
-     * @param super_classifier The super class of this classifier, as a <strong>Classifier</strong>.
-     */
-    public Classifier(String name, String description, Classifier super_classifier) {
-	super();
-	this.description = description;
-	this.name = name;
-	this.super_classifier = super_classifier;
-    }
-
-    /** Method to add an argument to this classifier. Only adds the argument if it isn't already present.
-     * @param argument The <strong>Argument</strong> to add.
-     */
-    public void addArgument(Argument argument) {
-	if(element == null && !contains(argument)) {
-	    add(argument);
-	    argument.setOwner(name);
-	}
-    }
-
-    /** Method to compare two classifiers for ordering.
-     * @param object The classifier we are comparing to, as an <strong>Object</strong>.
-     * @return An <i>int</i> specifying the classifier order, using values as set out in String.
-     * @see java.lang.String#compareTo
-     */
-    public int compareTo(Object object) {
-	if(object == null) {
-	    return -1;
-	}
-	return toString().compareTo(object.toString());
+	super(element, base_classifier);
     }
 
@@ -169,112 +65,12 @@
 	Classifier base_classifier = CollectionDesignManager.classifier_manager.getBaseClassifier(classifier_name);
 	Classifier classifier = new Classifier(element, base_classifier);
+	if (base_classifier == null) {
+	    // this is kind of a place holder classifier for one which is invalid. It won't get written out to the config file when its next saved.
+	    classifier.setAssigned(false);
+	}
 	base_classifier = null;
 	classifier_name = null;
 	return classifier;
     }
-
-    /** Method to determine if two classifiers are equal.
-     * @param object The classifier to test against, as an <strong>Object</strong>.
-     * @return <i>true</i> if the classifier names match, <i>false</i> otherwise.
-     */
-    public boolean equals(Object object) {
-	return (compareTo(object) == 0);
-    }
-
-    /** Method to retrieve an argument by its name.
-     * @param name The name of the argument as a <strong>String</strong>.
-     * @return The <strong>Argument</strong> requested, or <i>null</i> if no such argument.
-     */
-    public Argument getArgument(String name) {
-	// The name given may still include the '-'
-	if(name.startsWith("-")) {
-	    name = name.substring(1);
-	}
-	ArrayList arguments = getArguments(true, true);
-	for(int i = 0; i < arguments.size(); i++) {
-	    Argument argument = (Argument)arguments.get(i);
-	    if(argument.getName().equals(name)) {
-		return argument;
-	    }
-	}
-	return null;
-    }
-
-     /** Retrieve all of the arguments available to this base classifier, including its super classifiers arguments. Some complexity is added by allowing the caller to choose whether they want normal arguments, custom arguments, or both.
-      * @return an ArrayList of all of the arguments, starting with those for this classifier and ending with the arguments for basplug or similiar root classifier
-      */
-    public ArrayList getArguments(boolean include_normal, boolean include_custom) {
-	ArrayList arguments = new ArrayList();
-	if(include_normal && include_custom) {
-	    arguments.addAll(this);
-	}
-	else {
-	    int size = size();
-	    for(int i = 0; i < size; i++) {
-		Argument argument = (Argument) get(i);
-		if(argument.isCustomArgument()) {
-		    if(include_custom && !arguments.contains(argument)) {
-			arguments.add(argument);
-		    }
-		}
-		else {
-		    if(include_normal && !arguments.contains(argument)) {
-			arguments.add(argument);
-		    }
-		}
-		argument = null;
-	    }
-	}
-	if(super_classifier != null) {
-	    ArrayList remainder = super_classifier.getArguments(include_normal, include_custom);
-	    remainder.removeAll(arguments);
-	    arguments.addAll(remainder);
-	}
-	return arguments;
-    }
-
-    /** Method to retrieve a classifiers custom argument information. Custom arguments are defined to be those that have not got matching arguments in the base reference classifier from the library. Of course if there is no base classifier then all arguments are considered to be custom.
-     * @return the custom arguments as a String
-     */
-    public String getCustom() {
-	StringBuffer custom_text = new StringBuffer();
-	// Retrieve all of the arguments, and append any that are custom into one long string
-	ArrayList arguments = getArguments(false, true);
-	int arguments_size = arguments.size();
-	boolean first = true;
-	for(int i = 0; i < arguments_size; i++) {
-	    Argument argument = (Argument) arguments.get(i);
-	    if(argument.isAssigned()) {
-		if(!first) {
-		    custom_text.append(" ");
-		}
-		custom_text.append(argument.toString());
-		first = false;
-	    }
-	}
-	return custom_text.toString();
-    }
-
-    public String getDescription() {
-	return description;
-    }
-
-    public Element getElement() {
-	return element;
-    }
-
-    /** Method to retrieve a classifiers name.
-     * @return A <strong>String</strong> containing the classifiers name.
-     */
-    public String getName() {
-	if(name == null && element != null) {
-	    name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
-	}
-	return name;
-    }
-
-    /* private String getOldPositionString() {
-	return old_position_string;
-	} */
 
     /** Generate the string showing this classifiers position. */
@@ -291,124 +87,3 @@
     }
 
-    public boolean isAbstract() {
-	return is_abstract;
-    }
-
-    public boolean isAssigned() {
-	return (element != null && !element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.FALSE_STR));
-    }
-
-    public void setAssigned(boolean assigned) {
-	if(element != null) {
-	    element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (assigned ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR));
-	}
-    }
-
-    /** Set the custom arguments. This turns out to be quite tricky. We must parse in the string, searching for arguments (for that we use a handy method in CollectionConfiguration). Next, for each argument, we check if we already know about it. If so we update its value, otherwise we create a new argument and assign it (must assign!).
-     * @param custom_str the custom arguments all splodged together in one String
-     */
-    public void setCustom(String custom_str) {
-	HashMap raw_arguments = CollectionConfiguration.parseArguments(new CommandTokenizer(custom_str));
-	ArrayList custom_arguments = getArguments(false, true);
-	int size = custom_arguments.size();
-	for(int i = 0; i < size; i++) {
-	    Argument argument = (Argument) custom_arguments.get(i);
-	    String original_argument_name = StaticStrings.MINUS_CHARACTER + argument.getName();
-	    if(raw_arguments.containsKey(original_argument_name)) {
-		// Set as assigned
-		argument.setAssigned(true);
-		String argument_value = (String)raw_arguments.remove(original_argument_name);
-		if(argument_value != null) {
-		    argument.setValue(argument_value);
-		    argument_value = null;
-		}
-	    }
-	    // We've removed it from our custom statement, so unassign
-	    else {
-		argument.setAssigned(false);
-	    }
-	    argument = null;
-	}
-	// Any left over, add to the classifier
-	Iterator argument_names = raw_arguments.keySet().iterator();
-	while(argument_names.hasNext()) {
-	    String argument_name = (String) argument_names.next();
-	    String argument_value = (String) raw_arguments.get(argument_name);
-	    // The tricky thing is that we have to create a new element in the DOM as well.
-	    Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT);
-	    argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, argument_name.substring(1));
-	    argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
-	    argument_element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, StaticStrings.TRUE_STR);
-	    Argument argument = new Argument(argument_element);
-	    argument_name = null;
-	    if(argument_value != null) {
-		argument.setValue(argument_value);
-		argument_value = null;
-	    }
-	    // All done. Add it.
-	    element.appendChild(argument_element);
-	    add(argument);
-	    argument_element = null;
-	}
-	raw_arguments = null;
-    }
-
-    /** Method to set the value of desc.
-     * @param description The new value of desc as a <strong>String</strong>.
-     */
-    public void setDescription(String description) {
-	this.description = description;
-    }
-
-    public void setElement(Element element) {
-	this.element = element;
-    }
-
-    public void setIsAbstract(boolean is_abstract) {
-	this.is_abstract = is_abstract;
-    }
-
-    /** Method to set the value of name.
-     * @param name The new value of name as a <strong>String</strong>.
-     */
-    public void setName(String name) {
-	this.name = name;
-    }
-
-    /** Method to set the value of the super_classifier.
-     * @param super_classifier The new value of super_classifier as a <strong>Classifier</strong>, or <i>null</i> if this class has no inheritance.
-     */
-    public void setSuper(Classifier super_classifier) {
-	this.super_classifier = super_classifier;
-    }
-
-
-    /** Method to print out this classifier as it would appear to the user in the interface
-     * @return A <strong>String</strong> containing a single classifier command.
-     */
-    public String toString()
-    {
-	if (element == null) {
-	    return name;
-	}
-
-	if (name == null) {
-	    name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
-	}
-
-	StringBuffer text = new StringBuffer(StaticStrings.CLASSIFY_STR);
-	text.append(" ");
-	text.append(name);
-
-	ArrayList arguments = getArguments(true, true);
-	for (int i = 0; i < arguments.size(); i++) {
-	    Argument argument = (Argument) arguments.get(i);
-	    if (argument.isAssigned()) {
-		text.append(" ");
-		text.append(argument.toString());
-	    }
-	}
-
-	return text.toString();
-    }
 }
Index: trunk/gli/src/org/greenstone/gatherer/cdm/Plugin.java
===================================================================
--- trunk/gli/src/org/greenstone/gatherer/cdm/Plugin.java	(revision 12245)
+++ trunk/gli/src/org/greenstone/gatherer/cdm/Plugin.java	(revision 12247)
@@ -35,15 +35,7 @@
 /** This class is responsible for storing information from a parsed pluginfo call in such a way that it allows easy access to parsed details for the purposes of user design and specification of plugins. */
 public class Plugin
-    extends ArrayList
-    implements ArgumentContainer, Comparable, DOMProxyListEntry, Serializable {
-    /** The DOM Element this assigned Plugin is modelled on. */
-    private Element element;
-    private boolean does_explode_metadata_databases = false; // Only for Base
-    private boolean is_abstract = false; // Only for Base
-    /** The parent Plugin this one inherits from, if any. */
-    private Plugin super_plugin; // Only for Base
-    private String description; // Only for Base
-    private String name; // Only for Base
-
+    extends ArgumentContainer {
+    private boolean does_explode_metadata_databases = false; 
+    
     /** Constructor used in DOMProxyListModel initializations, and Library Level. Used for Base plugins (those in the list of available plugins, not ones that are in the DOMProxyList)
      */
@@ -51,91 +43,10 @@
     }
     
-    /** Constructor used for the plugins that are in the DOMProxyList */
-    // Every time the list of plugins in the assigned plugins box changes, (eg plugin added or removed, not when plugin configured), the plugins seem to be regenerated, using the element from the old plugin. All known args get added to the element the first time this happens - we need to add them to the arguments list in the order they are found in the base plugins though, not this order.
     public Plugin(Element element, Plugin base_plugin) {
-	super();
-	this.element = element;
-	this.name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
-	//DebugStream.println("Establishing Plugin: " + name);
-	// Parse in any argument options for this plugin, keeping a list of the ones found
-	HashMap known_arguments = new HashMap();
-	NodeList option_elements = element.getElementsByTagName(StaticStrings.OPTION_ELEMENT);
-	int option_elements_length = option_elements.getLength();
-	for(int i = 0; i < option_elements_length; i++) {
-	    Element option_element = (Element) option_elements.item(i);
-	    Argument argument = new Argument(option_element);
-	    //DebugStream.println("Rebuilding existing argument: " + argument.getName());
-	    known_arguments.put(argument.getName(), argument);
-	    if (base_plugin == null) {
-		// otherwise they will all be added in the next step
-		argument.setOwner(name);
-		add(argument);
-	    } 
-	}
-	// If a base plugin was given
-	if(base_plugin != null) {
-	    //DebugStream.println("Based on previous plugin.");
-	    // Copy the details, and add a reference to whatever base_plugins super plugin is. ?? 
-	    description = base_plugin.getDescription();
-	    // Now search through the 'dummy' arguments belonging to the base plugin. For each found, if it is already assigned, fill out further details such as type. If any are found that are not already assigned for this plugin, copy them and add them, but without a value.
-	    ArrayList all_arguments = base_plugin.getArguments(true, true);
-	    int argument_count = all_arguments.size();
-	    for(int j = 0; j < argument_count; j++) {
-		Argument base_argument = (Argument) all_arguments.get(j);
-		String base_argument_name = base_argument.getName();
-		//DebugStream.println("Library indicates this plugin should have an argument: " + base_argument_name);
-		Argument existing_argument = (Argument) known_arguments.get(base_argument_name);
-		// Found an existing argument. Complete its details
-		if(existing_argument != null) {
-		    //DebugStream.println("Found existing argument. Filling out details.");
-		    existing_argument.setCustomArgument(false);
-		    existing_argument.setDefaultValue(base_argument.getDefaultValue());
-		    existing_argument.setDescription(base_argument.getDescription());
-		    existing_argument.setOptions(base_argument.getOptions());
-		    existing_argument.setRequired(base_argument.isRequired());
-		    existing_argument.setType(base_argument.getType());
-		    existing_argument.setMinimum(base_argument.getMinimum());
-		    existing_argument.setMaximum(base_argument.getMaximum());
-		    existing_argument.setOwner(base_argument.getOwner());
-		    existing_argument.setHiddenGLI(base_argument.isHiddenGLI());
-		    add(existing_argument); 
-		    
-		}
-		// No existing argument. Copy base_argument and add it, but do not set its assigned flag. That should be set the first time its changed by the user.
-		else {
-		    //DebugStream.println("No such argument. Adding new, unassigned, argument.");
-		    // The trick thing is that we have to create a new element in the DOM as well.
-		    Argument new_argument = base_argument.copy();
-		    Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT);
-		    argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, base_argument_name);
-		    argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR);
-		    argument_element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, StaticStrings.FALSE_STR);
-		    // All done. Add it.
-		    // if we are not in the first collection opened, then this 
-		    /// will belong to a different document, so need to import 
-		    // it.
-		    Node new_element = element.getOwnerDocument().importNode(argument_element, true);
-		    new_argument.setElement((Element) new_element);
-		    element.appendChild(new_element);
-		    add(new_argument);
-		}
-	    }
-	}
-    }
-
-    /** Method to add an argument to this base plugin. Only adds the argument if it isn't already present, and only if this is a base plugin (ie not based on DOM).
-     * @param argument the Argument to add
-     */
-    public void addArgument(Argument argument) {
-	if(element == null && !contains(argument)) {
-	    add(argument);
-	    argument.setOwner(name);
-	}
+	super(element, base_plugin);
     }
 
     /** Method to compare two plugins for ordering.
-     * @param object The plugin we are comparing to, as an <strong>Object</strong>.
-     * @return An <i>int</i> specifying the plugin order, using values as set out in <strong>String</strong>.
-     * @see java.lang.String#compareTo
+     * We override the base method cos we compare by plugin name rather than toString()
      */
     public int compareTo(Object object) {
@@ -145,5 +56,5 @@
 	return -1;
     }
-
+    
     /** The assigned plugin constructor.
      * @param element the DOM Element this plugin is based upon
@@ -154,4 +65,7 @@
 	Plugin base_plugin = CollectionDesignManager.plugin_manager.getBasePlugin(plugin_name);
 	Plugin plugin = new Plugin(element, base_plugin);
+	if (base_plugin == null) {
+	    plugin.setAssigned(false);
+	}
 	base_plugin = null;
 	plugin_name = null;
@@ -175,5 +89,6 @@
     {
 	// Check the filename against the plugin's block_exp value
-	ArrayList arguments = getArguments(true, true);
+	//ArrayList arguments = getArguments(true, true);
+	ArrayList arguments = getArguments();
 	for (int i = 0; i < arguments.size(); i++) {
 	    Argument argument = (Argument) arguments.get(i);
@@ -214,5 +129,6 @@
     {
 	// Check the filename against the plugin's process_exp value
-	ArrayList arguments = getArguments(true, true);
+	//ArrayList arguments = getArguments(true, true);
+	ArrayList arguments = getArguments();
 	for (int i = 0; i < arguments.size(); i++) {
 	    Argument argument = (Argument) arguments.get(i);
@@ -248,177 +164,6 @@
     }
 
-
-    /** Method to determine if two plugins are equal.
-     * @param object The plugin to test against, as an <strong>Object</strong>.
-     * @return <i>true</i> if the plugin names match, <i>false</i> otherwise.
-     */
-    public boolean equals(Object object) {
-	return (compareTo(object) == 0);
-    }
-
-    /** Method to retrieve an argument by its name.
-     * @param name The name of the argument as a <strong>String</strong>.
-     * @return The <strong>Argument</strong> requested, or <i>null</i> if no such argument.
-     */
-    public Argument getArgument(String name) {
-	// The name given may still include the '-'
-	if(name.startsWith("-")) {
-	    name = name.substring(1);
-	}
-	ArrayList arguments = getArguments(true, true);
-	for(int i = 0; i < arguments.size(); i++) {
-	    Argument argument = (Argument)arguments.get(i);
-	    if(argument.getName().equals(name)) {
-		return argument;
-	    }
-	}
-	return null;
-    }
-
-    /** Retrieve all of the arguments available to this base plugin, including its super plugins arguments. Some complexity is added by allowing the caller to choose whether they want normal arguments, custom arguments, or both.
-     * @return an ArrayList of all of the arguments, starting with those for this plugin and ending with the arguments for basplug or similiar root plugin
-     */
-    public ArrayList getArguments(boolean include_normal, boolean include_custom) {
-	ArrayList arguments = new ArrayList();
-	if(include_normal && include_custom) {
-	    arguments.addAll(this);
-	}
-	else {
-	    int size = size();
-	    for(int i = 0; i < size; i++) {
-		Argument argument = (Argument) get(i);
-		if(argument.isCustomArgument()) {
-		    if(include_custom && !arguments.contains(argument)) {
-			arguments.add(argument);
-		    }
-		}
-		else {
-		    if(include_normal && !arguments.contains(argument)) {
-			arguments.add(argument);
-		    }
-		}
-		argument = null;
-	    }
-	}
-	if(super_plugin != null) {
-	    ArrayList remainder = super_plugin.getArguments(include_normal, include_custom);
-	    remainder.removeAll(arguments);
-	    arguments.addAll(remainder);
-	}
-	return arguments;
-    }
-
-    /** Method to retrieve a plugins custom argument information. Custom arguments are defined to be those that have not got matching arguments in the base reference plugin from the library. Of course if there is no base plugin then all arguments are considered to be custom.
-     * @return the custom arguments as a String
-     */
-    public String getCustom() {
-	StringBuffer custom_text = new StringBuffer();
-	// Retrieve all of the arguments, and append any that are custom into one long string
-	ArrayList arguments = getArguments(false, true);
-	int arguments_size = arguments.size();
-	boolean first = true;
-	for(int i = 0; i < arguments_size; i++) {
-	    Argument argument = (Argument) arguments.get(i);
-	    if(argument.isAssigned()) {
-		if(!first) {
-		    custom_text.append(" ");
-		}
-		custom_text.append(argument.toString());
-		first = false;
-	    }
-	}
-	return custom_text.toString();
-    }
-
-    public String getDescription() {
-	return description;
-    }
-
-    public Element getElement() {
-	return element;
-    }
-
-    /** Method to retrieve a plugins name.
-     * @return A <strong>String</strong> containing the plugins name.
-     */
-    public String getName() {
-	if(name == null && element != null) {
-	    name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
-	}
-	return name;
-    }
-
-    public boolean isAbstract() {
-	return is_abstract;
-    }
-
-    public boolean isAssigned() {
-	return (element != null && !element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.FALSE_STR));
-    }
-
     public boolean isSeparator() {
 	return (element != null && element.getAttribute(StaticStrings.SEPARATOR_ATTRIBUTE).equals(StaticStrings.TRUE_STR));
-    }
-
-    public void setAssigned(boolean assigned) {
-	if(element != null) {
-	    element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (assigned ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR));
-	}
-    }
-
-    /** Set the custom arguments. This turns out to be quite tricky. We must parse in the string, searching for arguments (for that we use a handy method in CollectionConfiguration). Next, for each argument, we check if we already know about it. If so we update its value, otherwise we create a new argument and assign it (must assign!).
-     * @param custom_str the custom arguments all splodged together in one String
-     */
-    public void setCustom(String custom_str) {
-	HashMap raw_arguments = CollectionConfiguration.parseArguments(new CommandTokenizer(custom_str));
-	ArrayList custom_arguments = getArguments(false, true);
-	int size = custom_arguments.size();
-	for(int i = 0; i < size; i++) {
-	    Argument argument = (Argument) custom_arguments.get(i);
-	    String original_argument_name = StaticStrings.MINUS_CHARACTER + argument.getName();
-	    if(raw_arguments.containsKey(original_argument_name)) {
-		// Set as assigned
-		argument.setAssigned(true);
-		String argument_value = (String)raw_arguments.remove(original_argument_name);
-		if(argument_value != null) {
-		    argument.setValue(argument_value);
-		    argument_value = null;
-		}
-	    }
-	    // We've removed it from our custom statement, so unassign
-	    else {
-		argument.setAssigned(false);
-	    }
-	    argument = null;
-	}
-	// Any left over, add to the plugin
-	Iterator argument_names = raw_arguments.keySet().iterator();
-	while(argument_names.hasNext()) {
-	    String argument_name = (String) argument_names.next();
-	    String argument_value = (String) raw_arguments.get(argument_name);
-	    // The tricky thing is that we have to create a new element in the DOM as well.
-	    Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT);
-	    argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, argument_name.substring(1));
-	    argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR);
-	    argument_element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, StaticStrings.TRUE_STR);
-	    Argument argument = new Argument(argument_element);
-	    argument_name = null;
-	    if(argument_value != null) {
-		argument.setValue(argument_value);
-		argument_value = null;
-	    }
-	    // All done. Add it.
-	    element.appendChild(argument_element);
-	    add(argument);
-	    argument_element = null;
-	}
-	raw_arguments = null;
-    }
-
-    /** Method to set the value of desc.
-     * @param description The new value of desc as a <strong>String</strong>.
-     */
-    public void setDescription(String description) {
-	this.description = description;
     }
 
@@ -427,54 +172,3 @@
     }
 
-    public void setElement(Element element) {
-	this.element = element;
-    }
-
-    public void setIsAbstract(boolean is_abstract) {
-	this.is_abstract = is_abstract;
-    }
-
-    /** Method to set the value of name.
-     * @param name The new value of name as a <strong>String</strong>.
-     */
-    public void setName(String name) {
-	this.name = name;
-    }
-
-    /** Method to set the value of the super_plugin.
-     * @param super_plugin The new value of super_plugin as a <strong>Plugin</strong>, or <i>null</i> if this class has no inheritance.
-     */
-    public void setSuper(Plugin super_plugin) {
-	this.super_plugin = super_plugin;
-    }
-
-    /** Method to print out this plugin as it would appear as a command within the collection configuration file.
-     * @return A <strong>String</strong> containing a single plugin command.
-     */
-    public String toString() {
-	if(element != null) {
-	    if(name == null) {
-		name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE);
-	    }
-	    StringBuffer text = new StringBuffer(StaticStrings.PLUGIN_STR);
-	    text.append(" ");
-	    text.append(name);
-	    text.append(" ");
-	    ArrayList arguments = getArguments(true, true);
-	    int arguments_size = arguments.size();
-	    for(int i = 0; i < arguments_size; i++) {
-		Argument argument = (Argument)arguments.get(i);
-		if(argument.isAssigned()) {
-		    text.append(argument.toString());
-		    text.append(" ");
-		}
-		argument = null;
-	    }
-	    return text.substring(0, text.length() - 1);
-	}
-	// Basic Plugin
-	else {
-	    return name;
-	}
-    }
 }
