Index: /main/trunk/gli/classes/dictionary.properties
===================================================================
--- /main/trunk/gli/classes/dictionary.properties	(revision 34265)
+++ /main/trunk/gli/classes/dictionary.properties	(revision 34266)
@@ -979,7 +979,18 @@
 
 #***** ConfigFileEditor *****
-ConfigFileEditor.Tooltip:Greenstone 3 collection configuration XML editor.
 ConfigFileEditor.Save_Tooltip:Save changes and close.
 ConfigFileEditor.Cancel_Tooltip:Close without saving.
+ConfigFileEditor.Add_Element_Label:Add element to:
+ConfigFileEditor.Add_Label:Add
+ConfigFileEditor.Add_Element_Tooltip:Select the (security related) element to add to the collection configuration file then edit the newly added element accordingly.
+ConfigFileEditor.Hide_Collection:Hide the collection
+ConfigFileEditor.Secure_Collection:Secure the collection
+ConfigFileEditor.Secure_All_Documents:Secure all documents in this collection
+ConfigFileEditor.Secure_Certain_Documents:Secure certain documents in this collection
+ConfigFileEditor.Add_Another_DocumentSet:Add another documentSet element
+ConfigFileEditor.Add_Another_Exception:Add another exception element
+ConfigFileEditor.Press_Undo_Once_More_First:Cannot add to the collection configuration as it is currently empty. Try pressing Undo (once more) first to get any earlier configuration contents back before trying to add further elements to it.
+ConfigFileEditor.Need_Security_Element_To_Add:Since there is no <security> element in collectionConfig.xml yet, cannot add further elements to it. Try one of the Secure... options first before trying this option again.
+ConfigFileEditor.Config_Already_Has_Security_Element:The collectionConfiguration.xml file already contains a <security> element, cannot add more to it. Remove the existing element in entirety first before attempting to add a new one.
 
 #**********************
Index: /main/trunk/gli/classes/xml/elementsForInsertion.xml
===================================================================
--- /main/trunk/gli/classes/xml/elementsForInsertion.xml	(revision 34266)
+++ /main/trunk/gli/classes/xml/elementsForInsertion.xml	(revision 34266)
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<Elements>
+  <!-- for now, only security related elements are available to add into the collection's config file
+       using GLI's collection ConfigFileEditor that's available for GS3.
+       See http://wiki.greenstone.org/doku.php?id=en:user:authentication
+       and especially http://wiki.greenstone.org/doku.php?id=en:user_advanced:security
+  -->
+
+  <!-- Leave the elements in this file in this order for now.
+       Code using this file (ConfigFileEditor.java) is dependent on ordering for ease of coding.
+  -->
+  
+  <!-- element for hiding a collection -->
+  <metadata name="public">false</metadata>
+
+  <!-- element to make the entire collection private except for specified group(s) -->
+  <security scope="collection" default_access="private">
+    <exception>
+      <group name="TYPE-GROUP-NAME-HERE"/>
+      <!--<group name="KEEP-ADDING-ANOTHER-OF-THESE-TO-GIVE-ACCESS-TO-AN-ADDITIONAL-GROUP"/>-->
+    </exception>
+  </security>
+
+  <!-- element to make all docs in collection private except for specified group(s).
+       Can browse and search in collection, but docs found by browsing/searching can't be viewed -->
+  <security scope="document" default_access="private">
+    <exception>
+      <group name="TYPE-GROUP-NAME-HERE"/>
+      <!--<group name="KEEP-ADDING-ANOTHER-OF-THESE-TO-GIVE-ACCESS-TO-AN-ADDITIONAL-GROUP"/>-->
+    </exception>
+  </security>
+
+  <!-- Make certain collection's docs private: except being some carefully defined set(s) of docs,
+       which should then be made accessible only to the groups specified here as having access to
+       those documentset(s).
+       If different documentSets should be accessible to different groups, then define multipe
+       <exception> elements here, each referencing the different docset(s) that exception pertains to.
+  -->
+  <security scope="document" default_access="public">
+    
+    <exception>
+      <documentSet name="INVENT-A-RESTRICTED-DOCSET-NAME-HERE"/>
+      <!--<documentSet name="CAN-HAVE-ADDITIONAL-DOCSETS"/>-->
+      <group name="TYPE-GROUP-NAME-THAT-SHOULD-HAVE-ACCESS-TO-RESTRICTED-DOCSET(S)"/>
+      <!--<group name="ADD-ANOTHER-OF-THESE-TO-GIVE-AN-ADDITIONAL-GROUP-ACCESS-TO-THE-SAME-DOCSET(S)"/>-->
+    </exception>
+
+    <documentSet name="REPEAT-INVENTED-RESTRICTED-DOCSET-NAME-HERE">
+      <match type="match" field="TYPE-HERE-THE-METADATA-FIELD-NAME-WHOSE-VALUE-SHOULD-MATCH">TYPE-HERE-THE-METADATA-VALUE-THAT-SHOULD-EXACTLY-MATCH</match>
+      <!--<match type="regex" field="TYPE-METADATA-FIELD-NAME">TYPE-HERE-THE-SO-CALLED-REGEX-PATTERN-THAT-THE-METADATA-VALUE-SHOULD-MATCH</match>-->
+      <!--<match>TYPE-THE-DOC-IDENTIFIER-OF-RESTRICTED-DOC-HERE</match>-->
+      
+      <!--ADD AS MANY <match> elements as you like to define this documentSet-->
+      
+    </documentSet>
+  </security>
+  
+</Elements>
Index: /main/trunk/gli/src/org/greenstone/gatherer/gui/ConfigFileEditor.java
===================================================================
--- /main/trunk/gli/src/org/greenstone/gatherer/gui/ConfigFileEditor.java	(revision 34265)
+++ /main/trunk/gli/src/org/greenstone/gatherer/gui/ConfigFileEditor.java	(revision 34266)
@@ -55,4 +55,7 @@
     public final File config_file;
 
+    /** User can add some complex elements by clcking a button */
+    private Document elements_available_for_insertion;
+    
     private GLIButton cancel_button = null;
     private GLIButton save_button = null;
@@ -60,4 +63,6 @@
     private JTextArea editor_msgarea;
 
+    private JComboBox chooseElementComboBox;
+    private GLIButton addElementButton;
     
     // https://github.com/bobbylight/RSyntaxTextArea/wiki/Example:-Using-Find-and-Replace
@@ -67,9 +72,38 @@
     private JButton nextButton;
     private JButton prevButton;
-	
+    
     //private final String DEFAULT_PROCESSING_INSTRUCTION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";    
 
     private static final Dimension SIZE = new Dimension(850,550);
 
+    
+    // Enum to define elements the user can add
+    // enum available from Java 1.5
+    // https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
+    // https://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html
+    private enum ElementOption {	
+	HIDE_COLLECTION (Dictionary.get("ConfigFileEditor.Hide_Collection")),
+	SECURE_COLLECTION (Dictionary.get("ConfigFileEditor.Secure_Collection")),
+	SECURE_ALL_DOCUMENTS(Dictionary.get("ConfigFileEditor.Secure_All_Documents")),
+	SECURE_CERTAIN_DOCUMENTS(Dictionary.get("ConfigFileEditor.Secure_Certain_Documents")),
+	ADD_ANOTHER_DOCUMENTSET(Dictionary.get("ConfigFileEditor.Add_Another_DocumentSet")),
+	ADD_ANOTHER_EXCEPTION(Dictionary.get("ConfigFileEditor.Add_Another_Exception"));	
+	
+	private final String displayString;
+	// Constructor may not be declared as public
+	ElementOption(String displayStr) {
+	    // interesting that Enum implementation classes don't
+	    // have to call protected superclass constructor
+	    displayString = displayStr;
+	}
+
+	// override default behaviour of returning the ENUM string itself
+	// to display the displayString instead
+	public String toString() {
+	    return displayString;
+	}
+    }
+
+    
     public ConfigFileEditor() {
 	
@@ -127,5 +161,7 @@
 	
 	// the all important XML editor
-	editor = new NumberedJTextArea(Dictionary.get("ConfigFileEditor.Tooltip"));
+	editor = new NumberedJTextArea(); // Don't pass in tooltip string for editor:
+	                                  // The editor's purpose should be obvious, and
+	                                  // the tooltip annoyingly constantly floats over the editor all the time
 	editor.getDocument().addDocumentListener(this);
 	// if Ctrl (or Mac equiv) + F is pressed in the config file editing area,
@@ -138,5 +174,26 @@
 	save_button.addActionListener(this);
 
+	// widgets in section for adding security-related XML elements into the collectionConfigXML file
+	JLabel addElementLabel = new JLabel(Dictionary.get("ConfigFileEditor.Add_Element_Label"));
+
+	chooseElementComboBox = new JComboBox(ElementOption.values()); // calls the implicit static values() method on Enum class to get an array of all Enum values
+	addElementButton = new GLIButton(Dictionary.get("ConfigFileEditor.Add_Label"),
+					 Dictionary.get("ConfigFileEditor.Add_Element_Tooltip"));
+	elements_available_for_insertion = XMLTools.parseXMLFile("xml/elementsForInsertion.xml", true);
+	addElementButton.addActionListener(this);
+
+	// Elements can't be added if gli/classes/xml/elementsForInsertion.xml file
+	// does not exist or can't be parsed
+	if(elements_available_for_insertion == null) {
+	    addElementButton.setEnabled(false);
+	}
+	
 	// LAYOUT
+	JPanel add_elements_panel = new JPanel(new FlowLayout());
+	add_elements_panel.setComponentOrientation(Dictionary.getOrientation());
+	add_elements_panel.add(addElementLabel);
+	add_elements_panel.add(chooseElementComboBox);
+	add_elements_panel.add(addElementButton);
+	
 	JPanel button_panel = new JPanel(new FlowLayout());
 	button_panel.setComponentOrientation(Dictionary.getOrientation());
@@ -145,9 +202,10 @@
 	button_panel.add(cancel_button);
 	button_panel.add(save_button);
-
+	
 	// toolbars_panel to contain find-and-replace toolbar and undo/redo/cancel/save button panel
 	JPanel toolbars_panel = new JPanel(new BorderLayout());
 	toolbars_panel.add(toolBar, BorderLayout.NORTH);
-	toolbars_panel.add(button_panel, BorderLayout.CENTER);
+	toolbars_panel.add(add_elements_panel, BorderLayout.CENTER);
+	toolbars_panel.add(button_panel, BorderLayout.SOUTH);
 	
 	JPanel content_pane = (JPanel) getContentPane();
@@ -196,4 +254,5 @@
 		editor_msgarea.setText(msg); // display the parsing error
 		save_button.setEnabled(false);
+		addElementButton.setEnabled(false);
 
 		editor.setText(xml_str); // display the xml contents with error and all		
@@ -204,5 +263,5 @@
 	    }	    
 	}
-	
+
 
 	// Final dialog setup & positioning.
@@ -320,6 +379,128 @@
 	    
 	}
-    }
-    
+	else if(e.getSource() == addElementButton) {
+	    
+	    ElementOption elementToAdd = (ElementOption)chooseElementComboBox.getSelectedItem();
+	    addElementToConfigFile(elementToAdd);
+	    
+	}
+    }
+
+    /** Method to add the selected security-related element to the config file
+     * so that the user can then edit it to behave as they wish.
+     */
+    private void addElementToConfigFile(ElementOption elementOption) {
+
+	// if the user just undid a previous add operation, then the editor would be empty
+	// and can't be parsed. In such a case, don't try to add any elements into the editor
+	String config_xml_str = editor.getText();
+	if(config_xml_str.equals("")) {
+	    editor_msgarea.setText(Dictionary.get("ConfigFileEditor.Press_Undo_Once_More_First"));
+	    editor_msgarea.setBackground(Color.orange);
+	    return;
+	}
+	Document config_xml_doc = XMLTools.getDOM(config_xml_str);
+	// The addElementButton would not have been enabled/available for pressing
+	// and we wouldn't be here unless the collConfig xml parses fine.	
+
+	Element targetParent = config_xml_doc.getDocumentElement(); // tentative target element
+	
+
+	final String SECURITY = "security"; // just looking for security elements to insert
+	final String EXCEPTION = "exception"; // just looking for security elements to insert
+	final String DOCUMENTSET = "documentSet"; // just looking for security elements to insert
+	
+	NodeList children = elements_available_for_insertion.getElementsByTagName(SECURITY);	    
+
+	Element elementToAdd = null;
+	
+	// To find out if the collectionConfig.xml has any security nodes in it already
+	NodeList configXMLSecurityNodes = config_xml_doc.getElementsByTagName(SECURITY);
+
+	
+	// Switch on an Enum type is interesting:
+	// don't have to do "case ElementOption.HIDE_COLLECTION:"
+	// and just "case HIDE_COLLECTION:" is fine
+	// see https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
+
+	switch(elementOption) {
+	case HIDE_COLLECTION:
+	    Element publicElement = XMLTools.getNamedElement(
+					      config_xml_doc.getDocumentElement(), // parent
+					      "metadata", // element name
+					      "name", // attribute name
+					      "public" // attribute value
+				      );
+	    
+	    if(publicElement != null) {
+		XMLTools.setNodeText(publicElement, "false");
+		// done, with elementToAdd = null, no more processing
+	    } else { // collConfig.xml missing <metadata name="public">true</metadata>
+		// need to add in the necessary element from elements_available_for_insertion XML,
+		// which is set to hide
+		elementToAdd = XMLTools.getNamedElement(
+					elements_available_for_insertion.getDocumentElement(), // parent
+					"metadata", // element name
+					"name", // attribute name
+					"public" // attribute value
+				);
+	    }
+	    break;
+	    
+	case SECURE_COLLECTION:
+	case SECURE_ALL_DOCUMENTS:
+	case SECURE_CERTAIN_DOCUMENTS:
+	    if(configXMLSecurityNodes.getLength() == 0) {
+		elementToAdd = (Element)children.item(elementOption.ordinal()-1);
+	    } else {
+		editor_msgarea.setText(Dictionary.get("ConfigFileEditor.Config_Already_Has_Security_Element"));
+		editor_msgarea.setBackground(Color.orange);
+	    }
+	    break;
+	    
+	    
+	case ADD_ANOTHER_DOCUMENTSET:
+	case ADD_ANOTHER_EXCEPTION:
+	    
+	    if(configXMLSecurityNodes.getLength() > 0) {
+
+		// get first security element child of collectionConfigXML file.
+		// There should at most be one
+		targetParent = (Element)configXMLSecurityNodes.item(0);
+		Element lastSecurityElement = (Element)children.item(children.getLength()-1);
+	    
+		if(elementOption == ElementOption.ADD_ANOTHER_DOCUMENTSET) {
+		    // Get the immediate child called documentSet, not any other descendants by that name
+		    // i.e. not the child <exception> element's child called <documentSet>, but the last
+		    // <security> element's <documentSet> element
+		    elementToAdd = (Element)XMLTools.getChildByTagName(lastSecurityElement, DOCUMENTSET);
+		}
+		else { // ElementOption.ADD_ANOTHER_EXCEPTION:
+
+		    // Get the last <security> element's sole <exception> child
+		    elementToAdd = (Element)XMLTools.getChildByTagName(lastSecurityElement, EXCEPTION);
+		}
+	    }
+	    else {
+		// Can't Add Another DocSet/Exception element if the collectionConfigXML has no
+		// Security element in place to add them into.
+		// Display an error/warning if no security element and don't do anything.	    
+		
+		targetParent = null;
+		editor_msgarea.setText(Dictionary.get("ConfigFileEditor.Need_Security_Element_To_Add"));
+		editor_msgarea.setBackground(Color.orange);
+	    }
+	    break;
+	}
+
+	if(elementToAdd != null) {
+	    Node copiedNode = config_xml_doc.importNode(elementToAdd, true);
+	    targetParent.appendChild(copiedNode);
+	    StringBuffer xml_str_buf = new StringBuffer();
+	    // now set the text in the XML editor to reflect the changes to the doc	    
+	    XMLTools.xmlNodeToString(xml_str_buf, config_xml_doc.getDocumentElement(), true, "  ", 0); 
+	    editor.setText(xml_str_buf.toString()); // display the xml contents with error and all	    
+	} // TODO: sadly, the act of doing a editor.setText() adds 2 actions to undo history instead of 1
+    }
    
     // This method returns a proper processing instruction (starts with <?xml and ends with ?>)
@@ -395,4 +576,5 @@
 		editor_msgarea.setBackground(Color.red);
 		save_button.setEnabled(false);
+		addElementButton.setEnabled(false);
 	    }
     }
Index: /main/trunk/gli/src/org/greenstone/gatherer/gui/NumberedJTextArea.java
===================================================================
--- /main/trunk/gli/src/org/greenstone/gatherer/gui/NumberedJTextArea.java	(revision 34265)
+++ /main/trunk/gli/src/org/greenstone/gatherer/gui/NumberedJTextArea.java	(revision 34266)
@@ -53,4 +53,8 @@
     public final GLIButton redoButton;
 
+    public NumberedJTextArea() {
+	this("");
+    }
+    
     public NumberedJTextArea(String tooltip) {
 	this("", tooltip);
