Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/ConnectorServlet.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/ConnectorServlet.java	(revision 2253)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/ConnectorServlet.java	(revision 2292)
@@ -34,5 +34,5 @@
 import net.fckeditor.handlers.ConnectorHandler;
 import net.fckeditor.handlers.ExtensionsHandler;
-import net.fckeditor.handlers.LocaleResolverHandler;
+import net.fckeditor.handlers.LocalizedPropertiesLoader;
 import net.fckeditor.handlers.RequestCycleHandler;
 import net.fckeditor.handlers.ResourceTypeHandler;
@@ -117,20 +117,16 @@
 
 		XmlResponse xr;
-		LocaleResolverHandler lrh = new LocaleResolverHandler(request);
+		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(request);
 
 		if (!RequestCycleHandler.isEnabledForFileBrowsing(request))
-			xr = new XmlResponse(XmlResponse.EN_ERROR, lrh
-					.getString("message.connector.fileBrowsing.disabled"));
+			xr = new XmlResponse(XmlResponse.EN_ERROR, lpl
+					.getFileBrowsingDisabled());
 		else if (!CommandHandler.isValidForGet(commandStr))
-			xr = new XmlResponse(XmlResponse.EN_ERROR, lrh
-					.getString("message.connector.invalid_command_specified"));
+			xr = new XmlResponse(XmlResponse.EN_ERROR, lpl.getInvalidCommand());
 		else if (typeStr != null && !ResourceTypeHandler.isValid(typeStr))
-			xr = new XmlResponse(XmlResponse.EN_ERROR, lrh
-					.getString("message.connector.invalid_type_specified"));
+			xr = new XmlResponse(XmlResponse.EN_ERROR, lpl.getInvalidType());
 		else if (!UtilsFile.isValidPath(currentFolderStr))
-			xr = new XmlResponse(
-					XmlResponse.EN_ERROR,
-					lrh
-							.getString("message.connector.invalid_current_folder_speficied"));
+			xr = new XmlResponse(XmlResponse.EN_ERROR, lpl
+					.getInvalidCurrentFolder());
 		else {
 			CommandHandler command = CommandHandler.getCommand(commandStr);
@@ -218,5 +214,5 @@
 
 		UploadResponse ur;
-		LocaleResolverHandler lrh = new LocaleResolverHandler(request);
+		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(request);
 
 		// if this is a QuickUpload request, 'commandStr' and 'currentFolderStr'
@@ -229,19 +225,14 @@
 		if (!RequestCycleHandler.isEnabledForFileUpload(request))
 			ur = new UploadResponse(UploadResponse.SC_SECURITY_ERROR, null,
-					null, lrh
-							.getString("message.connector.fileUpload.disabled"));
+					null, lpl.getFileBrowsingDisabled());
 		else if (!CommandHandler.isValidForPost(commandStr))
-			ur = new UploadResponse(UploadResponse.SC_ERROR, null, null, lrh
-					.getString("message.connector.invalid_command_specified"));
+			ur = new UploadResponse(UploadResponse.SC_ERROR, null, null, lpl
+					.getInvalidCommand());
 		else if (typeStr != null && !ResourceTypeHandler.isValid(typeStr))
-			ur = new UploadResponse(UploadResponse.SC_ERROR, null, null, lrh
-					.getString("message.connector.invalid_type_specified"));
+			ur = new UploadResponse(UploadResponse.SC_ERROR, null, null, lpl
+					.getInvalidType());
 		else if (!UtilsFile.isValidPath(currentFolderStr))
-			ur = new UploadResponse(
-					UploadResponse.SC_ERROR,
-					null,
-					null,
-					lrh
-							.getString("message.connector.invalid_current_folder_speficied"));
+			ur = new UploadResponse(UploadResponse.SC_ERROR, null, null, lpl
+					.getInvalidCurrentFolder());
 		else {
 			ResourceTypeHandler resourceType = ResourceTypeHandler
@@ -258,10 +249,6 @@
 
 			if (!currentDir.exists())
-				ur = new UploadResponse(
-						UploadResponse.SC_ERROR,
-						null,
-						null,
-						lrh
-								.getString("message.connector.invalid_current_folder_speficied"));
+				ur = new UploadResponse(UploadResponse.SC_ERROR, null, null,
+						lpl.getInvalidCurrentFolder());
 			else {
 
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/LocaleResolverHandler.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/LocaleResolverHandler.java	(revision 2253)
+++ 	(revision )
@@ -1,94 +1,0 @@
-/*
- * FCKeditor - The text editor for Internet - http://www.fckeditor.net
- * Copyright (C) 2003-2008 Frederico Caldeira Knabben
- * 
- * == BEGIN LICENSE ==
- * 
- * Licensed under the terms of any of the following licenses at your
- * choice:
- * 
- *  - GNU General Public License Version 2 or later (the "GPL")
- *    http://www.gnu.org/licenses/gpl.html
- * 
- *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
- *    http://www.gnu.org/licenses/lgpl.html
- * 
- *  - Mozilla Public License Version 1.1 or later (the "MPL")
- *    http://www.mozilla.org/MPL/MPL-1.1.html
- * 
- * == END LICENSE ==
- */
-package net.fckeditor.handlers;
-
-import java.util.ResourceBundle;
-
-import javax.servlet.http.HttpServletRequest;
-
-import net.fckeditor.localization.LocaleResolver;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class wraps to a {@link LocaleResolver} implementation and retrieves
- * localized strings for a given request. This class safely returns default
- * strings if anything fails.
- * 
- * @version $Id$
- * 
- */
-public class LocaleResolverHandler {
-
-	private static Logger logger = LoggerFactory
-			.getLogger(LocaleResolverHandler.class);
-	private static LocaleResolver localeResolver;
-	private ResourceBundle rb;
-
-	static {
-		String className = PropertiesLoader
-				.getProperty("localization.localeResolverImpl");
-
-		try {
-			Class<?> clazz = Class.forName(className);
-			localeResolver = (LocaleResolver) clazz.newInstance();
-			logger.info("LocaleResolver initialized to {}", localeResolver
-					.getClass());
-		} catch (Exception e) {
-			logger.warn("Error while loading LocaleResolver implementation", e);
-		}
-	}
-
-	/**
-	 * Constructor which resolves the current user's locale.
-	 * 
-	 * @param request
-	 *            The current request instance.
-	 */
-	public LocaleResolverHandler(HttpServletRequest request) {
-		try {
-			rb = ResourceBundle.getBundle("fckeditor", localeResolver
-					.resolveLocale(request), Thread.currentThread()
-					.getContextClassLoader());
-		} catch (Exception e) {
-			rb = null;
-		}
-	}
-
-	/**
-	 * Retrieves a string for a given key.
-	 * 
-	 * @param key
-	 *            Given key.
-	 * @return Localized string or default string.
-	 */
-	public String getString(String key) {
-
-		try {
-			return rb.getString(key);
-		} catch (Exception e) {
-			return PropertiesLoader.getProperty(key);
-		}
-
-	}
-
-}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/LocalizedPropertiesLoader.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/LocalizedPropertiesLoader.java	(revision 2292)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/LocalizedPropertiesLoader.java	(revision 2292)
@@ -0,0 +1,179 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.handlers;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ResourceBundle;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.fckeditor.localization.LocaleResolver;
+
+/**
+ * This class wraps to a {@link LocaleResolver} implementation and retrieves
+ * localized strings for a given request. This class safely returns default
+ * strings if anything fails. Loaded strings will be cached on load.
+ * 
+ * @version $Id$
+ * 
+ */
+public class LocalizedPropertiesLoader implements Cloneable {
+
+	private static Map<Locale, LocalizedPropertiesLoader> localizedProps = new HashMap<Locale, LocalizedPropertiesLoader>();
+	private Properties properties;
+	private static LocaleResolver localeResolver;
+	private static final Logger logger = LoggerFactory
+			.getLogger(LocalizedPropertiesLoader.class);
+
+	/**
+	 * This method return an instance of this class for the given locale.
+	 * 
+	 * @param request
+	 *            The current request instance
+	 * @return The LPL instance with localized strings.
+	 */
+	public static LocalizedPropertiesLoader getInstance(
+			HttpServletRequest request) {
+
+		Locale locale;
+
+		if (request == null)
+			locale = Locale.getDefault();
+		else
+			locale = getLocaleResolverInstance().resolveLocale(request);
+
+		if (locale == null)
+			locale = Locale.getDefault();
+
+		LocalizedPropertiesLoader lpl = localizedProps.get(locale);
+		if (lpl == null) {
+			lpl = new LocalizedPropertiesLoader(locale);
+			localizedProps.put(locale, lpl);
+		}
+
+		return (LocalizedPropertiesLoader) lpl.clone();
+
+	}
+
+	private static LocaleResolver getLocaleResolverInstance() {
+
+		if (localeResolver == null) {
+			String className = PropertiesLoader
+					.getProperty("localization.localeResolverImpl");
+
+			try {
+				Class<?> clazz = Class.forName(className);
+				localeResolver = (LocaleResolver) clazz.newInstance();
+				logger.info("LocaleResolver initialized to {}", localeResolver
+						.getClass());
+			} catch (Exception e) {
+				logger.warn(
+						"Error while loading LocaleResolver implementation", e);
+			}
+		}
+
+		return localeResolver;
+	}
+
+	@Override
+	protected Object clone() {
+		LocalizedPropertiesLoader cloned;
+		try {
+			cloned = (LocalizedPropertiesLoader) super.clone();
+		} catch (CloneNotSupportedException e) {
+			throw new RuntimeException(e);
+		}
+		cloned.properties = (Properties) this.properties.clone();
+		return cloned;
+	}
+
+	/**
+	 * Loads the default strings and the string for the given locale.
+	 * 
+	 * @param locale
+	 *            Given locale
+	 */
+	private LocalizedPropertiesLoader(Locale locale) {
+
+		ResourceBundle rb = ResourceBundle.getBundle("fckeditor", locale,
+				Thread.currentThread().getContextClassLoader());
+
+		this.properties = new Properties(PropertiesLoader.getProperties());
+
+		if (rb != null) {
+			Enumeration<String> keys = rb.getKeys();
+
+			while (keys.hasMoreElements()) {
+				String key = keys.nextElement();
+				properties.setProperty(key, rb.getString(key));
+			}
+		}
+
+	}
+
+	private String getString(String key) {
+		return properties.getProperty(key);
+	}
+
+	public String getCompatibleBrowser() {
+		return getString("message.compatible_browser.yes");
+	}
+
+	public String getNotCompatibleBrowser() {
+		return getString("message.compatible_browser.no");
+	}
+
+	public String getFileUploadEnabled() {
+		return getString("message.connector.fileUpload.enabled");
+	}
+
+	public String getFileUploadDisabled() {
+		return getString("message.connector.fileUpload.disabled");
+	}
+
+	public String getFileBrowsingEnabled() {
+		return getString("message.connector.fileBrowsing.enabled");
+	}
+
+	public String getFileBrowsingDisabled() {
+		return getString("message.connector.fileBrowsing.disabled");
+	}
+
+	public String getInvalidCommand() {
+		return getString("message.connector.invalid_command_specified");
+	}
+
+	public String getInvalidType() {
+		return getString("message.connector.invalid_type_specified");
+	}
+
+	public String getInvalidCurrentFolder() {
+		return getString("message.connector.invalid_current_folder_speficied");
+	}
+
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/PropertiesLoader.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/PropertiesLoader.java	(revision 2253)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/PropertiesLoader.java	(revision 2292)
@@ -75,5 +75,5 @@
 		// 2. load user defaults
 		InputStream in2 = PropertiesLoader.class
-				.getResourceAsStream("/fckeditor.properties_");
+				.getResourceAsStream("/fckeditor.properties");
 
 		if (in2 == null) {
@@ -126,3 +126,11 @@
 		properties.setProperty(key, value);
 	}
+	
+	/**
+	 * Retrieve the <em>cloned</em> properties.
+	 * @return The properties in the loader
+	 */
+	public static Properties getProperties() {
+		return (Properties) properties.clone();
+	}
 }
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/tags/CheckTag.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/tags/CheckTag.java	(revision 2253)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/tags/CheckTag.java	(revision 2292)
@@ -31,5 +31,5 @@
 import javax.servlet.jsp.tagext.TagSupport;
 
-import net.fckeditor.handlers.LocaleResolverHandler;
+import net.fckeditor.handlers.LocalizedPropertiesLoader;
 import net.fckeditor.handlers.RequestCycleHandler;
 import net.fckeditor.tool.Compatibility;
@@ -78,25 +78,25 @@
 
 		HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
-		LocaleResolverHandler lrh = new LocaleResolverHandler(request);
+		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(request);
 		String response = null;
 
 		if (command.equals(FILE_UPLOAD)) {
 			if (RequestCycleHandler.isEnabledForFileUpload(request))
-				response = lrh.getString("message.connector.fileUpload.enabled");
+				response = lpl.getFileUploadEnabled();
 			else
-				response = lrh.getString("message.connector.fileUpload.disabled");
+				response = lpl.getFileUploadDisabled();
 		}
 
 		if (command.equals(FILE_BROWSING)) {
 			if (RequestCycleHandler.isEnabledForFileBrowsing(request))
-				response = lrh.getString("message.connector.fileBrowsing.enabled");
+				response = lpl.getFileBrowsingEnabled();
 			else
-				response = lrh.getString("message.connector.fileBrowsing.disabled");
+				response = lpl.getFileBrowsingDisabled();
 		}
 		if (command.equals(COMPATIBLE_BROWSER)) {
 			if (Compatibility.isCompatibleBrowser(request))
-				response = lrh.getString("message.compatible_browser.yes");
+				response = lpl.getCompatibleBrowser();
 			else
-				response = lrh.getString("message.compatible_browser.no");
+				response = lpl.getNotCompatibleBrowser();
 		}
 
