Index: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/Authentication.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/Authentication.java	(revision 32368)
+++ main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/Authentication.java	(revision 32369)
@@ -11,6 +11,17 @@
 import java.util.regex.Pattern;
 
-import net.tanesha.recaptcha.ReCaptchaImpl;
-import net.tanesha.recaptcha.ReCaptchaResponse;
+// for verifying recaptcha
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.net.URL;
+import javax.net.ssl.HttpsURLConnection;
+// https://developer.android.com/reference/org/json/JSONObject.html
+// https://developer.android.com/reference/org/json/JSONArray.html
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
 
 import org.apache.commons.codec.digest.DigestUtils;
@@ -36,10 +47,9 @@
 	//Error codes
 	protected static final int NO_ERROR = 0;
-	protected static final int ERROR_REQUEST_HAS_NO_PARAM_LIST = -1;
 	protected static final int ERROR_NOT_LOGGED_IN = -2;
 	protected static final int ERROR_ADMIN_NOT_LOGGED_IN = -3;
 	protected static final int ERROR_COULD_NOT_GET_USER_INFO = -4;
 	protected static final int ERROR_USERNAME_NOT_SPECIFIED = -5;
-	protected static final int ERROR_REQUESTED_USER_NOT_FOUND = -6;
+	protected static final int ERROR_USER_NOT_FOUND = -6;
 	protected static final int ERROR_SQL_EXCEPTION = -7;
 	protected static final int ERROR_INVALID_USERNAME = -8;
@@ -52,34 +62,34 @@
 	protected static final int ERROR_ADDING_USER = -15;
 	protected static final int ERROR_REMOVING_USER = -16;
-	protected static final int ERROR_CAPTCHA_DOES_NOT_MATCH = -17;
+	protected static final int ERROR_CAPTCHA_FAILED = -17;
 	protected static final int ERROR_CAPTCHA_MISSING = -18;
 	protected static final int ERROR_NOT_AUTHORISED = -19;
-
-	protected static final HashMap<Integer, String> _errorMessageMap;
+  	protected static final int ERROR_MISSING_PARAMS = -20;
+  
+	protected static final HashMap<Integer, String> _errorKeyMap;
 	static
 	{
-		//Corresponding error messages
-		HashMap<Integer, String> errorMessageMap = new HashMap<Integer, String>();
-		errorMessageMap.put(ERROR_REQUEST_HAS_NO_PARAM_LIST, "The list of parameters for this request was empty.");
-		errorMessageMap.put(ERROR_NOT_LOGGED_IN, "You must be logged in to access this page.");
-		errorMessageMap.put(ERROR_ADMIN_NOT_LOGGED_IN, "You must be logged in as an administrator to access this page.");
-		errorMessageMap.put(ERROR_COULD_NOT_GET_USER_INFO, "There was a error getting the user information.");
-		errorMessageMap.put(ERROR_USERNAME_NOT_SPECIFIED, "No username was specified.");
-		errorMessageMap.put(ERROR_REQUESTED_USER_NOT_FOUND, "The requested user was not found in the database.");
-		errorMessageMap.put(ERROR_SQL_EXCEPTION, "There was an SQL exception while accessing the database.");
-		errorMessageMap.put(ERROR_INVALID_USERNAME, "The username specified was invalid.");
-		errorMessageMap.put(ERROR_PASSWORD_NOT_ENTERED, "No password was entered.");
-		errorMessageMap.put(ERROR_PASSWORD_TOO_SHORT, "The password you entered was too short (minimum of 3 characters).");
-		errorMessageMap.put(ERROR_PASSWORD_TOO_LONG, "The password you entered was too long (maximum of 64 characters).");
-		errorMessageMap.put(ERROR_PASSWORD_USES_ILLEGAL_CHARACTERS, "The password you entered contains illegal characters.");
-		errorMessageMap.put(ERROR_INCORRECT_PASSWORD, "The password specified was incorrect.");
-		errorMessageMap.put(ERROR_USER_ALREADY_EXISTS, "This user already exists and therefore cannot be added.");
-		errorMessageMap.put(ERROR_ADDING_USER, "There was an error adding this user to the database.");
-		errorMessageMap.put(ERROR_REMOVING_USER, "There was an error removing this user from the database.");
-		errorMessageMap.put(ERROR_CAPTCHA_DOES_NOT_MATCH, "The words you entered did not match the image, please try again.");
-		errorMessageMap.put(ERROR_CAPTCHA_MISSING, "The information from the captcha is missing.");
-		errorMessageMap.put(ERROR_NOT_AUTHORISED, "You are not authorised to access this page.");
-
-		_errorMessageMap = errorMessageMap;
+		//Corresponding error message keys for looking up in ServiceRack dictionary
+		HashMap<Integer, String> errorKeyMap = new HashMap<Integer, String>();
+		errorKeyMap.put(ERROR_NOT_LOGGED_IN, "auth.error.not_logged_in");
+		errorKeyMap.put(ERROR_ADMIN_NOT_LOGGED_IN, "auth.error.admin_not_logged_in");
+		errorKeyMap.put(ERROR_COULD_NOT_GET_USER_INFO, "auth.error.could_not_get_user_info");
+		errorKeyMap.put(ERROR_USERNAME_NOT_SPECIFIED, "auth.error.username_not_specified");
+		errorKeyMap.put(ERROR_USER_NOT_FOUND, "auth.error.user_not_found");
+		errorKeyMap.put(ERROR_SQL_EXCEPTION, "auth.error.sql_exception");
+		errorKeyMap.put(ERROR_INVALID_USERNAME, "auth.error.invalid_username");
+		errorKeyMap.put(ERROR_PASSWORD_NOT_ENTERED, "auth.error.no_password");
+		errorKeyMap.put(ERROR_PASSWORD_TOO_SHORT, "auth.error.password_too_short");
+		errorKeyMap.put(ERROR_PASSWORD_TOO_LONG, "auth.error.password_too_long");
+		errorKeyMap.put(ERROR_PASSWORD_USES_ILLEGAL_CHARACTERS, "auth.error.password_illegal_chars");
+		errorKeyMap.put(ERROR_INCORRECT_PASSWORD, "auth.error.incorrect_password");
+		errorKeyMap.put(ERROR_USER_ALREADY_EXISTS, "auth.error.user_already_exists");
+		errorKeyMap.put(ERROR_ADDING_USER, "auth.error.add_user_error");
+		errorKeyMap.put(ERROR_REMOVING_USER, "auth.error.remove_user_error");
+		errorKeyMap.put(ERROR_CAPTCHA_FAILED, "auth.error.captcha_failed");
+		errorKeyMap.put(ERROR_CAPTCHA_MISSING, "auth.error.captcha_missing");
+		errorKeyMap.put(ERROR_NOT_AUTHORISED, "auth.error.not_authorised");
+		errorKeyMap.put(ERROR_MISSING_PARAMS, "auth.error.missing_params"); // ???
+		_errorKeyMap = errorKeyMap;
 	}
 
@@ -123,8 +133,8 @@
 
 	//Other operations
-	protected static final String REGISTER = "Register";
-	protected static final String PERFORM_REGISTER = "PerformRegister";
+  protected static final String REGISTER = "Register"; // displays the register page
+  protected static final String PERFORM_REGISTER = "PerformRegister"; // performs the registration action
 	protected static final String LOGIN = "Login";
-
+  protected static final String BLANK = "Info"; // a dummy page just for showing an error message
 	//the services on offer
 	protected static final String AUTHENTICATION_SERVICE = "Authentication";
@@ -135,6 +145,6 @@
 	protected static boolean _derbyWrapperDoneForcedShutdown = false;
 
-	protected String _recaptchaPrivateKey = null;
-	protected String _recaptchaPublicKey = null;
+	protected String _recaptchaSiteKey = null;
+	protected String _recaptchaSecretKey = null;
 
 	/** constructor */
@@ -198,16 +208,16 @@
 		{
 			Element currentElem = (Element) recaptchaElems.item(i);
-			if (currentElem.getAttribute(GSXML.NAME_ATT) != null && currentElem.getAttribute(GSXML.NAME_ATT).equals("public_key"))
+			if (currentElem.getAttribute(GSXML.NAME_ATT) != null && currentElem.getAttribute(GSXML.NAME_ATT).equals("site_key"))
 			{
 				if (currentElem.getAttribute(GSXML.VALUE_ATT) != null)
 				{
-					_recaptchaPublicKey = currentElem.getAttribute(GSXML.VALUE_ATT);
-				}
-			}
-			else if (currentElem.getAttribute(GSXML.NAME_ATT) != null && currentElem.getAttribute(GSXML.NAME_ATT).equals("private_key"))
+					_recaptchaSiteKey = currentElem.getAttribute(GSXML.VALUE_ATT);
+				}
+			}
+			else if (currentElem.getAttribute(GSXML.NAME_ATT) != null && currentElem.getAttribute(GSXML.NAME_ATT).equals("secret_key"))
 			{
 				if (currentElem.getAttribute(GSXML.VALUE_ATT) != null)
 				{
-					_recaptchaPrivateKey = currentElem.getAttribute(GSXML.VALUE_ATT);
+					_recaptchaSecretKey = currentElem.getAttribute(GSXML.VALUE_ATT);
 				}
 			}
@@ -269,5 +279,8 @@
 		return getTextString(service_id + ".description", lang);
 	}
-
+  	protected String getErrorTextString(int error_code, String lang) {
+	  return getTextString(_errorKeyMap.get(error_code), lang);
+	  
+	}
 	protected Element processChangeUserEditMode(Element request)
 	{
@@ -282,6 +295,6 @@
 		if (paramList == null)
 		{
-			GSXML.addError(result, _errorMessageMap.get(ERROR_REQUEST_HAS_NO_PARAM_LIST));
-			return result;
+		  logger.error("ChangeUserEditMode request has no param list!!");
+		  return result;
 		}
 
@@ -384,9 +397,10 @@
 		result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
 
+		String lang = request.getAttribute(GSXML.LANG_ATT);
 		Element paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
 		if (paramList == null)
 		{
-			GSXML.addError(result, _errorMessageMap.get(ERROR_REQUEST_HAS_NO_PARAM_LIST));
-			return result;
+		  logger.error("GetUserInformation request has no param list");
+		  return result;
 		}
 
@@ -397,5 +411,5 @@
 		if (username == null)
 		{
-			GSXML.addError(result, _errorMessageMap.get(ERROR_USERNAME_NOT_SPECIFIED));
+			GSXML.addError(result, getErrorTextString(ERROR_USERNAME_NOT_SPECIFIED, lang));
 			return result;
 		}
@@ -410,5 +424,5 @@
 		if (terms.size() == 0)
 		{
-			GSXML.addError(result, _errorMessageMap.get(ERROR_REQUESTED_USER_NOT_FOUND));
+			GSXML.addError(result, getErrorTextString(ERROR_USER_NOT_FOUND, lang));
 			return result;
 		}
@@ -461,9 +475,10 @@
 
 		// Get the parameters of the request
+		String lang = request.getAttribute(GSXML.LANG_ATT);
 		Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
 		if (param_list == null)
 		{
 			serviceNode.setAttribute("operation", LOGIN);
-			GSXML.addError(result, _errorMessageMap.get(ERROR_REQUEST_HAS_NO_PARAM_LIST));
+			logger.error("Authentication request has no param list");
 			return result; // Return the empty result
 		}
@@ -476,11 +491,4 @@
 
 		Element userInformation = (Element) GSXML.getChildByTagName(request, GSXML.USER_INFORMATION_ELEM);
-		if (userInformation == null && _userOpList.contains(op))
-		{
-			serviceNode.setAttribute("operation", LOGIN);
-			GSXML.addError(result, _errorMessageMap.get(ERROR_NOT_LOGGED_IN));
-			return result;
-		}
-
 		if (userInformation != null)
 		{
@@ -489,8 +497,9 @@
 		}
 
-		if (username == null && _userOpList.contains(op))
-		{
+		if ((userInformation == null || username == null) && _userOpList.contains(op))
+		{
+		  // its an operation that requires the user to be logged on - direct them to login page
 			serviceNode.setAttribute("operation", LOGIN);
-			GSXML.addError(result, _errorMessageMap.get(ERROR_NOT_LOGGED_IN));
+			GSXML.addError(result, getErrorTextString(ERROR_NOT_LOGGED_IN, lang));
 			return result;
 		}
@@ -498,6 +507,7 @@
 		if (_adminOpList.contains(op) && (groups == null || !groups.matches(".*\\badministrator\\b.*")))
 		{
+		  // actually, the user needs to be an admin user and they are not
 			serviceNode.setAttribute("operation", LOGIN);
-			GSXML.addError(result, _errorMessageMap.get(ERROR_ADMIN_NOT_LOGGED_IN));
+			GSXML.addError(result, getErrorTextString(ERROR_ADMIN_NOT_LOGGED_IN, lang));
 			return result;
 		}
@@ -505,11 +515,15 @@
 		if (op.equals(LIST_USERS))
 		{
-			int error = addUserInformationToNode(null, serviceNode);
-			if (error != NO_ERROR)
-			{
-				GSXML.addError(result, _errorMessageMap.get(error));
-			}
-		}
-		else if (op.equals(PERFORM_ADD))
+		  int error = addUserInformationToNode(null, serviceNode);
+		  if (error != NO_ERROR)
+		    {
+		      serviceNode.setAttribute("operation", BLANK);
+		      GSXML.addError(result, getErrorTextString(error, lang));
+		    }
+		  return result;
+		  
+		}
+		
+		if (op.equals(PERFORM_ADD))
 		{
 			String newUsername = (String) paramMap.get("username");
@@ -524,5 +538,5 @@
 			if ((error = checkUsername(newUsername)) != NO_ERROR)
 			{
-				GSXML.addError(result, _errorMessageMap.get(error));
+				GSXML.addError(result, getErrorTextString(error, lang));
 				return result;
 			}
@@ -531,5 +545,5 @@
 			if ((error = checkPassword(newPassword)) != NO_ERROR)
 			{
-				GSXML.addError(result, _errorMessageMap.get(error));
+				GSXML.addError(result, getErrorTextString(error, lang));
 				return result;
 			}
@@ -541,5 +555,5 @@
 			{
 				serviceNode.setAttribute("operation", ADD_USER);
-				GSXML.addError(result, _errorMessageMap.get(error));
+				GSXML.addError(result, getErrorTextString(error, lang));
 			}
 			else
@@ -548,6 +562,8 @@
 				serviceNode.setAttribute("operation", LIST_USERS);
 			}
-		}
-		else if (op.equals(PERFORM_REGISTER))
+			return result;
+		}
+		
+		if (op.equals(PERFORM_REGISTER))
 		{
 			String newUsername = (String) paramMap.get("username");
@@ -559,5 +575,5 @@
 			if ((error = checkUsername(newUsername)) != NO_ERROR)
 			{
-				GSXML.addError(result, _errorMessageMap.get(error));
+				GSXML.addError(result, getErrorTextString(error, lang));
 				return result;
 			}
@@ -566,5 +582,5 @@
 			if ((error = checkPassword(newPassword)) != NO_ERROR)
 			{
-				GSXML.addError(result, _errorMessageMap.get(error));
+				GSXML.addError(result, getErrorTextString(error, lang));
 				return result;
 			}
@@ -572,38 +588,14 @@
 			newPassword = hashPassword(newPassword);
 
-			if (_recaptchaPrivateKey != null && _recaptchaPrivateKey.length() > 0)
-			{
-				ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
-				reCaptcha.setPrivateKey(_recaptchaPrivateKey);
-
-				try
-				{
-					//If this line throws an exception then we'll assume the user has a firewall that is too restrictive
-					//(or that they're not connected to the Internet) to allow access to google services.
-					//In this situation we won't use the recaptcha test.
-					reCaptcha.checkAnswer(request.getAttribute("remoteAddress"), "", "");
-
-					String challenge = (String) paramMap.get("recaptcha_challenge_field");
-					String uResponse = (String) paramMap.get("recaptcha_response_field");
-
-					if (challenge == null || uResponse == null)
-					{
-						serviceNode.setAttribute("operation", REGISTER);
-						GSXML.addError(result, _errorMessageMap.get(ERROR_CAPTCHA_MISSING));
-						return result;
-					}
-
-					ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(request.getAttribute("remoteAddress"), challenge, uResponse);
-
-					if (!reCaptchaResponse.isValid())
-					{
-						serviceNode.setAttribute("operation", REGISTER);
-						GSXML.addError(result, _errorMessageMap.get(ERROR_CAPTCHA_DOES_NOT_MATCH));
-						return result;
-					}
-				}
-				catch (Exception ex)
-				{
-				}
+			// check the recaptcha
+			if (_recaptchaSiteKey != null && _recaptchaSecretKey.length() > 0) {
+
+			  String user_response = (String) paramMap.get("g-recaptcha-response");
+			  int recaptcha_error = verifyRecaptcha(_recaptchaSecretKey, user_response);
+			  if (recaptcha_error != NO_ERROR) {
+			    serviceNode.setAttribute("operation", REGISTER);
+			    GSXML.addError(result, getErrorTextString(recaptcha_error, lang));
+			    return result;
+			  }
 			}
 
@@ -612,7 +604,9 @@
 			{
 				serviceNode.setAttribute("operation", REGISTER);
-				GSXML.addError(result, _errorMessageMap.get(error));
-			}
-		}
+				GSXML.addError(result, getErrorTextString(error, lang));
+			}
+			return result;
+		}
+		
 		else if (op.equals(PERFORM_EDIT))
 		{
@@ -629,5 +623,5 @@
 			if ((error = checkUsername(newUsername)) != NO_ERROR)
 			{
-				GSXML.addError(result, _errorMessageMap.get(error));
+				GSXML.addError(result, getErrorTextString(error, lang));
 				return result;
 			}
@@ -642,5 +636,5 @@
 				if ((error = checkPassword(newPassword)) != NO_ERROR)
 				{
-					GSXML.addError(result, _errorMessageMap.get(error));
+					GSXML.addError(result, getErrorTextString(error, lang));
 					return result;
 				}
@@ -660,5 +654,5 @@
 				{
 					serviceNode.setAttribute("operation", EDIT_USER);
-					GSXML.addError(result, _errorMessageMap.get(error));
+					GSXML.addError(result, getErrorTextString(error, lang));
 				}
 				return result;
@@ -669,5 +663,5 @@
 			{
 				serviceNode.setAttribute("operation", EDIT_USER);
-				GSXML.addError(result, _errorMessageMap.get(error));
+				GSXML.addError(result, getErrorTextString(error, lang));
 			}
 			else
@@ -677,4 +671,5 @@
 			}
 		}
+		// this operation is done by a user when editing their own details. Should not return userNode info.
 		else if (op.equals(PERFORM_ACCOUNT_EDIT))
 		{
@@ -690,5 +685,5 @@
 				addUserInformationToNode(previousUsername, serviceNode);
 				serviceNode.setAttribute("operation", ACCOUNT_SETTINGS);
-				GSXML.addError(result, _errorMessageMap.get(ERROR_USER_ALREADY_EXISTS));
+				GSXML.addError(result, getErrorTextString(ERROR_USER_ALREADY_EXISTS, lang));
 				return result;
 			}
@@ -704,5 +699,5 @@
 					addUserInformationToNode(previousUsername, serviceNode);
 					serviceNode.setAttribute("operation", ACCOUNT_SETTINGS);
-					GSXML.addError(result, _errorMessageMap.get(ERROR_INCORRECT_PASSWORD), "Incorrect Password");
+					GSXML.addError(result, getErrorTextString(ERROR_INCORRECT_PASSWORD, lang), "INCORRECT_PASSWORD");
 					return result;
 				}
@@ -712,5 +707,7 @@
 				if ((error = checkPassword(newPassword)) != NO_ERROR)
 				{
-					GSXML.addError(result, _errorMessageMap.get(error));
+				  addUserInformationToNode(previousUsername, serviceNode);
+				  serviceNode.setAttribute("operation", ACCOUNT_SETTINGS);
+					GSXML.addError(result, getErrorTextString(error, lang));
 					return result;
 				}
@@ -727,5 +724,7 @@
 			if ((error = checkUsername(newUsername)) != NO_ERROR)
 			{
-				GSXML.addError(result, _errorMessageMap.get(error));
+			  addUserInformationToNode(previousUsername, serviceNode);
+				  serviceNode.setAttribute("operation", ACCOUNT_SETTINGS);
+				GSXML.addError(result, getErrorTextString(error, lang));
 				return result;
 			}
@@ -738,16 +737,8 @@
 			if (error != NO_ERROR)
 			{
-				if (error == ERROR_USERNAME_NOT_SPECIFIED)
-				{
-					addUserInformationToNode(null, serviceNode);
-					serviceNode.setAttribute("operation", LIST_USERS);
-				}
-				else
-				{
-					addUserInformationToNode(previousUsername, serviceNode);
-					serviceNode.setAttribute("operation", ACCOUNT_SETTINGS);
-					GSXML.addError(result, _errorMessageMap.get(error));
-				}
-				return result;
+			  addUserInformationToNode(previousUsername, serviceNode);
+			  serviceNode.setAttribute("operation", ACCOUNT_SETTINGS);
+			  GSXML.addError(result, getErrorTextString(error, lang));
+			  return result;
 			}
 
@@ -755,9 +746,12 @@
 			if (error != NO_ERROR)
 			{
-				GSXML.addError(result, _errorMessageMap.get(error));
-			}
-
-			addUserInformationToNode(null, serviceNode);
-			serviceNode.setAttribute("operation", LIST_USERS);
+			  serviceNode.setAttribute("operation", ACCOUNT_SETTINGS);
+				GSXML.addError(result, getErrorTextString(error, lang));
+			}
+
+			addUserInformationToNode(newUsername, serviceNode);
+			serviceNode.setAttribute("operation", ACCOUNT_SETTINGS);
+			GSXML.addError(result, getTextString("auth.success.account_settings", lang));
+			
 		}
 		else if (op.equals(PERFORM_RETRIEVE_PASSWORD))
@@ -773,5 +767,5 @@
 			if (user_name == null || oldPassword == null || newPassword == null)
 			{
-				GSXML.addError(result, _errorMessageMap.get("missing compulsory parameters: username, oldPassword, or newPassword"));
+				GSXML.addError(result, getErrorTextString(ERROR_MISSING_PARAMS, lang));
 				return result;
 			}
@@ -781,5 +775,5 @@
 			{
 				addUserInformationToNode(user_name, serviceNode);
-				GSXML.addError(result, _errorMessageMap.get(ERROR_INCORRECT_PASSWORD), "Incorrect Password");
+				GSXML.addError(result, getErrorTextString(ERROR_INCORRECT_PASSWORD, lang), "INCORRECT_PASSWORD");
 				return result;
 			}
@@ -789,5 +783,5 @@
 			if ((error = checkPassword(newPassword)) != NO_ERROR)
 			{
-				GSXML.addError(result, _errorMessageMap.get(error));
+				GSXML.addError(result, getErrorTextString(error, lang));
 				return result;
 			}
@@ -800,5 +794,5 @@
 			if (info != "succeed")
 			{//see DerbyWrapper.modifyUserInfo
-				GSXML.addError(result, _errorMessageMap.get(info));
+			  GSXML.addError(result, info); 
 				return result;
 			}
@@ -810,5 +804,5 @@
 			if (error != NO_ERROR)
 			{
-				GSXML.addError(result, _errorMessageMap.get(error));
+			  GSXML.addError(result, getErrorTextString(error, lang));
 			}
 		}
@@ -820,5 +814,5 @@
 			{
 				serviceNode.setAttribute("operation", "");
-				GSXML.addError(result, _errorMessageMap.get(ERROR_USERNAME_NOT_SPECIFIED));
+				GSXML.addError(result, getErrorTextString(ERROR_USERNAME_NOT_SPECIFIED, lang));
 				return result;
 			}
@@ -827,5 +821,5 @@
 			{
 				serviceNode.setAttribute("operation", LOGIN);
-				GSXML.addError(result, _errorMessageMap.get(ERROR_NOT_AUTHORISED));
+				GSXML.addError(result, getErrorTextString(ERROR_NOT_AUTHORISED, lang));
 				return result;
 			}
@@ -833,5 +827,5 @@
 			if (error != NO_ERROR)
 			{
-				GSXML.addError(result, _errorMessageMap.get(error));
+			  GSXML.addError(result, getErrorTextString(error, lang));
 			}
 		}
@@ -851,25 +845,4 @@
 		else if (op.equals(REGISTER))
 		{
-			if (_recaptchaPrivateKey != null && _recaptchaPrivateKey.length() > 0)
-			{
-				try
-				{
-					ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
-					reCaptcha.setPrivateKey(_recaptchaPrivateKey);
-					reCaptcha.checkAnswer(request.getAttribute("remoteAddress"), "", "");
-				}
-				catch (Exception ex)
-				{
-					return result;
-				}
-			}
-
-			if (_recaptchaPublicKey != null && _recaptchaPrivateKey != null)
-			{
-				Element recaptchaElem = result_doc.createElement("recaptcha");
-				recaptchaElem.setAttribute("publicKey", _recaptchaPublicKey);
-				recaptchaElem.setAttribute("privateKey", _recaptchaPrivateKey);
-				result.appendChild(recaptchaElem);
-			}
 		}
 		else if (op.equals(PERFORM_DELETE_USER))
@@ -879,5 +852,5 @@
 			if (error != NO_ERROR)
 			{
-				GSXML.addError(result, _errorMessageMap.get(error));
+			  GSXML.addError(result, getErrorTextString(error, lang));
 			}
 			addUserInformationToNode(null, serviceNode);
@@ -933,4 +906,60 @@
 	}
 
+  public int verifyRecaptcha(String secret_key, String user_response) {
+
+    if (user_response == null || user_response.length() == 0) {
+      return ERROR_CAPTCHA_MISSING;
+    }
+
+    try{
+      
+      URL obj = new URL("https://www.google.com/recaptcha/api/siteverify");
+      HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
+
+      // add reuqest header
+      con.setRequestMethod("POST");
+      con.setRequestProperty("User-Agent", "Mozilla/5.0");
+      con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
+
+      String postParams = "secret=" + secret_key + "&response="
+	+ user_response;
+
+      // Send post request
+      con.setDoOutput(true);
+      DataOutputStream wr = new DataOutputStream(con.getOutputStream());
+      wr.writeBytes(postParams);
+      wr.flush();
+      wr.close();
+
+      int responseCode = con.getResponseCode();
+      //System.out.println("\nSending 'POST' request to URL : https://www.google.com/recaptcha/api/siteverify");// + url);
+      //System.out.println("Post parameters : " + postParams);
+      //System.out.println("Response Code : " + responseCode);
+      
+      BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
+      String inputLine;
+      StringBuffer response = new StringBuffer();
+      
+      while ((inputLine = in.readLine()) != null) {
+	response.append(inputLine);
+      }
+      in.close();
+      
+      // print result
+      //System.out.println(response.toString());
+
+      JSONObject json_obj = new JSONObject(response.toString());
+      boolean res = json_obj.getBoolean("success");
+      if (res) {
+	return NO_ERROR;
+      } else {
+	return ERROR_CAPTCHA_FAILED;
+      }
+    }catch(Exception e){
+      e.printStackTrace();
+      return ERROR_CAPTCHA_FAILED;
+    }
+
+  }
 	// This method can also be used for printing out the password in hex (in case
 	// the password used the UTF-8 Charset), or the hex values in any unicode string.
@@ -1164,4 +1193,5 @@
 	}
 
+
 	// main() method - calls hashPassword() on any String argument, printing this to stdout
 	// This main() is invoked by gliserver.pl perl code to encrypt passwords identically to Java code.
