Index: main/trunk/greenstone3/web/interfaces/default/js/gsajaxapi.js
===================================================================
--- main/trunk/greenstone3/web/interfaces/default/js/gsajaxapi.js	(revision 31541)
+++ main/trunk/greenstone3/web/interfaces/default/js/gsajaxapi.js	(revision 31542)
@@ -167,84 +167,84 @@
 // http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp
     this.urlPostSync = function(scriptURL, params) {
-    var xmlHttp=false;
-       try {
-         // Firefox, Opera 8.0+, Safari
-         xmlHttp=new XMLHttpRequest();
-       }
-       catch (e) {
-         // Internet Explorer
-         try {
-           xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
-         }
-         catch (e) {
-           try {
-             xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
-           }
-           catch (e) {
-             alert("Your browser does not support AJAX!");
-             return false;
-           }
-         }
-       }
-
-    // e.g. scriptURL: /greenstone/cgi-bin/metadata-server.pl
-    xmlHttp.open('POST', scriptURL, false); // false means synchronous
-    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
-    
-    if(un_ != null) {
-	params += "&un=" + un_;
-    }
-    if(ky_ != null) {
-	params += "&ky=" + ky_;
-    }
-
-    xmlHttp.send(params); // needs to be escaped/encoded
-
-    //alert(scriptURL + "?" + params);
-    //alert(xmlHttp.responseText); // if synchronous, process xmlHttp.responseText AFTER send() call
-    return xmlHttp.responseText;
-}
+	var xmlHttp=false;
+	try {
+            // Firefox, Opera 8.0+, Safari
+            xmlHttp=new XMLHttpRequest();
+	}
+	catch (e) {
+            // Internet Explorer
+            try {
+		xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
+            }
+            catch (e) {
+		try {
+		    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
+		}
+		catch (e) {
+		    alert("Your browser does not support AJAX!");
+		    return false;
+		}
+            }
+	}
+
+	// e.g. scriptURL: /greenstone/cgi-bin/metadata-server.pl
+	xmlHttp.open('POST', scriptURL, false); // false means synchronous
+	xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+	
+	if(un_ != null) {
+	    params += "&un=" + un_;
+	}
+	if(ky_ != null) {
+	    params += "&ky=" + ky_;
+	}
+	
+	xmlHttp.send(params); // needs to be escaped/encoded
+	
+	//alert(scriptURL + "?" + params);
+	//alert(xmlHttp.responseText); // if synchronous, process xmlHttp.responseText AFTER send() call
+	return xmlHttp.responseText;
+    }
 
     // New, an Ajax Asynchronous Post method.
     // For helpful links, see the urlPostSync() method above
     this.urlPostAsync = function(scriptURL, params, callback) {
-    var xmlHttp=false;
-       try {
-         // Firefox, Opera 8.0+, Safari
-         xmlHttp=new XMLHttpRequest();
-       }
-       catch (e) {
-         // Internet Explorer
-         try {
-           xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
-         }
-         catch (e) {
-           try {
-             xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
-           }
-           catch (e) {
-             alert("Your browser does not support AJAX!");
-             return false;
-           }
-         }
-       }
-
-
-
-    // e.g. scriptURL: /greenstone/cgi-bin/metadata-server.pl
-    xmlHttp.open('POST', scriptURL, true); // true means asynchronous
-    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
-
-
-    // If asynchronous:
-    // If the callback param is a function, we will set it up to get called when 
-    // the async post has finished (is ready)
-    // if the callback parameter isn't a function, the param represents a field 
-    // that we want to dynamically update when the async post process has finished
-
+	var xmlHttp=false;
+	try {
+            // Firefox, Opera 8.0+, Safari
+            xmlHttp=new XMLHttpRequest();
+	}
+	catch (e) {
+            // Internet Explorer
+            try {
+		xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
+            }
+            catch (e) {
+		try {
+		    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
+		}
+		catch (e) {
+		    alert("Your browser does not support AJAX!");
+		    return false;
+		}
+            }
+	}
+	
+	
+	
+	// e.g. scriptURL: /greenstone/cgi-bin/metadata-server.pl
+	xmlHttp.open('POST', scriptURL, true); // true means asynchronous
+	xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+	
+	
+	// If asynchronous:
+	// If the callback param is a function, we will set it up to get called when 
+	// the async post has finished (is ready)
+	// if the callback parameter isn't a function, the param represents a field 
+	// that we want to dynamically update when the async post process has finished
+	
 	var typeof_callback = typeof(callback);
 	if ((typeof_callback == "string") || (typeof_callback == "number") || (typeof_callback == "boolean")) {
 	    var locid = callback;
-
+	    
 	    xmlHttp.onreadystatechange=function() {
 		if(xmlHttp.readyState==4) {
@@ -267,17 +267,17 @@
 	    alert("Unrecognized type of callback value: " + typeof_callback);
 	}
-    
-    if(un_ != null) {
-	params += "&un=" + un_;
-    }
-    if(ky_ != null) {
-	params += "&ky=" + ky_;
-    }
-    //alert("Posting Async: " + scriptURL + "?" + params);
-
-    xmlHttp.send(params); // needs to be escaped/encoded
-    // if synchronous, would process xmlHttp AFTER send() call, such as by
-    // accessing xmlHttp.responseText to return that to the caller at this point.
-}
+	
+	if(un_ != null) {
+	    params += "&un=" + un_;
+	}
+	if(ky_ != null) {
+	    params += "&ky=" + ky_;
+	}
+	//alert("Posting Async: " + scriptURL + "?" + params);
+	
+	xmlHttp.send(params); // needs to be escaped/encoded
+	// if synchronous, would process xmlHttp AFTER send() call, such as by
+	// accessing xmlHttp.responseText to return that to the caller at this point.
+    }
 
     // New
Index: main/trunk/greenstone3/web/interfaces/default/js/javascript-global-functions.js
===================================================================
--- main/trunk/greenstone3/web/interfaces/default/js/javascript-global-functions.js	(revision 31541)
+++ main/trunk/greenstone3/web/interfaces/default/js/javascript-global-functions.js	(revision 31542)
@@ -424,5 +424,5 @@
 // No function overloading in JavaScript. Can pass a custom object, however, see
 // http://stackoverflow.com/questions/456177/function-overloading-in-javascript-best-practices
-function callMetadataServer(callingFunction, url, responseFunction, opts)
+function callMetadataServerGET(callingFunction, url, responseFunction, opts)
 {
     var async_setting = true; // Internal processing of 'read' operations (get meta) is not order dependent
@@ -457,5 +457,5 @@
 	.success(function(response)
 	{
-		console.log("(" + callingFunction + ") Response received from server: " + response);
+		console.log("(" + callingFunction + ") Response received from server: " + ajaxResponse);
 
 	    ajaxResponse = response;
@@ -480,4 +480,62 @@
     return ajaxResponse;
 }
+
+
+// No function overloading in JavaScript. Can pass a custom object, however, see
+// http://stackoverflow.com/questions/456177/function-overloading-in-javascript-best-practices
+function callMetadataServer(callingFunction, url, responseFunction, opts)
+{
+    var async_setting = true; // Internal processing of 'read' operations (get meta) is not order dependent
+
+    // If doing set- or remove- (not get-) metadata, then rewrite URLs to call GS2Construct's ModfiyMetadata service instead (which will ensure this only works when authenticated). 
+    // From:
+    // <gs3server>/cgi-bin/metadata-server.pl?a=set-archives-metadata&c=smallcol&site=localsite&d=HASH01454f31011f6b6b26eaf8d7&metaname=Title&metavalue=Moo&prevmetavalue=Blabla&metamode=override
+    // To:
+    // <gs3server>/library?a=g&rt=r&ro=1&s=ModifyMetadata&s1.a=set-archives-metadata&s1.collection=smallcol&s1.site=localsite&s1.d=HASH01454f31011f6b6b26eaf8d7&s1.metaname=Title&s1.metavalue=Moo&s1.prevmetavalue=Blabla&s1.metamode=override
+
+    // if we're doing a set- or remove- metadata operations, then we'll be changing the URL to make sure we go through GS3's authentication
+    if(url.indexOf("set-") != -1 || url.indexOf("remove-") != -1) {
+	
+	url = url.replace("&c=",  "&collection="); // c is a special param name for GS2Construct
+	url = url.replace(/(&|\?)([^=]*=)/g, "$1"+"s1.$2"); // prefix param names with "s1."
+	url = url.replace("cgi-bin/metadata-server.pl?",  gs.xsltParams.library_name + "?a=g&rt=r&ro=1&s=ModifyMetadata&");
+	
+	//console.log("@@@@@ URL is " + url);
+
+	async_setting = false; // for 'write' operations (set/remove meta), we force sequential processing of the internal operation.
+
+    } // otherwise, such as for get- metadata operation, we proceed as before, which will not require authentication
+
+    if (opts != null) {
+	if(opts["forceSync"] != null) {
+	    async_setting = (!opts["forceSync"]);
+	}
+    }
+
+    console.log("Away to call: " + url);
+    var ajaxResponse = "No response received yet, async ajax request";
+
+    var splitURL = url.split("?");
+    url = splitURL[0];
+    var params = splitURL[1];
+    var gsapi = new GSAjaxAPI(url);
+
+    // ajax calls default to using method GET, we want to do POST operations for get-meta and set-meta requests
+    // since get-meta-array and especially set-meta-array can be large, e.g. for user comments.
+
+    if(async_setting) {
+	gsapi.urlPostAsync(url, params, responseFunction);
+    } else {
+	ajaxResponse = gsapi.urlPostSync(url, params);	
+    }
+
+    console.log("(" + callingFunction + ") Response received from server: " + ajaxResponse);
+
+    console.log("Finished ajax call to: " + url);
+    
+    console.log("Got response: " + ajaxResponse);
+    return ajaxResponse;
+}
+
 
 /*************************
Index: main/trunk/greenstone3/web/interfaces/default/transform/layouts/usercomments.xsl
===================================================================
--- main/trunk/greenstone3/web/interfaces/default/transform/layouts/usercomments.xsl	(revision 31541)
+++ main/trunk/greenstone3/web/interfaces/default/transform/layouts/usercomments.xsl	(revision 31542)
@@ -21,4 +21,5 @@
 
   <!-- 2. Load the javascript, which will do stuff on window load/ready for which it needs the above gs.variables -->
+  <script type="text/javascript" src="interfaces/{$interface_name}/js/gsajaxapi.js"><xsl:text> </xsl:text></script>
   <script type="text/javascript" src="interfaces/{$interface_name}/js/user_comments.js"><xsl:text> </xsl:text></script>
 
