Index: /trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentConfiguration.java
===================================================================
--- /trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentConfiguration.java	(revision 12304)
+++ /trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentConfiguration.java	(revision 12305)
@@ -56,6 +56,4 @@
     /** The data whose arguments we are editing. */
     private ArgumentContainer data = null;
-    /** Argument these argument controls coloured or uncoloured (alternates to indicate inheritance). */
-    private boolean coloured = false;
     /** Whether we have successfully edited the arguments associated with the ArgumentContainer or if we have failed to enter required arguments and have instead cancelled (which would cause argument additions to roll back). */
     private boolean success = false;
@@ -68,6 +66,4 @@
     /** The central pane where a list of known arguments is displayed. */
     private JPanel central_pane = null;
-    /** The name of the owner of the last argument control. */
-    private String previous_owner = null;
     /** The size used for an argument label. */
     static final private Dimension LABEL_SIZE = new Dimension(225, 25);
@@ -201,12 +197,35 @@
      */
     private void generateControls() {
+	// Alternating colours to show inheritance
+	Color colour_one = Configuration.getColor("coloring.collection_heading_background", false);
+	Color colour_two = Configuration.getColor("coloring.collection_tree_background", false);
+	boolean coloured = false;
 	ArrayList arguments = data.getArguments();
 	int total_height = 250;
 	int current_mode = Configuration.getMode();
+
+	String previous_owner = ((Argument) arguments.get(0)).getOwner();
+	addHeader(previous_owner, colour_two);
+
 	for(int i = 0; i < arguments.size(); i++) {
 	    Argument argument = (Argument) arguments.get(i);
+	    String owner = argument.getOwner();
+	    if(previous_owner != argument.getOwner()) {
+	    ///ystem.err.println("previous owner is different from current owner");
+		coloured = !coloured;
+		previous_owner = argument.getOwner();
+		addHeader(previous_owner, (coloured ? colour_one : colour_two));
+	    }
 	    if(!argument.isHiddenGLI() && (current_mode > Configuration.LIBRARIAN_MODE || !(argument.getType() == Argument.REGEXP))) {
-		ArgumentControl argument_control = new ArgumentControl(argument);
+		ArgumentControl argument_control = new ArgumentControl(argument, false, null);
 		total_height = total_height - argument_control.getPreferredSize().height;
+		// Create
+		if(coloured) {
+		    argument_control.setBackground(colour_one);
+		}
+		else {
+		    argument_control.setBackground(colour_two);
+		}
+
 		central_pane.add(argument_control);
 	    }
@@ -220,781 +239,3 @@
     }
 
-    /** This class encapsulates all the technical difficulty of creating a specific control based on an Argument. */
-    private class ArgumentControl
-	extends JPanel {
-	/** The Argument this control will be based on. */
-	private Argument argument = null;
-
-	private Color colour_one = Configuration.getColor("coloring.collection_heading_background", false);
-	private Color colour_two = Configuration.getColor("coloring.collection_tree_background", false);
-	/** One of a possible two buttons available for adding to this control. */
-	private JButton one = null;
-	/** The second of two buttons available for adding to this control. */
-	private JButton two = null;
-	/** A checkbox to allow enabling or diabling of this Argument. */
-	private JCheckBox enabled = null;
-	/** Some form of editor component, such as a JComboBox or JTextField, used to set parameters to an Argument. */
-	private JComponent value = null;
-	/** Can be used in place of the other editor components if a list is required. */
-	private JList list = null;
-	/** Constructor.
-	 * @param argument The <strong>Argument</strong> this control will be built around.
-	 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.AddListener
-	 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.EnabledListener
-	 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.HierarchyListener
-	 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.ListOption
-	 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.RemoveListener
-	 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.ToolTipUpdater
-	 */
-	public ArgumentControl(Argument argument) {
-	    this.argument = argument;
-	    ///ystem.err.println("generating controls for arg "+argument.getName());
-	    String tip = "<html>" + argument.getDescription() + "</html>";
-	    tip = Utility.formatHTMLWidth(tip, 60);
-
-	    // If this is the first control, there is no history.
-	    if(previous_owner == null) {
-		///ystem.err.println("previous owner is null");
-		previous_owner = argument.getOwner();
-		addHeader(previous_owner, colour_two);
-	    }
-	    // Otherwise if the owner of the control has changed since the last argument, toggle the colouring of the control.
-	    else if(previous_owner != argument.getOwner()) {
-		///ystem.err.println("previous owner is different from current owner");
-		coloured = !coloured;
-		previous_owner = argument.getOwner();
-		addHeader(previous_owner, (coloured ? colour_one : colour_two));
-	    }
-	    // Create
-	    if(coloured) {
-		setBackground(colour_one);
-	    }
-	    else {
-		setBackground(colour_two);
-	    }
-	    JLabel owner_label = new JLabel(argument.getOwner());
-	    owner_label.setOpaque(false);
-	    JLabel label = new JLabel(argument.getName());
-	    label.setOpaque(false);
-	    label.setPreferredSize(LABEL_SIZE);
-	    label.setToolTipText(tip);
-	    enabled = new JCheckBox(argument.getName());
-	    enabled.setOpaque(false);
-	    enabled.setPreferredSize(LABEL_SIZE);
-	    enabled.setToolTipText(tip);
-	    JPanel inner_pane = new JPanel();
-	    inner_pane.setOpaque(false);
-	    String existing_value = argument.getValue();
-	    String default_value = argument.getDefaultValue();
-
-	    switch(argument.getType()) {
-	    case Argument.ENUM:
-		// Build an option model, wrapping each entry of the list table.
-		HashMap arg_list = argument.getOptions();
-		ArrayList options_model = new ArrayList();
-		Iterator it = arg_list.keySet().iterator();
-		while(it.hasNext()) {
-		    String key = (String) it.next();
-		    options_model.add(new ListOption(key, (String)arg_list.get(key)));
-		}
-		Collections.sort(options_model);
-		value = new GComboBox(options_model.toArray(), false);
-		((JComboBox)value).addActionListener(new ToolTipUpdater());
-		if(existing_value != null && existing_value.length() > 0) {
-		    // Select the correct value. Since they're all text strings we better iterate to be safe.
-		    selectValue((JComboBox)value, existing_value);
-		}
-		else if(default_value != null) {
-		    ///ystem.err.println("Default for argument: " + argument.getName());
-		    // Same as above except for default value.
-		    selectValue((JComboBox)value, default_value);
-		}
-		break;
-
-	    case Argument.FLAG:
-		// Only need the check box.
-		break;
-
-	    case Argument.HIERARCHY:
-		// I don't think these are used any more...
-		break;
-
-	    case Argument.INTEGER:
-		// Build a spinner
-		int initial_value=0;
-		// If there was an original value, set it.
-		if(existing_value != null && !existing_value.equals("")) {
-		    try {
-			initial_value = Integer.parseInt(existing_value);
-			//spinner.setValue(new Integer(existing_value));
-		    }
-		    catch (Exception error) {
-			DebugStream.println("ArgumentConfiguration Error: "+error);
-		    }
-		} else if (default_value != null && !default_value.equals("")) {
-		    try {
-			initial_value = Integer.parseInt(default_value);
-			//spinner.setValue(new Integer(default_value));
-		    }
-		    catch (Exception error) {
-			DebugStream.println("ArgumentConfiguration Error: "+error);
-		    }
-		}
-		if (initial_value < argument.getMinimum()) {
-		    initial_value = argument.getMinimum();
-		} else if (initial_value > argument.getMaximum()) {
-		    initial_value = argument.getMaximum();
-		}
-
-		JSpinner spinner = new JSpinner(new SpinnerNumberModel(initial_value, argument.getMinimum(), argument.getMaximum(), 1));
-
-		// And remember it
-		value = spinner;
-		break;
-
-	    case Argument.REGEXP:
-	    case Argument.STRING:
-		// If there is already a value set for this argument, use it
-		if (existing_value != null && !existing_value.equals("")) {
-		    value = new JTextField(existing_value);
-		    break;
-		}
-
-		// Use the default value, if there is one
-		if (default_value != null && !default_value.equals("")) {
-		    value = new JTextField(default_value);
-		    break;
-		}
-
-// 		// Special test just for the hfile field.
-// 		if (argument.getName().equals("hfile")) {
-// 		    // Work through previous controls looking for the metadata one.
-// 		    for (int i = 0; i < central_pane.getComponentCount(); i++) {
-// 			Object object = central_pane.getComponent(i);
-// 			if (object instanceof ArgumentControl) {
-// 			    ArgumentControl control = (ArgumentControl) object;
-// 			    if (control.toString().equals("metadata")) {
-// 				Object temp = control.getValue();
-// 				if (temp != null) {
-// 				    value = new JTextField(temp.toString() + ".txt");
-//                                  break;
-// 				}
-// 			    }
-// 			}
-// 		    }
-// 		}
-
-		// Blank field
-		value = new JTextField();
-		break;
-
-	    case Argument.LANGUAGE:
-		value = new GComboBox(CollectionDesignManager.language_manager.getLanguageCodes().toArray(), false);
-		// we want to display the language name not the code
-		((JComboBox)value).setRenderer(new LanguageListCellRenderer());
-		// Now ensure we have the existing value or default value selected if either exist in our known languages
-		String lang_name = null;
-		String selected_code = existing_value;
-		if(existing_value != null && !existing_value.equals("")) {
-		    lang_name = CollectionDesignManager.language_manager.getLanguageName(existing_value);
-		}
-		if(lang_name == null && default_value != null) {
-		    lang_name = CollectionDesignManager.language_manager.getLanguageName(default_value);
-		    selected_code = default_value;
-		}
-		if (lang_name != null) {
-		    ((JComboBox)value).setSelectedItem(selected_code);
-		}
-		break;
-
-	    case Argument.METADATUM:
-	    case Argument.METADATA:
-		value = new GComboBox(MetadataSetManager.getEveryMetadataSetElement(), false);
-
-		// Editable for advanced modes (allows things like dc.Title,ex.Title)
-		if (Configuration.getMode() > Configuration.ASSISTANT_MODE) {
-		    ((JComboBox) value).setEditable(true);
-		}
-
-		// Now ensure we have the existing value or default value selected if either exist.
-		if (existing_value != null && existing_value.length() > 0) {
-		    boolean found = selectValue((JComboBox) value, existing_value);
-		    // It's possible that this is a custom value and so doesn't exist in the combobox
-		    if (!found) {
-			// If so, add it then select it
-			((JComboBox) value).addItem(existing_value);
-			((JComboBox) value).setSelectedItem(existing_value);
-		    }
-		}
-		else if (default_value != null) {
-		    // if no namespace for default value, add ex.
-		    // won't work if we want to set a non-metadata value
-		    if (MetadataTools.getMetadataSetNamespace(default_value).equals("")) {
-			default_value = StaticStrings.EXTRACTED_NAMESPACE+default_value;
-		    }
-		    selectValue((JComboBox) value, default_value);
-		}
-		break;
-
-// ---- Special interface for adding and ordering multiple metadata items ----
-// Turned off at Ian's request!
-//  	    case Argument.METADATA:
-//  		// Comma separated metadata values.
-//  		ArrayList values = argument.getValues();
-//  		value = new GComboBox(MetadataSetManager.getEveryMetadataSetElement(), false);
-//  		//((JComboBox)value).setEditable(false);
-//  		DefaultListModel model = new DefaultListModel();
-//  		list = new JList(model);
-//  		list.setVisibleRowCount(3);
-//  		for(int i = 0; i < values.size(); i++) {
-//  		    model.addElement(values.get(i));
-//  		}
-
-//  		one = new GLIButton();
-//  		one.addActionListener(new AddListener((JComboBox)value, list));
-//  		Dictionary.setBoth(one, "CDM.ArgumentConfiguration.Add", "CDM.ArgumentConfiguration.Add_Tooltip");
-//  		two = new GLIButton();
-//  		two.addActionListener(new RemoveListener(list));
-//  		Dictionary.setBoth(two, "CDM.ArgumentConfiguration.Remove", "CDM.ArgumentConfiguration.Remove_Tooltip");
-
-//  		if(argument.getValues().size() > 0 || argument.isRequired()) {
-//  		    enabled.setSelected(true);
-//  		    list.setBackground(Color.white);
-//  		    list.setEnabled(true);
-//  		    one.setEnabled(true);
-//  		    two.setEnabled(true);
-//  		    value.setEnabled(true);
-//  		}
-//  		else {
-//  		    enabled.setSelected(false);
-//  		    list.setBackground(Color.lightGray);
-//  		    list.setEnabled(false);
-//  		    one.setEnabled(false);
-//  		    two.setEnabled(false);
-//  		    value.setEnabled(false);
-//  		}
-//  		break;
-	    } // end of switch
-
-	    // Enable or disable as necessary.
-	    if(argument.isRequired() || argument.isAssigned()) {
-		enabled.setSelected(true);
-		if(value != null) {
-		    value.setOpaque(true);
-		    value.setBackground(Color.white);
-		    value.setEnabled(true);
-		    if(value instanceof JSpinner) {
-			// Set enabled
-			JComponent c = ((JSpinner)value).getEditor();
-			if ( c instanceof JSpinner.DefaultEditor ) {
-			    JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
-			    JFormattedTextField field = editor.getTextField();
-			    field.setEditable(true);
-			    field.setBackground(Color.white);
-			}
-		    }
-		}
-	    }
-	    else {
-		enabled.setSelected(false);
-		if(value != null) {
-		    value.setOpaque(true);
-		    value.setBackground(Color.lightGray);
-		    value.setEnabled(false);
-		    if(value instanceof JSpinner) {
-			// Set enabled
-			JComponent c = ((JSpinner)value).getEditor();
-			if ( c instanceof JSpinner.DefaultEditor ) {
-			    JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
-			    JFormattedTextField field = editor.getTextField();
-			    field.setEditable(false);
-			    field.setBackground(Color.lightGray);
-			}
-		    }
-		}
-	    }
-	    // Listener
-	    if(value != null && !argument.isRequired()) {
-		enabled.addActionListener(new EnabledListener(one, two, list, value));
-	    }
-
-	    // Layout
-	    inner_pane.setLayout(new BorderLayout());
-	    if (argument.isRequired()) {
-		inner_pane.add(label, BorderLayout.WEST);
-	    }
-	    else {
-		inner_pane.add(enabled, BorderLayout.WEST);
-	    }
-
-	    if (list == null) {
-		enabled.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
-		if (value != null) {
-		    inner_pane.add(value, BorderLayout.CENTER);
-		}
-	    }
-	    else {
-		JPanel left_pane = new JPanel(new BorderLayout());
-		left_pane.add(new JLabel(""), BorderLayout.NORTH);
-		left_pane.add(value, BorderLayout.CENTER);
-		left_pane.add(one, BorderLayout.SOUTH);
-		left_pane.setOpaque(false);
-
-		JPanel right_pane = new JPanel(new BorderLayout());
-		right_pane.add(new JScrollPane(list), BorderLayout.CENTER);
-		right_pane.add(two, BorderLayout.SOUTH);
-		right_pane.setOpaque(false);
-
-		JPanel control_pane = new JPanel(new GridLayout(1, 2));
-		control_pane.add(left_pane);
-		control_pane.add(right_pane);
-
-		inner_pane.add(control_pane, BorderLayout.CENTER);
-	    }
-
-	    setLayout(new BorderLayout());
-	    add(inner_pane, BorderLayout.CENTER);
-	}
-
-       public Argument getArgument() {
-	  return argument;
-       }
-
-	public Object getValue() {
-	    if(value instanceof JComboBox) {
-		return ((JComboBox)value).getSelectedItem();
-	    }
-	    else if(value instanceof JTextField) {
-		return ((JTextField)value).getText();
-	    }
-	    return null;
-	}
-	/** Identifies this control by returning the name of the Argument it is based on.
-	 * @return The name of the Argument as a <strong>String</strong>.
-	 * @see org.greenstone.gatherer.cdm.Argument
-	 */
-	public String toString() {
-	    return argument.getName();
-	}
-	/** Updates the enwrapped Argument using the values provided by the controls.
-	 * @return <i>true</i> if the update was successful, <i>false</i> otherwise.
-	 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.ListOption
-	 * @see org.greenstone.gatherer.cdm.Language
-	 */
-	public boolean updateArgument() {
-	    if(enabled.isSelected() || argument.isRequired()) {
-		argument.setAssigned(false);
-		String result = null;
-		switch(argument.getType()) {
-		case Argument.ENUM:
-		    ListOption option = (ListOption)((JComboBox)value).getSelectedItem();
-		    if(option != null && option.getValue().length() > 0) {
-			argument.setValue(option.getValue());
-		    }
-		    else {
-			String args[] = new String[1];
-			args[0] = argument.getName();
-			if(argument.isRequired()) {
-			    JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
-			}
-			// They've left the field blank
-			else {
-			    JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
-			    argument.setValue(null);
-			}
-			args = null;
-			return false;
-		    }
-		    argument.setAssigned(true);
-		    return true;
-		case Argument.FLAG:
-		    // Should have already been handled above.
-		    argument.setAssigned(true);
-		    return true;
-		case Argument.INTEGER:
-		    result = ((JSpinner)value).getValue().toString();
-		    if(result.length() > 0) {
-			// Test if the value entered is a valid int.
-			try {
-			    int x = Integer.parseInt(result);
-			}
-			catch(NumberFormatException nfe) {
-			    String args[] = new String[2];
-			    args[0] = argument.getName();
-			    args[1] = result;
-			    JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.Bad_Integer", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
-			    args = null;
-			    return false;
-			}
-			argument.setValue(result);
-		    }
-		    else {
-			String args[] = new String[1];
-			args[0] = argument.getName();
-			if(argument.isRequired()) {
-			    JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
-			}
-			// They've left the field blank
-			else {
-			    JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
-			    argument.setValue(null);
-			}
-			args = null;
-			return false;
-		    }
-		    argument.setAssigned(true);
-		    return true;
-		case Argument.LANGUAGE:
-		    String language = (((JComboBox)value).getSelectedItem()).toString();
-		    argument.setValue(language);
-		    // Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted.
-		    argument.setAssigned(true);
-		    return true;
-		case Argument.METADATUM:
-		case Argument.METADATA:
-		    Object new_value_raw = ((JComboBox) value).getSelectedItem();
-		    if (new_value_raw instanceof MetadataElement) {
-			argument.setValue(((MetadataElement) new_value_raw).getFullName());
-		    }
-		    else {
-			// But we have to be careful as an arbitary string object could be zero length
-			String new_value = new_value_raw.toString();
-			///ystem.err.println("The current value is: " + new_value);
-			if(new_value.length() > 0) {
-			    argument.setValue(new_value);
-			}
-			else {
-			    String args[] = new String[1];
-			    args[0] = argument.getName();
-			    if(argument.isRequired()) {
-				JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
-			    }
-			    // They've left the field blank
-			    else {
-				JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
-				argument.setValue(null);
-			    }
-			    args = null;
-			    return false;
-			}
-		    }
-		    argument.setAssigned(true);
-		    return true;
-//  		case Argument.METADATA:
-//  		    DefaultListModel model = (DefaultListModel)list.getModel();
-//  		    ArrayList values = new ArrayList();
-//  		    for(int i = 0; i < model.size(); i++) {
-//  			values.add(model.get(i));
-//  		    }
-//  		    argument.setValues(values);
-//  		    argument.setAssigned(true);
-//  		    return true;
-		case Argument.HIERARCHY:
-// 		    argument.setValue(((JComboBox)value).getSelectedItem().toString());
-// 		    // Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted.
-// 		    argument.setAssigned(true);
-		    return true;
-		case Argument.REGEXP:
-		case Argument.STRING:
-		    result = ((JTextField)value).getText();
-		    if(result.length() > 0) {
-			argument.setValue(result);
-		    }
-		    else {
-			String args[] = new String[1];
-			args[0] = argument.getName();
-			if(argument.isRequired()) {
-			    JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
-			}
-			// They've left the field blank
-			else {
-			    JOptionPane.showMessageDialog(self, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
-			    argument.setValue(null);
-			}
-			args = null;
-			return false;
-		    }
-		    argument.setAssigned(true);
-		    return true;
-		}
-		return false;
-	    }
-	    else {
-		argument.setAssigned(false);
-		return true;
-	    }
-	}
-	/** Method to ensure that a certain value is selected, if it exists within that combobox to begin with.
-	 * @param combobox The <strong>JComboBox</strong> whose selection we are trying to preset.
-	 * @param target The desired value of the selection as a <strong>String</strong>.
-	 * @return true if the item was found and selected, false otherwise
-	 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.ListOption
-	 */
-	public boolean selectValue(JComboBox combobox, String target) {
-	    ///ystem.err.println("Searching for the target string: " + target);
-	    for(int i = 0; i < combobox.getItemCount(); i++) {
-		Object object = combobox.getItemAt(i);
-		if(object instanceof ListOption) {
-		    ListOption lo = (ListOption) object;
-		    ///ystem.err.print("/tChecking: " + lo.getValue() + "... ");
-		    if(lo.getValue().startsWith(target)) {
-			///ystem.err.println("Match!");
-			combobox.setSelectedIndex(i);
-			return true;
-		    }
-		    /*
-		    else {
-		        System.err.println("No Match.");
-		    }
-		    */
-		}
-		else if (object instanceof MetadataElement) {
-		    if(object.toString().equals(target)) {
-			combobox.setSelectedIndex(i);
-			return true;
-		    }
-		}
-	    }
-	    return false;
-	}
-	/** Forces the control into an 'enabled' mode. */
-	public void setEnabled() {
-	    enabled.setSelected(true);
-	}
-	/** Explicitly sets the value of a JTextField type control to the given String.
-	 * @param value_str The new value of the control as a <strong>String</strong>.
-	 */
-	public void setValue(String value_str) {
-	    ((JTextField)value).setText(value_str);
-	}
-// 	/** Listener which adds entries to a list from a combobox when fired. */
-// 	private class AddListener
-// 	    implements ActionListener {
-// 	    /** The model behind the target list. */
-// 	    private DefaultListModel model = null;
-//       	    /** The source for data to be added to the list. */
-// 	    private JComboBox source = null;
-// 	    /** The list to add data to. */
-// 	    private JList target = null;
-// 	    /** Constructor.
-// 	     * @param source A <strong>JComboBox</strong> which serves as the source for data.
-// 	     * @param target A <strong>JList</strong> which serves as the target for data.
-// 	     */
-// 	    public AddListener(JComboBox source, JList target) {
-// 		this.model = (DefaultListModel) target.getModel();
-// 		this.source = source;
-// 		this.target = target;
-// 	    }
-// 	    /** When the add button is clicked, we attempt to add the selected metadata from the source into the target.
-// 	     * @param event An <strong>ActionEvent</strong> containing information about the event.
-// 	     */
-// 	    public void actionPerformed(ActionEvent event) {
-// 		ElementWrapper element = (ElementWrapper) source.getSelectedItem();
-// 		String name = element.toString();
-// 		if (!model.contains(name)) {
-// 		    model.addElement(name);
-// 		}
-// 	    }
-// 	}
-	/** Listens for actions apon the enable checkbox, and if detected enables or diables control appropriately. */
-	private class EnabledListener
-	    implements ActionListener {
-	    /** One of two possible buttons that might have their enabled state changed by this listener. */
-	    private JButton one = null;
-	    /** One of two possible buttons that might have their enabled state changed by this listener. */
-	    private JButton two = null;
-	    /** An editor component, such as a JComboBox or JTextField, that might have its enabled state changed by this listener. */
-	    private JComponent target = null;
-	    /** A list which might have its enabled state changed by this listener. */
-	    private JList list = null;
-	    /** Constructor.
-	     * @param one A <strong>JButton</strong> whose enabled state is determined by the listener, or <i>null</i> if no button.
-	     * @param two A <strong>JButton</strong> whose enabled state is determined by the listener, or <i>null</i> if no button.
-	     * @param list A <strong>JList</strong> whose enabled state is determined by the listener, or <i>null</i> if no list.
-	     * @param target A <strong>JComponent</strong> whose enabled state is determined by the listener, or <i>null</i> if no component.
-	     */
-	    public EnabledListener(JButton one, JButton two, JList list, JComponent target) {
-		this.list = list;
-		this.one = one;
-		this.target = target;
-		this.two = two;
-	    }
-	    /** Any implementation of ActionListener must include this method so that we can be informed when an action has been performed on or registered check box, prompting us to change the state of the other controls as per the users request.
-	     * @param event An <strong>ActionEvent</strong> containing information about the click.
-	     */
-	    public void actionPerformed(ActionEvent event) {
-		JCheckBox source = (JCheckBox)event.getSource();
-		if(source.isSelected()) {
-		    target.setBackground(Color.white);
-		    target.setEnabled(true);
-		    if(target instanceof JSpinner) {
-			// Set enabled
-			JComponent c = ((JSpinner)target).getEditor();
-			if ( c instanceof JSpinner.DefaultEditor ) {
-			    JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
-			    JFormattedTextField field = editor.getTextField();
-			    field.setEditable(true);
-			    field.setBackground(Color.white);
-			}
-		    }
-		    if(one != null && two != null && list != null) {
-			one.setEnabled(true);
-			two.setEnabled(true);
-			list.setBackground(Color.white);
-			list.setEnabled(true);
-		    }
-		}
-		else {
-		    target.setBackground(Color.lightGray);
-		    target.setEnabled(false);
-		    if(target instanceof JSpinner) {
-			// Set enabled
-			JComponent c = ((JSpinner)target).getEditor();
-			if ( c instanceof JSpinner.DefaultEditor ) {
-			    JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
-			    JFormattedTextField field = editor.getTextField();
-			    field.setEditable(false);
-			    field.setBackground(Color.lightGray);
-			}
-		    }
-		    if(one != null && two != null && list != null) {
-			one.setEnabled(false);
-			two.setEnabled(false);
-			list.setBackground(Color.lightGray);
-			list.setEnabled(false);
-		    }
-		}
-	    }
-	}
-	/** If a metadata element is selected that requires an hfile, then this listener defaults that hfile. */
-// 	private class HierarchyListener
-// 	    implements ItemListener {
-// 	    /** Any implementation of ItemListener must include this method so that we can be informed when an item from the list is selected, and generate a predetermined hfile for that selection.
-// 	     * @param event An <strong>ItemEvent</strong> containing information about the selection.
-// 	     * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl
-// 	     */
-// 	    public void itemStateChanged(ItemEvent event) {
-// 		// Determine if the selected element represents a hierarchy.
-// 		Object temp = ((JComboBox)value).getSelectedItem();
-// 		String filename = temp.toString();
-// 		// Search for a argument control called hfile and enable and set value.
-// 		for(int i = 0; i < central_pane.getComponentCount(); i++) {
-// 		    Object object = central_pane.getComponent(i);
-// 		    if(object instanceof ArgumentControl) {
-// 			ArgumentControl control = (ArgumentControl) object;
-// 			if(control.toString().equals("hfile")) {
-// 			    control.setValue(filename + ".txt");
-// 			    control.setEnabled(true);
-// 			}
-// 		    }
-// 		}
-// 	    }
-// 	}
-	/** A ListOption is a compound item which is constructed from several Strings. That magic part is that the length of screen real-estate used by the text version of this item is limited. */
-	private class ListOption
-	    implements Comparable {
-	    /** The maximum length of this String version of this item. */
-	    private int MAX_DESC = 65;
-	    /** The description of the value for this item. */
-	    private String description = null;
-	    /** A cached value for the text value of this option, as it never changes after the first call to toString(). */
-	    private String text = null;
-	    /** The value for this item. */
-	    private String value = null;
-	    /** Constructor.
-	     * @param value The value for this item as a <strong>String</strong>.
-	     * @param description The description of the value as a <strong>String</strong>.
-	     */
-	    public ListOption(String value, String description) {
-		this.description = description;
-		this.value = value;
-	    }
-	    /** Compare two possible ListOption objects for ordering.
-	     * @param object The <strong>Object</strong> to compare to.
-	     * @return An <i>int</i> indicating order as explained in String.
-	     * @see java.lang.String#compareTo
-	     */
-	    public int compareTo(Object object) {
-		return toString().compareTo(object.toString());
-	    }
-	    /** Tests two possible ListOption objects for equality. Uses the result from compareTo().
-	     * @param object The <strong>Object</strong> which may be equal.
-	     * @return <i>true</i> if the objects are equal, <i>false</i> otherwise.
-	     */
-	    public boolean equals(Object object) {
-		return (object != null && compareTo(object) == 0);
-	    }
-	    /** Retrieve the description of this list item.
-	     * @return The description as a <strong>String</strong>.
-	     */
-	    public String getDesc() {
-		return description;
-	    }
-	    /** Retrieve the value of this list item.
-	     * @return The value as a <strong>String</strong>.
-	     */
-	    public String getValue() {
-		return value;
-	    }
-       	    /** Convert this object into a nice readable String.
-	     * @return A <strong>String</strong> representing this object.
-	     */
-	    public String toString() {
-		if(text == null) {
-		    if(description.length() >= MAX_DESC) {
-		    	text = value + " "+ StaticStrings.MINUS_CHARACTER + " "+ description.substring(0, MAX_DESC) + StaticStrings.TRUNCATED_STRING;
-		    }
-		    else {
-		       text = value + " "+ StaticStrings.MINUS_CHARACTER + " "+ description;
-		    }
-		}
-		return text;
-	    }
-	}
-	/** Listener which removes entries from a list from a combobox when fired. */
-	private class RemoveListener
-	    implements ActionListener {
-	    /** The model behind the target list. */
-	    private DefaultListModel model = null;
-	    /** The list to remove data from. */
-	    private JList target = null;
-	    /** Constructor.
-	     * @param target A <strong>JList</strong>.
-	     */
-	    public RemoveListener(JList target) {
-		this.model = (DefaultListModel) target.getModel();
-		this.target = target;
-	    }
-	    /** When the remove button is clicked, we attempt to remove the selected metadata from the target.
-	     * @param event An <strong>ActionEvent</strong> containing information about the event.
-	     */
-	    public void actionPerformed(ActionEvent event) {
-		if(!target.isSelectionEmpty()) {
-		    int index = target.getSelectedIndex();
-		    model.remove(index);
-		}
-	    }
-	}
-	/** Listener that sets the tooltip associated to a combobox to the tooltip relevant to the selected item. */
-	private class ToolTipUpdater
-	    implements ActionListener {
-	    /** Any implementation of an ActionListener must include this method so that we can be informed when the selection in a combobox has changed and update the tooltip accordingly.
-	     * @param event An <strong>ActionEvent</strong> containing information about the action that fired this call.
-	     */
-	    public void actionPerformed(ActionEvent event) {
-		JComboBox source = (JComboBox)event.getSource();
-		Object object = source.getSelectedItem();
-		if(object instanceof ListOption) {
-		    ListOption lo = (ListOption)object;
-		    if(lo != null) {
-			String description = Utility.formatHTMLWidth(lo.getDesc(), 60);
-			source.setToolTipText(description);
-		    }
-		    else {
-			source.setToolTipText(StaticStrings.EMPTY_STR);
-		    }
-		}
-	    }
-	}
-    }
 }
Index: /trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentControl.java
===================================================================
--- /trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentControl.java	(revision 12305)
+++ /trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentControl.java	(revision 12305)
@@ -0,0 +1,625 @@
+package org.greenstone.gatherer.cdm;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Iterator;
+import java.util.HashMap;
+
+import org.greenstone.gatherer.Configuration;
+import org.greenstone.gatherer.DebugStream;
+import org.greenstone.gatherer.Dictionary;
+import org.greenstone.gatherer.Gatherer;
+import org.greenstone.gatherer.gui.GComboBox;
+import org.greenstone.gatherer.util.StaticStrings;
+import org.greenstone.gatherer.util.Utility;
+import org.greenstone.gatherer.metadata.MetadataElement;
+import org.greenstone.gatherer.metadata.MetadataSet;
+import org.greenstone.gatherer.metadata.MetadataSetManager;
+import org.greenstone.gatherer.metadata.MetadataTools;
+
+/** This class encapsulates all the technical difficulty of creating a specific control based on an Argument. */
+public class ArgumentControl
+    extends JPanel {
+
+    static protected Dimension LABEL_SIZE = new Dimension(175, 25);
+    static protected Dimension ROW_SIZE = new Dimension(800, 30);
+
+    /** The Argument this control will be based on. */
+    private Argument argument = null;
+
+    /** A checkbox to allow enabling or diabling of this Argument. */
+    private JCheckBox enabled = null;
+    /** Some form of editor component, such as a JComboBox or JTextField, used to set parameters to an Argument. */
+    private JComponent value_control = null;
+	
+    /** Constructor.
+     */
+    public ArgumentControl(Argument argument, boolean is_enabled, String preset_value) {
+	this.argument = argument;
+	///ystem.err.println("generating controls for arg "+argument.getName());
+	String tip = "<html>" + argument.getDescription() + "</html>";
+	tip = Utility.formatHTMLWidth(tip, 60);
+
+	setBackground(Configuration.getColor("coloring.collection_tree_background", false));
+	setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
+	setLayout(new BorderLayout());
+	//setPreferredSize(ROW_SIZE);
+	setMaximumSize(ROW_SIZE);
+
+	if (argument.isRequired()) {
+	    JLabel label = new JLabel(argument.getName());
+	    label.setOpaque(false);
+	    label.setPreferredSize(LABEL_SIZE);
+	    label.setToolTipText(tip);
+	    add(label, BorderLayout.WEST);
+	} else {
+	    enabled = new JCheckBox(argument.getName());
+	    enabled.setOpaque(false);
+	    enabled.setPreferredSize(LABEL_SIZE);
+	    enabled.setToolTipText(tip);
+	    add(enabled, BorderLayout.WEST);
+	}
+	
+	String initial_value;
+	if (preset_value != null && !preset_value.equals("")) {
+	    initial_value = preset_value;
+	}
+	else {
+	    initial_value = argument.getValue();
+	}
+	if (initial_value == null || initial_value.equals("")) {
+	    initial_value = argument.getDefaultValue();
+	}
+	if (initial_value == null) {
+	    initial_value = "";
+	}
+	
+	switch(argument.getType()) {
+	case Argument.ENUM:
+	    // Build an option model, wrapping each entry of the list table.
+	    HashMap arg_list = argument.getOptions();
+	    ArrayList options_model = new ArrayList();
+	    Iterator it = arg_list.entrySet().iterator();
+	    while(it.hasNext()) {
+		Map.Entry e = (Map.Entry)it.next();
+		//String key = (String) it.next();
+		//options_model.add(new ListOption(key, (String)arg_list.get(key)));
+		options_model.add(new ListOption((String)e.getKey(), (String)e.getValue()));
+	    }
+	    Collections.sort(options_model);
+	    value_control = new GComboBox(options_model.toArray(), false);
+	    ((JComboBox)value_control).addActionListener(new ToolTipUpdater());
+	    selectValue((JComboBox)value_control, initial_value);
+	    break;
+	    
+	case Argument.FLAG:
+	    // Only need the check box.
+	    break;
+
+	case Argument.INTEGER:
+	    // Build a spinner
+	    int initial_int=0;
+	    // If there was an original value, set it.
+	    try {
+		initial_int = Integer.parseInt(initial_value);
+	    } catch (Exception error) {
+		DebugStream.println("ArgumentControl Error: "+error);
+	    }
+	    if (initial_int < argument.getMinimum()) {
+		initial_int = argument.getMinimum();
+	    } else if (initial_int > argument.getMaximum()) {
+		initial_int = argument.getMaximum();
+	    }
+	    
+	    JSpinner spinner = new JSpinner(new SpinnerNumberModel(initial_int, argument.getMinimum(), argument.getMaximum(), 1));
+
+	    // And remember it
+	    value_control = spinner;
+	    break;
+
+	case Argument.REGEXP:
+	case Argument.STRING:
+	    value_control = new JTextField(initial_value);
+		break;
+		
+	case Argument.LANGUAGE:
+	    value_control = new GComboBox(CollectionDesignManager.language_manager.getLanguageCodes().toArray(), false);
+	    // we want to display the language name not the code
+	    ((JComboBox)value_control).setRenderer(new LanguageListCellRenderer());
+	    // Now ensure we have the existing value or default value selected if either exist in our known languages
+	    String lang_name = CollectionDesignManager.language_manager.getLanguageName(initial_value);
+	    if (lang_name != null) {
+		((JComboBox)value_control).setSelectedItem(initial_value);
+	    }
+	    break;
+
+	case Argument.METADATUM:
+	case Argument.METADATA:
+	    value_control = new GComboBox(MetadataSetManager.getEveryMetadataSetElement(), false);
+
+	    // Editable for advanced modes (allows things like dc.Title,ex.Title)
+	    if (Configuration.getMode() > Configuration.ASSISTANT_MODE) {
+		((JComboBox) value_control).setEditable(true);
+	    }
+
+	    // Now ensure we have the existing value or default value selected if either exist.
+	    String existing_value = argument.getValue();
+	    if (existing_value != null && existing_value.length() > 0) {
+		boolean found = selectValue((JComboBox) value_control, existing_value);
+		// It's possible that this is a custom value and so doesn't exist in the combobox
+		if (!found) {
+		    // If so, add it then select it
+		    ((JComboBox) value_control).addItem(existing_value);
+		    ((JComboBox) value_control).setSelectedItem(existing_value);
+		}
+	    }
+	    else {
+		String default_value = argument.getDefaultValue();
+		if (default_value != null) {
+		    // if no namespace for default value, add ex.
+		    // won't work if we want to set a non-metadata value
+		    if (MetadataTools.getMetadataSetNamespace(default_value).equals("")) {
+			default_value = StaticStrings.EXTRACTED_NAMESPACE+default_value;
+		    }
+		    selectValue((JComboBox) value_control, default_value);
+		}
+	    }
+	    break;
+
+	case Argument.METADATA_SET_NAMESPACE:
+	    value_control = new JComboBox();
+	    // !! Hack for exploding metadata databases: add the (empty) exploded metadata set
+	    File exploded_metadata_set_file = new File(Gatherer.getGLIMetadataDirectoryPath() + "exp" + StaticStrings.METADATA_SET_EXTENSION);
+	    MetadataSet exploded_metadata_set = new MetadataSet(exploded_metadata_set_file);
+	    Gatherer.c_man.importMetadataSet(exploded_metadata_set);
+
+	    // All the loaded metadata sets except the extracted metadata set are applicable
+	    ArrayList metadata_sets = MetadataSetManager.getMetadataSets();
+	    for (int i = metadata_sets.size() - 1; i >= 0; i--) {
+		MetadataSet metadata_set = (MetadataSet) metadata_sets.get(i);
+		if (!(metadata_set.getNamespace().equals(MetadataSetManager.EXTRACTED_METADATA_NAMESPACE))) {
+		    ((JComboBox)value_control).addItem(metadata_set);
+		}
+	    }
+	} // end of switch
+
+	// Enable or disable as necessary.
+	if(argument.isRequired() || argument.isAssigned() || is_enabled) {
+	    if (enabled != null) {
+		enabled.setSelected(true);
+	    }
+	    if(value_control != null) {
+		value_control.setOpaque(true);
+		value_control.setBackground(Color.white);
+		value_control.setEnabled(true);
+		if(value_control instanceof JSpinner) {
+		    // Set enabled
+		    JComponent c = ((JSpinner)value_control).getEditor();
+		    if ( c instanceof JSpinner.DefaultEditor ) {
+			JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
+			JFormattedTextField field = editor.getTextField();
+			field.setEditable(true);
+			field.setBackground(Color.white);
+		    }
+		}
+	    }
+	}
+	else {
+	    if (enabled != null) {
+		enabled.setSelected(false);
+	    }
+	    if(value_control != null) {
+		value_control.setOpaque(true);
+		value_control.setBackground(Color.lightGray);
+		value_control.setEnabled(false);
+		if(value_control instanceof JSpinner) {
+		    // Set enabled
+		    JComponent c = ((JSpinner)value_control).getEditor();
+		    if ( c instanceof JSpinner.DefaultEditor ) {
+			JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
+			JFormattedTextField field = editor.getTextField();
+			field.setEditable(false);
+			field.setBackground(Color.lightGray);
+		    }
+		}
+	    }
+	}
+	
+	// Listener
+	if(value_control != null) {
+	    value_control.setToolTipText(tip);
+	    add(value_control, BorderLayout.CENTER);
+	    if (!argument.isRequired()) {
+		enabled.addActionListener(new EnabledListener(value_control));
+	    }
+	}
+    }
+    
+    public Argument getArgument() {
+	return argument;
+    }
+
+    public String getArgumentName() {
+	return argument.getName();
+    }
+
+    public String getValue() {
+	if(value_control == null) {
+	    return null;
+	}
+	if (value_control instanceof JSpinner) {
+	    return ((JSpinner)value_control).getValue().toString();
+	}
+	if(value_control instanceof JComboBox) {
+	    Object selected_item = ((JComboBox)value_control).getSelectedItem();
+	    if (selected_item != null) {
+		if (argument.getType() == Argument.METADATA_SET_NAMESPACE) {
+		    return ((MetadataSet) selected_item).getNamespace();
+		}
+		if (selected_item instanceof ListOption) {
+		    return ((ListOption)selected_item).getValue();
+		}
+		return selected_item.toString();
+	    }
+	    
+	    return null;
+	}
+	if(value_control instanceof JTextField) {
+	    return ((JTextField)value_control).getText();
+	}
+	return null;
+    }
+    /** Retrieve the control used for storing values.
+     * @return JComponent
+     */
+    public JComponent getValueControl() {
+	return value_control;
+    }
+
+    public boolean isEnabled() {
+	if (enabled == null) {
+	    return true; // always enabled
+	} 
+	return enabled.isSelected();
+    }
+
+
+    /** Identifies this control by returning the name of the Argument it is based on.
+     * @return The name of the Argument as a <strong>String</strong>.
+     * @see org.greenstone.gatherer.cdm.Argument
+     */
+    public String toString() {
+	return argument.getName();
+    }
+    /** Updates the enwrapped Argument using the values provided by the controls.
+     * @return <i>true</i> if the update was successful, <i>false</i> otherwise.
+     * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.ListOption
+     * @see org.greenstone.gatherer.cdm.Language
+     */
+    public boolean updateArgument() {
+	if(enabled.isSelected() || argument.isRequired()) {
+	    argument.setAssigned(false);
+	    String result = null;
+	    switch(argument.getType()) {
+	    case Argument.ENUM:
+		ListOption option = (ListOption)((JComboBox)value_control).getSelectedItem();
+		if(option != null && option.getValue().length() > 0) {
+		    argument.setValue(option.getValue());
+		}
+		else {
+		    String args[] = new String[1];
+		    args[0] = argument.getName();
+		    if(argument.isRequired()) {
+			JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
+		    }
+		    // They've left the field blank
+		    else {
+			JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
+			argument.setValue(null);
+		    }
+		    args = null;
+		    return false;
+		}
+		argument.setAssigned(true);
+		return true;
+	    case Argument.FLAG:
+		// Should have already been handled above.
+		argument.setAssigned(true);
+		return true;
+	    case Argument.INTEGER:
+		result = ((JSpinner)value_control).getValue().toString();
+		if(result.length() > 0) {
+		    // Test if the value entered is a valid int.
+		    try {
+			int x = Integer.parseInt(result);
+		    }
+		    catch(NumberFormatException nfe) {
+			String args[] = new String[2];
+			args[0] = argument.getName();
+			args[1] = result;
+			JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Bad_Integer", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
+			args = null;
+			return false;
+		    }
+		    argument.setValue(result);
+		}
+		else {
+		    String args[] = new String[1];
+		    args[0] = argument.getName();
+		    if(argument.isRequired()) {
+			JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
+		    }
+		    // They've left the field blank
+		    else {
+			JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
+			argument.setValue(null);
+		    }
+		    args = null;
+		    return false;
+		}
+		argument.setAssigned(true);
+		return true;
+	    case Argument.LANGUAGE:
+		String language = (((JComboBox)value_control).getSelectedItem()).toString();
+		argument.setValue(language);
+		// Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted.
+		argument.setAssigned(true);
+		return true;
+	    case Argument.METADATUM:
+	    case Argument.METADATA:
+		Object new_value_raw = ((JComboBox) value_control).getSelectedItem();
+		if (new_value_raw instanceof MetadataElement) {
+		    argument.setValue(((MetadataElement) new_value_raw).getFullName());
+		}
+		else {
+		    // But we have to be careful as an arbitary string object could be zero length
+		    String new_value = new_value_raw.toString();
+		    ///ystem.err.println("The current value is: " + new_value);
+		    if(new_value.length() > 0) {
+			argument.setValue(new_value);
+		    }
+		    else {
+			String args[] = new String[1];
+			args[0] = argument.getName();
+			if(argument.isRequired()) {
+			    JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
+			}
+			// They've left the field blank
+			else {
+			    JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
+			    argument.setValue(null);
+			}
+			args = null;
+			return false;
+		    }
+		}
+		argument.setAssigned(true);
+		return true;
+		//  		case Argument.METADATA:
+		//  		    DefaultListModel model = (DefaultListModel)list.getModel();
+		//  		    ArrayList values = new ArrayList();
+		//  		    for(int i = 0; i < model.size(); i++) {
+		//  			values.add(model.get(i));
+		//  		    }
+		//  		    argument.setValues(values);
+		//  		    argument.setAssigned(true);
+		//  		    return true;
+	    case Argument.HIERARCHY:
+		// 		    argument.setValue(((JComboBox)value).getSelectedItem().toString());
+		// 		    // Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted.
+		// 		    argument.setAssigned(true);
+		return true;
+	    case Argument.REGEXP:
+	    case Argument.STRING:
+		result = ((JTextField)value_control).getText();
+		if(result.length() > 0) {
+		    argument.setValue(result);
+		}
+		else {
+		    String args[] = new String[1];
+		    args[0] = argument.getName();
+		    if(argument.isRequired()) {
+			JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.Required_Argument", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
+		    }
+		    // They've left the field blank
+		    else {
+			JOptionPane.showMessageDialog(this, Dictionary.get("CDM.ArgumentConfiguration.No_Value", args), Dictionary.get("CDM.ArgumentConfiguration.Error_Title"), JOptionPane.ERROR_MESSAGE);
+			argument.setValue(null);
+		    }
+		    args = null;
+		    return false;
+		}
+		argument.setAssigned(true);
+		return true;
+	    }
+	    return false;
+	}
+	else {
+	    argument.setAssigned(false);
+	    return true;
+	}
+    }
+    /** Method to ensure that a certain value is selected, if it exists within that combobox to begin with.
+     * @param combobox The <strong>JComboBox</strong> whose selection we are trying to preset.
+     * @param target The desired value of the selection as a <strong>String</strong>.
+     * @return true if the item was found and selected, false otherwise
+     * @see org.greenstone.gatherer.cdm.ArgumentConfiguration.ArgumentControl.ListOption
+     */
+    public boolean selectValue(JComboBox combobox, String target) {
+	///ystem.err.println("Searching for the target string: " + target);
+	for(int i = 0; i < combobox.getItemCount(); i++) {
+	    Object object = combobox.getItemAt(i);
+	    if(object instanceof ListOption) {
+		ListOption lo = (ListOption) object;
+		///ystem.err.print("/tChecking: " + lo.getValue() + "... ");
+		if(lo.getValue().startsWith(target)) {
+		    ///ystem.err.println("Match!");
+		    combobox.setSelectedIndex(i);
+		    return true;
+		}
+		/*
+		  else {
+		  System.err.println("No Match.");
+		  }
+		*/
+	    }
+	    else if (object instanceof MetadataElement) {
+		if(object.toString().equals(target)) {
+		    combobox.setSelectedIndex(i);
+		    return true;
+		}
+	    }
+	}
+	return false;
+    }
+    /** Forces the control into an 'enabled' mode. */
+    public void setEnabled() {
+	enabled.setSelected(true);
+    }
+    /** Explicitly sets the value of a JTextField type control to the given String.
+     * @param value_str The new value of the control as a <strong>String</strong>.
+     */
+    public void setValue(String value_str) {
+	((JTextField)value_control).setText(value_str);
+    }
+
+    /** Listens for actions apon the enable checkbox, and if detected enables or diables control appropriately. */
+    private class EnabledListener
+	implements ActionListener {
+	/** An editor component, such as a JComboBox or JTextField, that might have its enabled state changed by this listener. */
+	private JComponent target = null;
+	
+	/** Constructor. */
+	public EnabledListener(JComponent target) {
+	    this.target = target;
+	}
+	
+	/** Any implementation of ActionListener must include this method so that we can be informed when an action has been performed on or registered check box, prompting us to change the state of the other controls as per the users request.
+	 * @param event An <strong>ActionEvent</strong> containing information about the click.
+	 */
+	public void actionPerformed(ActionEvent event) {
+	    if (this.target == null) {
+		return;
+	    }
+	    JCheckBox source = (JCheckBox)event.getSource();
+	    if(source.isSelected()) {
+		target.setBackground(Color.white);
+		target.setEnabled(true);
+	    }
+	    else {
+		target.setBackground(Color.lightGray);
+		target.setEnabled(false);
+	    }
+	    // Special case of stupid JSpinners who don't let their backgrounds change properly.
+	    if(target instanceof JSpinner) {
+		JSpinner spinner = (JSpinner) target;
+		JComponent c = spinner.getEditor();
+		if ( c instanceof JSpinner.DefaultEditor ) {
+		    JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
+		    JFormattedTextField field = editor.getTextField();
+		    field.setEditable(source.isSelected());
+		    if(source.isSelected()) {
+			field.setBackground(Color.white);
+		    }
+		    else {
+			field.setBackground(Color.lightGray);
+		    }
+		}
+	    }
+	}
+    }
+    
+
+
+    /** A ListOption is a compound item which is constructed from several Strings. That magic part is that the length of screen real-estate used by the text version of this item is limited. */
+    private class ListOption
+	implements Comparable {
+	/** The maximum length of this String version of this item. */
+	private int MAX_DESC = 47;
+	/** The description of the value for this item. */
+	private String description = null;
+	/** A cached value for the text value of this option, as it never changes after the first call to toString(). */
+	private String text = null;
+	/** The value for this item. */
+	private String value = null;
+	/** Constructor.
+	 * @param value The value for this item as a <strong>String</strong>.
+	 * @param description The description of the value as a <strong>String</strong>.
+	 */
+	public ListOption(String value, String description) {
+	    this.description = description;
+	    this.value = value;
+	}
+	/** Compare two possible ListOption objects for ordering.
+	 * @param object The <strong>Object</strong> to compare to.
+	 * @return An <i>int</i> indicating order as explained in String.
+	 * @see java.lang.String#compareTo
+	 */
+	public int compareTo(Object object) {
+	    return toString().compareTo(object.toString());
+	}
+	/** Tests two possible ListOption objects for equality. Uses the result from compareTo().
+	 * @param object The <strong>Object</strong> which may be equal.
+	 * @return <i>true</i> if the objects are equal, <i>false</i> otherwise.
+	 */
+	public boolean equals(Object object) {
+	    return (object != null && compareTo(object) == 0);
+	}
+	/** Retrieve the description of this list item.
+	 * @return The description as a <strong>String</strong>.
+	 */
+	public String getDesc() {
+	    return description;
+	}
+	/** Retrieve the value of this list item.
+	 * @return The value as a <strong>String</strong>.
+	 */
+	public String getValue() {
+	    return value;
+	}
+	/** Convert this object into a nice readable String.
+	 * @return A <strong>String</strong> representing this object.
+	 */
+	public String toString() {
+	    if(text == null) {
+		if(value.length() + description.length() >= MAX_DESC) {
+		    text = value + " "+ StaticStrings.MINUS_CHARACTER + " "+ description.substring(0, MAX_DESC-value.length()) + StaticStrings.TRUNCATED_STRING;
+		}
+		else {
+		    text = value + " "+ StaticStrings.MINUS_CHARACTER + " "+ description;
+		}
+	    }
+	    return text;
+	}
+    }
+
+
+    /** Listener that sets the tooltip associated to a combobox to the tooltip relevant to the selected item. */
+    private class ToolTipUpdater
+	implements ActionListener {
+	/** Any implementation of an ActionListener must include this method so that we can be informed when the selection in a combobox has changed and update the tooltip accordingly.
+	 * @param event An <strong>ActionEvent</strong> containing information about the action that fired this call.
+	 */
+	public void actionPerformed(ActionEvent event) {
+	    JComboBox source = (JComboBox)event.getSource();
+	    Object object = source.getSelectedItem();
+	    if(object instanceof ListOption) {
+		ListOption lo = (ListOption)object;
+		if(lo != null) {
+		    String description = Utility.formatHTMLWidth(lo.getDesc(), 60);
+		    source.setToolTipText(description);
+		}
+		else {
+		    source.setToolTipText(StaticStrings.EMPTY_STR);
+		}
+	    }
+	}
+    }
+}
Index: unk/gli/src/org/greenstone/gatherer/gui/ArgumentControl.java
===================================================================
--- /trunk/gli/src/org/greenstone/gatherer/gui/ArgumentControl.java	(revision 12304)
+++ 	(revision )
@@ -1,357 +1,0 @@
-/**
- *#########################################################################
- *
- * A component of the Gatherer application, part of the Greenstone digital
- * library suite from the New Zealand Digital Library Project at the
- * University of Waikato, New Zealand.
- *
- * <BR><BR>
- *
- * Author: John Thompson, Greenstone Digital Library, University of Waikato
- *
- * <BR><BR>
- *
- * Copyright (C) 1999 New Zealand Digital Library Project
- *
- * <BR><BR>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * <BR><BR>
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * <BR><BR>
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *########################################################################
- */
-package org.greenstone.gatherer.gui;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.io.*;
-import java.util.*;
-import javax.swing.*;
-import javax.swing.event.*;
-import javax.swing.text.*;
-
-import org.greenstone.gatherer.Configuration;
-import org.greenstone.gatherer.Gatherer;
-import org.greenstone.gatherer.cdm.Argument;
-import org.greenstone.gatherer.util.StaticStrings;
-import org.greenstone.gatherer.util.Utility;
-import org.greenstone.gatherer.metadata.MetadataSet;
-import org.greenstone.gatherer.metadata.MetadataSetManager;
-
-public class ArgumentControl
-    extends JPanel {
-    static protected Dimension LABEL_SIZE = new Dimension(180, 25);
-    static protected Dimension ROW_SIZE = new Dimension(610, 30);
-    static protected Dimension SPINNER_SIZE = new Dimension(100, 25);
-    static protected String DESCRIPTION_SEP = " + ";
-
-    protected Argument argument;
-    protected JComponent value_control;
-    protected JCheckBox enabled;
-
-    public ArgumentControl(Argument argument, boolean enable, String value) {
-	super();
-	this.argument = argument;
-	String tooltip = Utility.formatHTMLWidth("<html>" + argument.getDescription() + "</html>", 60);
-	setBackground(Configuration.getColor("coloring.collection_tree_background", false));
-	setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
-	setLayout(new BorderLayout());
-	setPreferredSize(ROW_SIZE);
-	setMaximumSize(ROW_SIZE);
-	
-	// Try to determine what the value_controls value should be.
-	if(value == null) {
-	    value = argument.getDefaultValue();
-	}
-	// Create a correct value control based on the argument provided.
-	switch(argument.getType()) {
-	case Argument.ENUM:
-	case Argument.METADATUM:
-	    JComboBox combobox = new JComboBox();
-	    combobox.setEnabled(enable);
-	    combobox.setToolTipText(tooltip);
-	    combobox.setBackground(enable ? Color.white : Color.lightGray);
-	    
-	    // Build an option model, wrapping each entry of the list table
-	    if (argument.getType() == Argument.ENUM) {
-		HashMap arg_list = argument.getOptions();
-		Iterator it = arg_list.keySet().iterator();
-		ArrayList options = new ArrayList();
-		while (it.hasNext()) {
-		    options.add((String) it.next());
-		}
-		Collections.sort(options);
-		for (int i=0; i<options.size(); i++) {
-		    combobox.addItem(options.get(i));
-		}
-		// Connect this so if a value is selected the tooltip updates accordingly
-		combobox.addActionListener(new ToolTipUpdater(arg_list));
-	    }
-	    if (argument.getType() == Argument.METADATUM) {
-		ArrayList every_metadata_set_element = MetadataSetManager.getEveryMetadataSetElement();
-		for (int i = 0; i < every_metadata_set_element.size(); i++) {
-		    combobox.addItem(every_metadata_set_element.get(i));
-		}
-	    }
-
-	    if (value != null) {
-		// Set the selected string
-		for (int i = 0; i < combobox.getItemCount(); i++) {
-		    if (combobox.getItemAt(i).toString().equals(value)) {
-			combobox.setSelectedIndex(i);
-		    }
-		}
-	    }
-	    // Layout
-	    add(combobox, BorderLayout.CENTER);
-	    // And remember
-	    value_control = combobox;
-	    break;
-	case Argument.FLAG:
-	    // Only need the check box.
-	    value_control = null;
-	    break;
-	case Argument.INTEGER:
-	    // Build a spinner
-	    int initial_value=0;
-	    if (value != null) {
-		try {
-		    initial_value = Integer.parseInt(value);
-		} catch (Exception exception) {
-		}
-	    }
-	    if (initial_value < argument.getMinimum()) {
-		initial_value = argument.getMinimum();
-	    } else if (initial_value > argument.getMaximum()) {
-		initial_value = argument.getMaximum();
-	    }
-	    JSpinner spinner = new JSpinner(new SpinnerNumberModel(initial_value, argument.getMinimum(), argument.getMaximum(), 1));		
-	    spinner.setEnabled(enable);
-	    spinner.setPreferredSize(SPINNER_SIZE);
-	    spinner.setToolTipText(tooltip);
-	    // Set enabled
-	    JComponent c = spinner.getEditor();
-	    if ( c instanceof JSpinner.DefaultEditor ) {
-		JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
-		JFormattedTextField field = editor.getTextField();
-		field.setEditable(enable);
-		if(enable) {
-		    field.setBackground(Color.white);
-		}
-		else {
-		    field.setBackground(Color.lightGray);
-		}
-	    }
-	    // Layout
-	    add(new JLabel(), BorderLayout.CENTER);
-	    add(spinner, BorderLayout.EAST);
-	    // And remember it
-	    value_control = spinner;
-	    break;
-	case Argument.REGEXP:
-	case Argument.STRING:
-	    // Use a standard text field
-	    JTextField textfield = new JTextField();
-	    textfield.setEnabled(enable);
-	    textfield.setToolTipText(tooltip);
-	    // Set enabled
-	    if(enable) {
-		textfield.setBackground(Color.white);
-	    }
-	    else {
-		textfield.setBackground(Color.lightGray);
-	    }
-	    // If there was an original value, set it.
-	    if(value != null) {
-		textfield.setText(value);
-	    }
-	    // Layout
-	    add(textfield, BorderLayout.CENTER);
-	    // And remember it
-	    value_control = textfield;
-	    break;
-	case Argument.METADATA_SET_NAMESPACE:
-	    JComboBox metadata_sets_combobox = new JComboBox();
-	    metadata_sets_combobox.setEnabled(enable);
-	    metadata_sets_combobox.setToolTipText(tooltip);
-	    metadata_sets_combobox.setBackground(enable ? Color.white : Color.lightGray);
-
-	    // !! Hack for exploding metadata databases: add the (empty) exploded metadata set
-	    File exploded_metadata_set_file = new File(Gatherer.getGLIMetadataDirectoryPath() + "exp" + StaticStrings.METADATA_SET_EXTENSION);
-	    MetadataSet exploded_metadata_set = new MetadataSet(exploded_metadata_set_file);
-	    Gatherer.c_man.importMetadataSet(exploded_metadata_set);
-
-	    // All the loaded metadata sets except the extracted metadata set are applicable
-	    ArrayList metadata_sets = MetadataSetManager.getMetadataSets();
-	    for (int i = metadata_sets.size() - 1; i >= 0; i--) {
-		MetadataSet metadata_set = (MetadataSet) metadata_sets.get(i);
-		if (!(metadata_set.getNamespace().equals(MetadataSetManager.EXTRACTED_METADATA_NAMESPACE))) {
-		    metadata_sets_combobox.addItem(metadata_set);
-		}
-	    }
-
-	    // Layout
-	    add(metadata_sets_combobox, BorderLayout.CENTER);
-	    // And remember
-	    value_control = metadata_sets_combobox;
-	    break;
-	}
-
-	// If the argument is required, then you don't get a choice of whether it is enabled.
-	if(argument.isRequired()) {
-	    JLabel label = new JLabel(argument.getName());
-	    label.setOpaque(false);
-	    label.setPreferredSize(LABEL_SIZE);
-	    label.setToolTipText(tooltip);
-	    add(label, BorderLayout.WEST);
-	}
-	else {
-	    enabled = new JCheckBox(argument.getName(), enable);
-	    enabled.setOpaque(false);
-	    enabled.setPreferredSize(LABEL_SIZE);
-	    enabled.setToolTipText(tooltip);
-	    // Connect
-	    enabled.addActionListener(new EnabledListener(value_control));
-	    // Layout
-	    add(enabled, BorderLayout.WEST);
-	}
-    }
-
-    public String getArgumentName()
-    {
-	return argument.getName();
-    }
-
-    public String getValue() {
-	String value = null;
-	if(value_control == null) {
-	    // Flag value, nothing to do.
-	}
-	else if(value_control instanceof JTextField) {
-	    value = ((JTextField)value_control).getText();
-	}
-	else if(value_control instanceof JSpinner) {
-	    value = ((JSpinner)value_control).getValue().toString();
-	}
-	else if(value_control instanceof JComboBox) {
-	    Object selected_item = ((JComboBox)value_control).getSelectedItem();
-	    if (selected_item != null) {
-		if (argument.getType() == Argument.METADATA_SET_NAMESPACE) {
-		    value = ((MetadataSet) selected_item).getNamespace();
-		}
-		else {
-		    value = selected_item.toString();
-		}
-	    }
-	}
-	return value;
-    }
-    /** Retrieve the control used for storing values.
-     * @return JComponent
-     */
-    public JComponent getValueControl() {
-	return value_control;
-    }
-
-    public boolean isEnabled() {
-	if (enabled == null) {
-	    return true; // always enabled
-	} 
-	return enabled.isSelected();
-    }
-
-    /** Method to ensure that a certain value is selected, if it exists within that combobox to begin with.
-     * @param combobox the JComboBox whose selection we are trying to preset
-     * @param target The desired value of the selection as a String
-     * @return true if the item was found and selected, false otherwise
-     */
-    public boolean selectValue(JComboBox combobox, String target) {
-	for(int i = 0; i < combobox.getItemCount(); i++) {
-	    if(combobox.getItemAt(i).toString().equals(target)) {
-		combobox.setSelectedIndex(i);
-		return true;
-	    }
-	}
-	return false;
-    }
-
-    /** Listens for actions apon the enable checkbox, and if detected enables or diables control appropriately. */
-    private class EnabledListener
-	implements ActionListener {
-	/** An editor component, such as a JComboBox or JTextField, that might have its enabled state changed by this listener. */
-	private JComponent target = null;
-	/** Constructor. */
-	public EnabledListener(JComponent target) {
-	    this.target = target;
-	}
-	/** Any implementation of ActionListener must include this method so that we can be informed when an action has been performed on or registered check box, prompting us to change the state of the other controls as per the users request.
-	 * @param event An <strong>ActionEvent</strong> containing information about the click.
-	 */
-	public void actionPerformed(ActionEvent event) {
-	    JCheckBox source = (JCheckBox)event.getSource();
-	    if(target != null) {
-		if(source.isSelected()) {
-		    target.setBackground(Color.white);
-		    target.setEnabled(true);
-		}
-		else {
-		    target.setBackground(Color.lightGray);
-		    target.setEnabled(false);
-		}
-		// Special case of stupid JSpinners who don't let their backgrounds change properly.
-		if(target instanceof JSpinner) {
-		    JSpinner spinner = (JSpinner) target;
-		    JComponent c = spinner.getEditor();
-		    if ( c instanceof JSpinner.DefaultEditor ) {
-			JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor) c;
-			JFormattedTextField field = editor.getTextField();
-			field.setEditable(source.isSelected());
-			if(source.isSelected()) {
-			    field.setBackground(Color.white);
-			}
-			else {
-			    field.setBackground(Color.lightGray);
-			}
-		    }
-		}
-	    }
-	}
-    }
-
-   /** Listener that sets the tooltip associated to a combobox to the tooltip relevant to the selected item. */
-    private class ToolTipUpdater
-	implements ActionListener {
-	private HashMap arg_list;
-	public ToolTipUpdater(HashMap arg_list) {
-	    this.arg_list = arg_list;
-	}
-	/** Any implementation of an ActionListener must include this method so that we can be informed when the selection in a combobox has changed and update the tooltip accordingly.
-	 * @param event An <strong>ActionEvent</strong> containing information about the action that fired this call.
-	 */
-	public void actionPerformed(ActionEvent event) {
-	    JComboBox source = (JComboBox)event.getSource();
-	    String key = (String) source.getSelectedItem();
-	    if(arg_list != null) {
-		String description = (String) arg_list.get(key);
-		if(description != null) {
-		    description = Utility.formatHTMLWidth(description, 60);
-		    source.setToolTipText(description);
-		}
-	    }
-	}
-    }
-}
Index: /trunk/gli/src/org/greenstone/gatherer/gui/ExplodeMetadataPrompt.java
===================================================================
--- /trunk/gli/src/org/greenstone/gatherer/gui/ExplodeMetadataPrompt.java	(revision 12304)
+++ /trunk/gli/src/org/greenstone/gatherer/gui/ExplodeMetadataPrompt.java	(revision 12305)
@@ -42,4 +42,5 @@
 import org.greenstone.gatherer.LocalGreenstone;
 import org.greenstone.gatherer.cdm.Argument;
+import org.greenstone.gatherer.cdm.ArgumentControl;
 import org.greenstone.gatherer.cdm.CollectionDesignManager;
 import org.greenstone.gatherer.cdm.Plugin;
@@ -198,5 +199,5 @@
        
 	// first we add the plugin arg
-	ArgumentControl argument_control = new ArgumentControl(plugin_arg,true, null);
+	ArgumentControl argument_control = new ArgumentControl(plugin_arg, true, null);
 	argument_control.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
 	options_pane.add((JComponent)argument_control);
@@ -209,5 +210,5 @@
 		}
 		// by default, all args are disabled, and no value
-		argument_control = new ArgumentControl(argument,false, null);
+		argument_control = new ArgumentControl(argument, false, null);
 		// make sure they are coloured the way we want - this is not the standard arg control coloring
 		argument_control.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
Index: /trunk/gli/src/org/greenstone/gatherer/gui/OptionsPane.java
===================================================================
--- /trunk/gli/src/org/greenstone/gatherer/gui/OptionsPane.java	(revision 12304)
+++ /trunk/gli/src/org/greenstone/gatherer/gui/OptionsPane.java	(revision 12305)
@@ -49,4 +49,5 @@
 import org.greenstone.gatherer.Gatherer;
 import org.greenstone.gatherer.cdm.Argument;
+import org.greenstone.gatherer.cdm.ArgumentControl;
 import org.greenstone.gatherer.collection.ScriptOptions;
 import org.greenstone.gatherer.collection.Collection;
