Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/Connector.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/Connector.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/Connector.java	(revision 2584)
@@ -0,0 +1,135 @@
+/*
+ * 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.connector;
+
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+
+import net.fckeditor.connector.exception.FolderAlreadyExistsException;
+import net.fckeditor.connector.exception.InvalidCurrentFolderException;
+import net.fckeditor.connector.exception.InvalidFolderNameException;
+import net.fckeditor.connector.exception.SecurityIssueException;
+import net.fckeditor.connector.exception.UnknownException;
+import net.fckeditor.handlers.ResourceType;
+
+/**
+ * Interface for all Connectors.<br>
+ * The Connector will be initialized by the {@link Dispatcher}. If an error is happened there are well-defined
+ * exceptions which could be thrown. So the {@link Dispatcher} can react according to it.
+ * <br><br>
+ * Keep in mind that the {@link Dispatcher} verifies the request and redirects the relevant parameters
+ * to the different methods of the connector and forwards the response to {@link ConnectorServlet}.
+ * Therefore you don't need to check the basic parameters 'type' and 'currentFolder' against <code>null</code>.
+ * 
+ * @version $Id$
+ */
+public interface Connector {
+	
+	/**
+	 * This key is to address a file's name in {@link #getFiles(ResourceType, String)} map.
+	 */
+	public final static String KEY_NAME  = "name";
+	/**
+	 * This key is to address a file's size in {@link #getFiles(ResourceType, String)} map.
+	 */
+	public final static String KEY_SIZE = "size";
+	
+	/**
+	 * Initializes the connector. This method will be called on the start of the webapp.
+	 * 
+	 * @param servletContext eg. to get the real path of a file for example.
+	 */
+	public void init(final ServletContext servletContext);
+
+	/**
+	 * Returns a list of file attributes. which are inside the abstract path
+	 * <code>/[type-folder]/[currentFolder]</code>.
+	 * Filename, file size (in bytes).
+	 * 
+	 * @param type
+	 * @param currentFolder
+	 * @return A list of folder names.
+	 * @throws InvalidCurrentFolderException
+	 * @throws SecurityIssueException
+	 * @throws UnknownException
+	 */
+	public List<Map<String, Object>> getFiles(final ResourceType type, final String currentFolder)
+		throws InvalidCurrentFolderException, SecurityIssueException, UnknownException;
+	
+	/**
+	 * Returns a list of folders which are inside the abstract path
+	 * <code>/[type-folder]/[currentFolder]</code>.
+	 * 
+	 * @param type
+	 * @param currentFolder
+	 * @return A list of file names.
+	 * @throws InvalidCurrentFolderException
+	 * @throws SecurityIssueException
+	 * @throws UnknownException
+	 */
+	public List<String> getFolders(final ResourceType type, final String currentFolder)
+		throws InvalidCurrentFolderException, SecurityIssueException, UnknownException;
+		
+	/**
+	 * Creates a new folder inside inside the abstract path
+	 * <code>/[type-folder]/[currentFolder]</code>.
+	 * 
+	 * @param type
+	 * @param currentFolder
+	 * @param newFolder Name of the new folder to create.
+	 * @throws InvalidCurrentFolderException
+	 * @throws SecurityIssueException
+	 * @throws InvalidFolderNameException
+	 * @throws FolderAlreadyExistsException
+	 */
+	public void createFolder(final ResourceType type, final String currentFolder, final String newFolder) 
+		throws InvalidCurrentFolderException, SecurityIssueException, InvalidFolderNameException, FolderAlreadyExistsException;
+
+	/**
+	 * Uploads a new file into the abstract path <code>/[type-folder]/[currentFolder]</code>. If there is 
+	 * already a file with the same name, the new one has to renamed.
+	 * 
+	 * @param type
+	 * @param currentFolder
+	 * @param fileName
+	 * @param inputStream Content of the file.
+	 * @return <code>fileName</code> or the name of the renamed file.
+	 * @throws InvalidCurrentFolderException
+	 * @throws SecurityIssueException
+	 */
+	public String fileUpload(final ResourceType type, final String currentFolder, final String fileName, final InputStream inputStream)
+		throws InvalidCurrentFolderException, SecurityIssueException;
+	
+	/**
+	 * Uploads a new file into the top of <code>userFiles</code>. If there is 
+	 * already a file with the same name, the new one has to renamed.
+	 * 
+	 * @param fileName
+	 * @param inputStream Content of the file.
+	 * @return
+	 * @throws SecurityIssueException
+	 */
+	public String quickUpload(final String fileName, final InputStream inputStream) throws SecurityIssueException;
+}
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 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/ConnectorServlet.java	(revision 2584)
@@ -21,8 +21,5 @@
 package net.fckeditor.connector;
 
-import java.io.File;
 import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.List;
 
 import javax.servlet.ServletException;
@@ -31,297 +28,79 @@
 import javax.servlet.http.HttpServletResponse;
 
-import net.fckeditor.handlers.CommandHandler;
-import net.fckeditor.handlers.ConnectorHandler;
-import net.fckeditor.handlers.ExtensionsHandler;
-import net.fckeditor.handlers.LocalizedPropertiesLoader;
-import net.fckeditor.handlers.RequestCycleHandler;
-import net.fckeditor.handlers.ResourceTypeHandler;
-import net.fckeditor.response.UploadResponse;
-import net.fckeditor.response.XmlResponse;
-import net.fckeditor.tool.Utils;
-import net.fckeditor.tool.UtilsFile;
-import net.fckeditor.tool.UtilsResponse;
-
-import org.apache.commons.fileupload.FileItem;
-import org.apache.commons.fileupload.FileItemFactory;
-import org.apache.commons.fileupload.disk.DiskFileItemFactory;
-import org.apache.commons.fileupload.servlet.ServletFileUpload;
-import org.apache.commons.io.FilenameUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import net.fckeditor.requestcycle.ThreadLocalData;
 
 /**
- * Servlet to upload and browse files.<br />
- * 
- * This servlet accepts 4 commands which interact with the server-side
- * filesystem.<br />
- * The allowed commands are:
+ * This is the FCKeditor Connector servlet. It has the following jobs:
  * <ul>
- * <li><code>GetFolders</code>: Retrieves a list of folders in the current
- * folder</li>
- * <li><code>GetFoldersAndFiles</code>: Retrieves a list of files and
- * folders in the current folder</li>
- * <li><code>CreateFolder</code>: Creates a new folder in the current folder</li>
- * <li><code>FileUpload</code>: Stores an uploaded file into the current
- * folder. (must be sent with POST)</li>
- * </ul>
+ * <li>Initialization of the {@link Dispatcher} object.</li>
+ * <li>Calling {@link ThreadLocalData#beginRequest(HttpServletRequest)}
+ * (It is an object that holds request-based objects.)</li>
+ * <li>Forwarding the requests:
+ * 	<ul><li><code>GET</code> to {@link Dispatcher#doGet(HttpServletRequest, HttpServletResponse)} </li>
+ * 		<li><code>POST</code> to {@link Dispatcher#doPost(HttpServletRequest, HttpServletResponse)}.</li>
+ *  </ul></li>
+ * <li>Calling {@link ThreadLocalData#endRequest()} to cleanup all ThreadLocal
+ * objects independent of if an exception was thrown or not. That's very
+ * important to prevent memory-leaks!!!</li>
+ * </ul><br>
+ * Summing up: This workflow guarantees the correct initialization and cleaning
+ * of the {@link ThreadLocalData}, - it's essential because of preventing memory-leaks. 
+ * All requests are dispatched to the {@link Dispatcher}. The {@link Dispatcher} 
+ * forwards the request to an implementation of the {@link Connector}.
  * 
  * @version $Id$
  */
 public class ConnectorServlet extends HttpServlet {
-
 	private static final long serialVersionUID = -5742008970929377161L;
-	private static final Logger logger = LoggerFactory
-			.getLogger(ConnectorServlet.class);
-
+	private Dispatcher dispatcher;
+	
 	/**
-	 * Initialize the servlet: <code>mkdir</code> &lt;DefaultUserFilesPath&gt;
+	 * Initializes the {@link Dispatcher}.
+	 * 
+	 * @see javax.servlet.GenericServlet#init()
 	 */
-	public void init() throws ServletException, IllegalArgumentException {
-		String realDefaultUserFilesPath = getServletContext().getRealPath(
-				ConnectorHandler.getDefaultUserFilesPath());
-
-		File defaultUserFilesDir = new File(realDefaultUserFilesPath);
-		UtilsFile.checkDirAndCreate(defaultUserFilesDir);
-
-		logger.info("ConnectorServlet successfully initialized!");
+	@Override
+	public void init() throws ServletException {
+		dispatcher = new Dispatcher(getServletContext());
+	}
+	
+	/* (non-Javadoc)
+	 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+	 */
+	@Override
+	protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
+			throws ServletException, IOException {
+		try {
+			ThreadLocalData.beginRequest(request);
+			dispatcher.doGet(request, response);
+		} catch (Exception e) {
+			// if an exception wasn't catched by the Dispatcher, it is a fatal one and has to re-thrown.
+			if (e instanceof IOException)
+				throw (IOException) e;
+			else
+				throw new ServletException(e);
+		} finally {
+			ThreadLocalData.endRequest();
+		}		
 	}
 
-	/**
-	 * Manage the <code>GET</code> requests (<code>GetFolders</code>,
-	 * <code>GetFoldersAndFiles</code>, <code>CreateFolder</code>).<br/>
-	 * 
-	 * The servlet accepts commands sent in the following format:<br/>
-	 * <code>connector?Command=&lt;CommandName&gt;&Type=&lt;ResourceType&gt;&CurrentFolder=&lt;FolderPath&gt;</code>
-	 * <p>
-	 * It executes the commands and then returns the result to the client in XML
-	 * format.
-	 * </p>
+	/* (non-Javadoc)
+	 * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
 	 */
-	public void doGet(HttpServletRequest request, HttpServletResponse response)
+	@Override
+	protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
 			throws ServletException, IOException {
-		logger.debug("Entering ConnectorServlet#doGet");
-
-		response.setCharacterEncoding("UTF-8");
-		response.setContentType("application/xml; charset=UTF-8");
-		response.setHeader("Cache-Control", "no-cache");
-		PrintWriter out = response.getWriter();
-
-		String commandStr = request.getParameter("Command");
-		String typeStr = request.getParameter("Type");
-		String currentFolderStr = request.getParameter("CurrentFolder");
-
-		logger.debug("Parameter Command: {}", commandStr);
-		logger.debug("Parameter Type: {}", typeStr);
-		logger.debug("Parameter CurrentFolder: {}", currentFolderStr);
-
-		XmlResponse xr;
-		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(request);
-
-		// FIXME check for isEnabledForFolderCreation
-		if (!RequestCycleHandler.isEnabledForFileBrowsing(request))
-			xr = new XmlResponse(XmlResponse.EN_ERROR, lpl
-					.getFileBrowsingDisabled());
-		else if (!CommandHandler.isValidForGet(commandStr))
-			xr = new XmlResponse(XmlResponse.EN_ERROR, lpl.getInvalidCommand());
-		else if (typeStr != null && !ResourceTypeHandler.isValid(typeStr))
-			xr = new XmlResponse(XmlResponse.EN_ERROR, lpl.getInvalidType());
-		else if (!UtilsFile.isValidPath(currentFolderStr))
-			xr = new XmlResponse(XmlResponse.EN_ERROR, lpl
-					.getInvalidCurrentFolder());
-		else {
-			CommandHandler command = CommandHandler.getCommand(commandStr);
-			ResourceTypeHandler resourceType = ResourceTypeHandler
-					.getDefaultResourceType(typeStr);
-
-			String typePath = UtilsFile.constructServerSidePath(request,
-					resourceType);
-			String typeDirPath = getServletContext().getRealPath(typePath);
-
-			File typeDir = new File(typeDirPath);
-			UtilsFile.checkDirAndCreate(typeDir);
-
-			File currentDir = new File(typeDir, currentFolderStr);
-
-			if (!currentDir.exists())
-				xr = new XmlResponse(XmlResponse.EN_INVALID_FOLDER_NAME);
-			else {
-
-				xr = new XmlResponse(command, resourceType, currentFolderStr,
-						UtilsResponse.constructResponseUrl(request,
-								resourceType, currentFolderStr, ConnectorHandler.isFullUrl()));
-
-				if (command.equals(CommandHandler.GET_FOLDERS))
-					xr.setFolders(currentDir);
-				else if (command.equals(CommandHandler.GET_FOLDERS_AND_FILES))
-					xr.setFoldersAndFiles(currentDir);
-				else if (command.equals(CommandHandler.CREATE_FOLDER)) {
-					String newFolderStr = UtilsFile.sanitizeFolderName(request
-							.getParameter("NewFolderName"));
-					logger.debug("Parameter NewFolderName: {}", newFolderStr);
-
-					File newFolder = new File(currentDir, newFolderStr);
-					int errorNumber = XmlResponse.EN_UKNOWN;
-
-					if (newFolder.exists())
-						errorNumber = XmlResponse.EN_ALREADY_EXISTS;
-					else {
-						try {
-							errorNumber = (newFolder.mkdir()) ? XmlResponse.EN_OK
-									: XmlResponse.EN_INVALID_FOLDER_NAME;
-						} catch (SecurityException e) {
-							errorNumber = XmlResponse.EN_SECURITY_ERROR;
-						}
-					}
-					xr.setError(errorNumber);
-				}
-			}
+		try {
+			ThreadLocalData.beginRequest(request);
+			dispatcher.doPost(request, response);
+		} catch (Exception e) {
+			// if an exception wasn't catched by the Dispatcher, it is a fatal one and has to re-thrown.
+			if (e instanceof IOException)
+				throw new IOException(e.getLocalizedMessage());
+			else
+				throw new ServletException(e);
+		} finally {
+			ThreadLocalData.endRequest();
 		}
-
-		out.print(xr);
-		out.flush();
-		out.close();
-		logger.debug("Exiting ConnectorServlet#doGet");
-	}
-
-	/**
-	 * Manage the <code>POST</code> requests (<code>FileUpload</code>).<br />
-	 * 
-	 * The servlet accepts commands sent in the following format:<br />
-	 * <code>connector?Command=&lt;FileUpload&gt;&Type=&lt;ResourceType&gt;&CurrentFolder=&lt;FolderPath&gt;</code>
-	 * with the file in the <code>POST</code> body.<br />
-	 * <br>
-	 * It stores an uploaded file (renames a file if another exists with the
-	 * same name) and then returns the JavaScript callback.
-	 */
-	@SuppressWarnings("unchecked")
-	public void doPost(HttpServletRequest request, HttpServletResponse response)
-			throws ServletException, IOException {
-		logger.debug("Entering Connector#doPost");
-
-		response.setCharacterEncoding("UTF-8");
-		response.setContentType("text/html; charset=UTF-8");
-		response.setHeader("Cache-Control", "no-cache");
-		PrintWriter out = response.getWriter();
-
-		String commandStr = request.getParameter("Command");
-		String typeStr = request.getParameter("Type");
-		String currentFolderStr = request.getParameter("CurrentFolder");
-
-		logger.debug("Parameter Command: {}", commandStr);
-		logger.debug("Parameter Type: {}", typeStr);
-		logger.debug("Parameter CurrentFolder: {}", currentFolderStr);
-
-		UploadResponse ur;
-		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(request);
-
-		// if this is a QuickUpload request, 'commandStr' and 'currentFolderStr'
-		// are empty
-		if (Utils.isEmpty(commandStr) && Utils.isEmpty(currentFolderStr)) {
-			commandStr = "QuickUpload";
-			currentFolderStr = "/";
-		}
-
-		if (!RequestCycleHandler.isEnabledForFileUpload(request))
-			ur = new UploadResponse(UploadResponse.SC_SECURITY_ERROR, null,
-					null, lpl.getFileBrowsingDisabled());
-		else if (!CommandHandler.isValidForPost(commandStr))
-			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, lpl
-					.getInvalidType());
-		else if (!UtilsFile.isValidPath(currentFolderStr))
-			ur = new UploadResponse(UploadResponse.SC_ERROR, null, null, lpl
-					.getInvalidCurrentFolder());
-		else {
-			ResourceTypeHandler resourceType = ResourceTypeHandler
-					.getDefaultResourceType(typeStr);
-
-			String typePath = UtilsFile.constructServerSidePath(request,
-					resourceType);
-			String typeDirPath = getServletContext().getRealPath(typePath);
-
-			File typeDir = new File(typeDirPath);
-			UtilsFile.checkDirAndCreate(typeDir);
-
-			File currentDir = new File(typeDir, currentFolderStr);
-
-			if (!currentDir.exists())
-				ur = new UploadResponse(UploadResponse.SC_ERROR, null, null,
-						lpl.getInvalidCurrentFolder());
-			else {
-
-				String newFilename = null;
-				FileItemFactory factory = new DiskFileItemFactory();
-				ServletFileUpload upload = new ServletFileUpload(factory);
-
-				try {
-
-					List<FileItem> items = upload.parseRequest(request);
-
-					// We upload only one file at the same time
-					FileItem uplFile = items.get(0);
-					String rawName = UtilsFile.sanitizeFileName(uplFile
-							.getName());
-					String filename = FilenameUtils.getName(rawName);
-					String baseName = FilenameUtils.removeExtension(filename);
-					String extension = FilenameUtils.getExtension(filename);
-
-					if (!ExtensionsHandler.isAllowed(resourceType, extension))
-						ur = new UploadResponse(
-								UploadResponse.SC_INVALID_EXTENSION);
-					else {
-
-						// construct an unique file name
-						File pathToSave = new File(currentDir, filename);
-						int counter = 1;
-						while (pathToSave.exists()) {
-							newFilename = baseName.concat("(").concat(
-									String.valueOf(counter)).concat(")")
-									.concat(".").concat(extension);
-							pathToSave = new File(currentDir, newFilename);
-							counter++;
-						}
-
-						if (Utils.isEmpty(newFilename))
-							ur = new UploadResponse(UploadResponse.SC_OK,
-									UtilsResponse.constructResponseUrl(request,
-											resourceType, currentFolderStr,
-											ConnectorHandler.isFullUrl())
-											.concat(filename));
-						else
-							ur = new UploadResponse(UploadResponse.SC_RENAMED,
-									UtilsResponse.constructResponseUrl(request,
-											resourceType, currentFolderStr,
-											ConnectorHandler.isFullUrl())
-											.concat(newFilename), newFilename);
-
-						// secure image check
-						if (resourceType.equals(ResourceTypeHandler.IMAGE)
-								&& ConnectorHandler.isSecureImageUploads()) {
-							if (UtilsFile.isImage(uplFile.getInputStream()))
-								uplFile.write(pathToSave);
-							else {
-								uplFile.delete();
-								ur = new UploadResponse(
-										UploadResponse.SC_INVALID_EXTENSION);
-							}
-						} else
-							uplFile.write(pathToSave);
-
-					}
-				} catch (Exception e) {
-					ur = new UploadResponse(UploadResponse.SC_SECURITY_ERROR);
-				}
-			}
-
-		}
-
-		out.print(ur);
-		out.flush();
-		out.close();
-
-		logger.debug("Exiting Connector#doPost");
 	}
 
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/Dispatcher.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/Dispatcher.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/Dispatcher.java	(revision 2584)
@@ -0,0 +1,270 @@
+/*
+ * 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.connector;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import net.fckeditor.connector.exception.FolderAlreadyExistsException;
+import net.fckeditor.connector.exception.InvalidCurrentFolderException;
+import net.fckeditor.connector.exception.InvalidFolderNameException;
+import net.fckeditor.connector.exception.SecurityIssueException;
+import net.fckeditor.connector.exception.UnknownException;
+import net.fckeditor.handlers.CommandHandler;
+import net.fckeditor.handlers.ConnectorHandler;
+import net.fckeditor.handlers.ExtensionsHandler;
+import net.fckeditor.handlers.RequestCycleHandler;
+import net.fckeditor.handlers.ResourceType;
+import net.fckeditor.requestcycle.Context;
+import net.fckeditor.requestcycle.ThreadLocalData;
+import net.fckeditor.response.GetResponse;
+import net.fckeditor.response.UploadResponse;
+import net.fckeditor.tool.Utils;
+import net.fckeditor.tool.UtilsFile;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.io.FilenameUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * This class is calling by {@link ConnectorServlet}. It verifies the request parameters 
+ * and forward it to the corresponding {@link Connector} methods. If errors are happened inside these methods,
+ * well defined exceptions from {@link net.fckeditor.connector.exception} will be thrown. These exceptions or the return
+ * values of {@link Connector} methods will be transfered to the HttpServletResponse object.
+ * 
+ * @version $Id$
+ */
+public class Dispatcher {
+	private static final Logger logger = LoggerFactory.getLogger(Dispatcher.class);
+	private Connector connector = null;
+	
+	/**
+	 * Initializes the {@link Connector}.
+	 * 
+	 * @param servletContext
+	 */
+	protected Dispatcher(final ServletContext servletContext) {
+		this.connector = ConnectorHandler.getConnector();
+		this.connector.init(servletContext);
+	}
+	
+	
+	/**
+	 * Manage the <code>GET</code> requests (<code>GetFolders</code>,
+	 * <code>GetFoldersAndFiles</code>, <code>CreateFolder</code>).<br/>
+	 * 
+	 * The method accepts commands sent in the following format:<br/>
+	 * <code>connector?Command=&lt;CommandName&gt;&Type=&lt;ResourceType&gt;&CurrentFolder=&lt;FolderPath&gt;</code>
+	 * <p>
+	 * It executes the relevant commands and then returns the result to the client in XML
+	 * format.
+	 * </p>
+	 */
+	public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
+		logger.debug("Entering Dispatcher#doGet");
+		Context context = ThreadLocalData.getContext();
+
+		response.setCharacterEncoding("UTF-8");
+		response.setContentType("application/xml; charset=UTF-8");
+		response.setHeader("Cache-Control", "no-cache");
+		PrintWriter out = response.getWriter();
+
+		context.logBaseParameters();
+		
+		GetResponse getResponse = null;
+		// check parameters
+		// TODO should we move the parameter check to Context -> throws an exception?
+		if (!CommandHandler.isValidForGet(context.getCommandStr()))
+			getResponse = GetResponse.getErrorInvalidCommand();
+		else if (!ResourceType.isValid(context.getTypeStr()))
+			getResponse = GetResponse.getErrorInvalidType();
+		else if (!UtilsFile.isValidPath(context.getCurrentFolderStr()))
+			getResponse = GetResponse.getErrorInvalidCurrentFolder();
+		else {
+			
+			ResourceType type = context.getDefaultResourceType();
+			CommandHandler command = context.getCommand();
+			
+			// check permissions for user action
+			if ((command.equals(CommandHandler.GET_FOLDERS) || command.equals(CommandHandler.GET_FOLDERS_AND_FILES))
+					&& !RequestCycleHandler.isEnabledForFileBrowsing())
+				getResponse = GetResponse.getErrorFileBrowsingDisabled();
+			else if (command.equals(CommandHandler.CREATE_FOLDER) && !RequestCycleHandler.isEnabledForFolderCreation())
+				getResponse = GetResponse.getErrorFolderCreationDisabled();
+			
+			else {
+				
+				// make the connector calls, catch its exceptions and generate the right response object
+				try {
+					if (command.equals(CommandHandler.CREATE_FOLDER)) {
+						String newFolderStr = UtilsFile.sanitizeFolderName(request.getParameter("NewFolderName"));
+						if (Utils.isEmpty(newFolderStr))
+							getResponse = GetResponse.getErrorInvalidFolderName();
+						else {
+							logger.debug("Parameter NewFolderName: {}", newFolderStr);
+							connector.createFolder(type, context.getCurrentFolderStr(), newFolderStr);
+							getResponse = GetResponse.getOK();
+						}
+					} else if (command.equals(CommandHandler.GET_FOLDERS) || command.equals(CommandHandler.GET_FOLDERS_AND_FILES)) {
+						// TODO I don't like this code, it has to be more generic
+						String responseUrl = context.buildUrl(ConnectorHandler.getUserFilesPath());
+						getResponse = getFoldersAndFiles(command, type, context.getCurrentFolderStr(), responseUrl); 
+					} else 
+						getResponse = GetResponse.getErrorUnknown();
+				} catch (InvalidCurrentFolderException e) {
+					getResponse = GetResponse.getErrorInvalidCurrentFolder();
+				} catch (SecurityIssueException e) {
+					getResponse = GetResponse.getErrorSecurity();
+				} catch (InvalidFolderNameException e) {
+					getResponse = GetResponse.getErrorInvalidFolderName();
+				} catch (FolderAlreadyExistsException e) {
+					getResponse = GetResponse.getErrorFolderAlreadyExists();
+				} catch (Exception e) {
+					getResponse = GetResponse.getErrorUnknown();
+				}
+			}
+		}
+		
+		out.print(getResponse);
+		out.flush();
+		out.close();
+		logger.debug("Exiting Dispatcher#doGet");
+	}
+	
+	/**
+	 * Helper to make the right {@link Connector}-calls for <code>GetFolders</code> and
+	 * <code>GetFoldersAndFiles</code>.
+	 * 
+	 * @param command should be only {@link CommandHandler#GET_FOLDERS} or {@link CommandHandler#GET_FOLDERS_AND_FILES}!!
+	 * @param type
+	 * @param currentFolderStr
+	 * @param responseUrl
+	 * @return
+	 * @throws InvalidCurrentFolderException
+	 * @throws SecurityIssueException
+	 * @throws UnknownException
+	 */
+	private GetResponse getFoldersAndFiles(final CommandHandler command, final ResourceType type, final String currentFolderStr, final String responseUrl)
+			throws InvalidCurrentFolderException, SecurityIssueException, UnknownException {
+		GetResponse getResponse = new GetResponse(command, type, currentFolderStr, responseUrl);
+		getResponse.setFolders(connector.getFolders(type, currentFolderStr));
+		if (command.equals(CommandHandler.GET_FOLDERS_AND_FILES)) 
+			getResponse.setFiles(connector.getFiles(type, currentFolderStr));
+		return getResponse;
+	}
+	
+	/**
+	 * Manage the <code>POST</code> requests (<code>FileUpload</code>).<br />
+	 * 
+	 * The method accepts commands sent in the following format:<br />
+	 * <code>connector?Command=&lt;FileUpload&gt;&Type=&lt;ResourceType&gt;&CurrentFolder=&lt;FolderPath&gt;</code>
+	 * with the file in the <code>POST</code> body.<br />
+	 * <br>
+	 * The Connector stores an uploaded file (renames a file if another exists with the
+	 * same name) and then returns the JavaScript callback.
+	 * @throws IOException 
+	 */
+	public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
+		logger.debug("Entering Dispatcher#doPost");
+		Context context = ThreadLocalData.getContext();
+		
+		response.setCharacterEncoding("UTF-8");
+		response.setContentType("text/html; charset=UTF-8");
+		response.setHeader("Cache-Control", "no-cache");
+		PrintWriter out = response.getWriter();
+
+		context.logBaseParameters();
+		
+		// if this is a QuickUpload request, 'commandStr' and 'currentFolderStr'
+		// are empty
+		boolean isQuickUpload = context.checkQuickUpload();
+		
+		UploadResponse uploadResponse;
+		// check permissions for user actions
+		if (!RequestCycleHandler.isEnabledForFileUpload())
+			uploadResponse = UploadResponse.getErrorFileUploadDisabled();
+
+		// check parameters  
+		// TODO should we move the parameter check to Context -> throws an exception?
+		else if (!CommandHandler.isValidForPost(context.getCommandStr()))
+			uploadResponse = UploadResponse.getErrorInvalidCommand();
+		else if (!isQuickUpload && !ResourceType.isValid(context.getTypeStr()))
+			uploadResponse = UploadResponse.getErrorInvalidType();
+		else if (!UtilsFile.isValidPath(context.getCurrentFolderStr()))
+			uploadResponse = UploadResponse.getErrorInvalidCurrentFolder();
+		else {
+
+			// call the Connector#fileUpload
+			ResourceType type = context.getDefaultResourceType();
+			FileItemFactory factory = new DiskFileItemFactory();
+			ServletFileUpload upload = new ServletFileUpload(factory);
+			try {
+				@SuppressWarnings("unchecked") List<FileItem> items = upload.parseRequest(request);
+				// We upload just one file at the same time
+				FileItem uplFile = items.get(0);
+				// check the extension (can't be done if QuickUpload)
+				if (!isQuickUpload && !ExtensionsHandler.isAllowed(type, FilenameUtils.getExtension(uplFile.getName())))
+					uploadResponse = UploadResponse.getErrorInvalidExtension();
+				// Secure image check (can't be done if QuickUpload)
+				else if (!isQuickUpload && type.equals(ResourceType.IMAGE) && ConnectorHandler.isSecureImageUploads() && !UtilsFile.isImage(uplFile.getInputStream())) {
+					uploadResponse = UploadResponse.getErrorInvalidExtension();
+				} else {
+					String fileName = FilenameUtils.getName(UtilsFile.sanitizeFileName(uplFile.getName()));
+					String newFileName;
+					if (isQuickUpload) {
+						newFileName = connector.quickUpload(fileName, uplFile.getInputStream());
+					} else {
+						newFileName = connector.fileUpload(type, context.getCurrentFolderStr(), fileName, uplFile.getInputStream());
+					}
+					// TODO I don't like this either
+					String responseUrl = context.buildUrl(ConnectorHandler.getUserFilesPath());
+					if (fileName.equals(newFileName))
+						uploadResponse = new UploadResponse(UploadResponse.SC_OK, responseUrl);
+					else
+						uploadResponse =  new UploadResponse(UploadResponse.SC_RENAMED, responseUrl, newFileName); 
+				}
+				uplFile.delete();
+			} catch (InvalidCurrentFolderException e) {
+				uploadResponse = UploadResponse.getErrorInvalidCurrentFolder();
+			} catch (SecurityIssueException e) {
+				uploadResponse = UploadResponse.getErrorSecurity();
+			} catch (Exception e) {
+				uploadResponse = UploadResponse.getErrorSecurity();
+			}
+		}
+		out.print(uploadResponse);
+		out.flush();
+		out.close();
+		logger.debug("Exiting Dispatcher#doPost");
+	}
+	
+	
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/FolderAlreadyExistsException.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/FolderAlreadyExistsException.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/FolderAlreadyExistsException.java	(revision 2584)
@@ -0,0 +1,34 @@
+/*
+ * 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.connector.exception;
+
+import net.fckeditor.connector.Connector;
+import net.fckeditor.connector.Dispatcher;
+
+/**
+ * Signals that a {@link Connector} method tried to create a folder that already exists. <br>
+ * <br> 
+ * These is an exception to signal the {@link Dispatcher} what was going wrong.
+ *
+ * @version $Id$
+ */
+public class FolderAlreadyExistsException extends Exception {
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/InvalidCurrentFolderException.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/InvalidCurrentFolderException.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/InvalidCurrentFolderException.java	(revision 2584)
@@ -0,0 +1,35 @@
+/*
+ * 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.connector.exception;
+
+import net.fckeditor.connector.Connector;
+import net.fckeditor.connector.Dispatcher;
+
+/**
+ * Signals that a {@link Connector} method can't find the current folder. That's 
+ * never happened in common cases.<br>
+ * <br> 
+ * These is an exception to signal the {@link Dispatcher} what was going wrong.
+ *
+ * @version $Id$
+ */
+public class InvalidCurrentFolderException extends Exception {
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/InvalidFolderNameException.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/InvalidFolderNameException.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/InvalidFolderNameException.java	(revision 2584)
@@ -0,0 +1,34 @@
+/*
+ * 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.connector.exception;
+
+import net.fckeditor.connector.Connector;
+import net.fckeditor.connector.Dispatcher;
+
+/**
+ * Signals that a {@link Connector} method tried to create a folder and it fails. <br>
+ * <br> 
+ * These is an exception to signal the {@link Dispatcher} what was going wrong.
+ *
+ * @version $Id$
+ */
+public class InvalidFolderNameException extends Exception {
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/SecurityIssueException.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/SecurityIssueException.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/SecurityIssueException.java	(revision 2584)
@@ -0,0 +1,34 @@
+/*
+ * 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.connector.exception;
+
+import net.fckeditor.connector.Connector;
+import net.fckeditor.connector.Dispatcher;
+
+/**
+ * Thrown to indicate a security violation in a {@link Connector}.<br>
+ * <br> 
+ * These is an exception to signal the {@link Dispatcher} what was going wrong. 
+ *
+ * @version $Id$
+ */
+public class SecurityIssueException extends Exception {
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/UnknownException.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/UnknownException.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/exception/UnknownException.java	(revision 2584)
@@ -0,0 +1,33 @@
+/*
+ * 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.connector.exception;
+
+import net.fckeditor.connector.Dispatcher;
+
+/**
+ * Signals an undefined exception.<br>
+ * <br> 
+ * These is an exception to signal the {@link Dispatcher} what was going wrong.
+ *
+ * @version $Id$
+ */
+public class UnknownException extends Exception {
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/impl/SimpleFileSystemConnector.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/impl/SimpleFileSystemConnector.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/connector/impl/SimpleFileSystemConnector.java	(revision 2584)
@@ -0,0 +1,197 @@
+/*
+ * 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.connector.impl;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+
+import net.fckeditor.connector.Connector;
+import net.fckeditor.connector.exception.FolderAlreadyExistsException;
+import net.fckeditor.connector.exception.InvalidCurrentFolderException;
+import net.fckeditor.connector.exception.InvalidFolderNameException;
+import net.fckeditor.connector.exception.SecurityIssueException;
+import net.fckeditor.connector.exception.UnknownException;
+import net.fckeditor.handlers.ConnectorHandler;
+import net.fckeditor.handlers.ResourceType;
+import net.fckeditor.requestcycle.ThreadLocalData;
+import net.fckeditor.tool.Utils;
+import net.fckeditor.tool.UtilsFile;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.filefilter.DirectoryFileFilter;
+import org.apache.commons.io.filefilter.FileFileFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of the {@link Connector} for the file system. All path are interpreted as sub-directories 
+ * of the {@link ConnectorHandler#getUserFilesPath()}.<br>
+ * 
+ * TODO should we move the static methods into a util-class in package net.fckeditor.connector.impl ???
+ * @version $Id$
+ */
+// FIXME the name is inappropriate, it should be ContextFileSystemConnector
+// we should provide another implementation which leads outside of the context
+// HINT: we should keep this name because it can run without any PathBuilder implementation
+public class SimpleFileSystemConnector implements Connector {
+	private static final Logger logger = LoggerFactory.getLogger(SimpleFileSystemConnector.class);
+	private static ServletContext servletContext;
+
+	/* (non-Javadoc)
+	 * @see net.fckeditor.connector.Connector#init()
+	 */
+	public void init(final ServletContext servletContext) {
+		// create user's default dir
+		SimpleFileSystemConnector.servletContext = servletContext;
+		String realDefaultUserFilesPath = SimpleFileSystemConnector.servletContext.getRealPath(ConnectorHandler.getDefaultUserFilesPath());
+		File defaultUserFilesDir = new File(realDefaultUserFilesPath);
+		UtilsFile.checkDirAndCreate(defaultUserFilesDir);
+		logger.info("Initialized!");
+	}
+	
+
+	/* (non-Javadoc)
+	 * @see net.fckeditor.connector.Connector#fileUpload(net.fckeditor.handlers.ResourceType, java.lang.String, java.lang.String, java.io.InputStream)
+	 */
+	public String fileUpload(final ResourceType type, final String currentFolder, final String fileName, final InputStream inputStream) 
+			throws InvalidCurrentFolderException, SecurityIssueException {
+		String baseDir = ConnectorHandler.getUserFilesPath();
+		File typeDir = getAndCreateResourceTypeDir(baseDir, type);
+		File currentDir = new File(typeDir, currentFolder);
+		if (!currentDir.exists())
+			throw new InvalidCurrentFolderException(); 
+		return upload(currentDir, fileName, inputStream);
+	}
+	
+	/* (non-Javadoc)
+	 * @see net.fckeditor.connector.Connector#quickUpload(java.lang.String, java.io.InputStream)
+	 */
+	public String quickUpload(String fileName, final InputStream inputStream) throws SecurityIssueException {
+		File currentDir = new File(servletContext.getRealPath(ConnectorHandler.getUserFilesPath()));
+		return upload(currentDir, fileName, inputStream);
+	}
+
+	private String upload(final File currentDir, final String fileName, final InputStream inputStream) throws SecurityIssueException {
+		File newFile = new File(currentDir, fileName);
+		File fileToSave = UtilsFile.getUniqueFile(newFile.getAbsoluteFile());
+		try {
+			BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileToSave));
+			IOUtils.copyLarge(inputStream, out);
+		} catch (Exception e) {
+			throw new SecurityIssueException();
+		}
+		return fileToSave.getName();
+	}
+
+	/* (non-Javadoc)
+	 * @see net.fckeditor.connector.Connector#createFolder(net.fckeditor.handlers.ResourceType, java.lang.String, java.lang.String)
+	 */
+	public void createFolder(final ResourceType type, final String currentFolder, final String newFolder) 
+			throws InvalidCurrentFolderException, SecurityIssueException, InvalidFolderNameException, FolderAlreadyExistsException {
+		String baseDir = ConnectorHandler.getUserFilesPath();
+		File typeDir = getAndCreateResourceTypeDir(baseDir, type);
+		File currentDir = new File(typeDir, currentFolder);
+		if (!currentDir.exists())
+			throw new InvalidCurrentFolderException();
+		File newDir = new File(currentDir, newFolder);
+		if (newDir.exists())
+			throw new FolderAlreadyExistsException();
+		try {
+			if (!newDir.mkdir()) 
+				throw new InvalidFolderNameException();
+		} catch (SecurityException e) {
+			throw new SecurityIssueException();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see net.fckeditor.connector.Connector#getFiles(net.fckeditor.handlers.ResourceType, java.lang.String)
+	 */
+	public List<Map<String, Object>> getFiles(ResourceType type, String currentFolder)
+			throws InvalidCurrentFolderException, SecurityIssueException, UnknownException {
+		String baseDir = ConnectorHandler.getUserFilesPath();
+		File typeDir = getAndCreateResourceTypeDir(baseDir, type);
+		File currentDir = new File(typeDir, currentFolder);
+		if (!currentDir.exists())
+			throw new InvalidCurrentFolderException();
+
+		// collect files
+		List<Map<String, Object>> files;
+		Map<String, Object> fileMap;
+		try {
+			File[] fileList = currentDir.listFiles((FileFilter) FileFileFilter.FILE);
+			files = new ArrayList<Map<String,Object>>(fileList.length);
+			for (File file : fileList) {
+				fileMap = new HashMap<String, Object>(2);
+				fileMap.put(Connector.KEY_NAME, file.getName());
+				fileMap.put(Connector.KEY_SIZE, file.length());
+				files.add(fileMap);
+			}
+			return files;
+		} catch (SecurityException e) {
+			throw new SecurityIssueException();
+		}
+	}
+
+
+	/* (non-Javadoc)
+	 * @see net.fckeditor.connector.Connector#getFolders(net.fckeditor.handlers.ResourceType, java.lang.String)
+	 */
+	public  List<String> getFolders(final ResourceType type, final String currentFolder)
+			throws InvalidCurrentFolderException, SecurityIssueException, UnknownException {
+		String baseDir = ConnectorHandler.getUserFilesPath();
+		File typeDir = getAndCreateResourceTypeDir(baseDir, type);
+		File currentDir = new File(typeDir, currentFolder);
+		if (!currentDir.exists())
+			throw new InvalidCurrentFolderException();
+		if (!currentDir.isDirectory())
+			throw new UnknownException();
+		try {
+			String[] fileList = currentDir.list(DirectoryFileFilter.DIRECTORY);
+			return Arrays.asList(fileList);
+		} catch (Exception e) {
+			throw new SecurityIssueException();
+		}
+	}
+
+	
+	private static File getAndCreateResourceTypeDir(final String baseDir, final ResourceType type) {
+		String folderStr = new String(baseDir);
+		String contextPath = ThreadLocalData.getServletRequest().getContextPath();
+		//we have to check, if there is a context path and cut it, it's obsolete for the filesystem
+		if (Utils.isNotEmpty(contextPath))
+			folderStr = folderStr.substring(contextPath.length());
+		File dir = new File(servletContext.getRealPath(folderStr), type.getPath());
+		if (!dir.exists()) 
+			dir.mkdirs();
+		return dir;
+	}
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/ConnectorHandler.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/ConnectorHandler.java	(revision 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/ConnectorHandler.java	(revision 2584)
@@ -21,6 +21,8 @@
 package net.fckeditor.handlers;
 
-import javax.servlet.http.HttpServletRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import net.fckeditor.connector.Connector;
 import net.fckeditor.requestcycle.UserPathBuilder;
 
@@ -32,14 +34,36 @@
  */
 public class ConnectorHandler {
+	
+	private static Logger logger = LoggerFactory.getLogger(ConnectorHandler.class);
+	private static Connector connector = null;
+	
+	static {
+		
+		// 3. try to instantiate the Connector object
+		String fqcn = PropertiesLoader.getProperty("connector.implementation");
+		if (fqcn == null)
+			logger.warn("No property found for Connector implementation, any user action will be disabled!");
+		else {
+			try {
+				Class<?> clazz = Class.forName(fqcn);
+				connector = (Connector) clazz.newInstance();
+				logger.info("Connector initialized to {}", connector.getClass());
+			} catch (Exception e) {
+				logger.error("Couldn't instantiate class [".concat(fqcn).concat(
+				        "], any user action will disabled!"), e);
+			}
+		}
+	}
 
 	/**
-	 * Getter for the <code>UserFilesPath</code>.
+	 * Getter for the <code>UserFilesPath</code>.<br>
+	 * Should be use in the implementations of {@link Connector}.
 	 * 
-	 * @return {@link UserPathBuilder#getUserFilesPath(HttpServletRequest)} or
+	 * @return {@link UserPathBuilder#getUserFilesPath()} or
 	 *         the <code>DefaultUserFilePath</code> if {@link UserPathBuilder}
 	 *         isn't set.
 	 */
-	public static String getUserFilesPath(final HttpServletRequest request) {
-    	String userFilePath = RequestCycleHandler.getUserFilePath(request);
+	public static String getUserFilesPath() {
+    	String userFilePath = RequestCycleHandler.getUserFilesPath();
     	return (userFilePath != null) ? userFilePath : getDefaultUserFilesPath();
     }
@@ -63,5 +87,9 @@
 	 */
 	public static boolean isFullUrl() {
-		return Boolean.valueOf(PropertiesLoader.getProperty("connector.fullUrl"));
+		return Boolean.parseBoolean(PropertiesLoader.getProperty("connector.fullUrl"));
+	}
+	
+	public static String getBaseUrl() {
+		return PropertiesLoader.getProperty("connector.baseUrl");
 	}
 
@@ -85,3 +113,12 @@
 		return Boolean.valueOf(PropertiesLoader.getProperty("connector.secureImageUploads"));
 	}
+
+	/**
+	 * Getter for the implementation of {@link Connector}.
+	 * 
+	 * @return Implementation of {@link Connector}.
+	 */
+	public static Connector getConnector() {
+		return connector;
+	}
 }
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/ExtensionsHandler.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/ExtensionsHandler.java	(revision 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/ExtensionsHandler.java	(revision 2584)
@@ -42,24 +42,24 @@
 public class ExtensionsHandler {
 
-	private static Map<ResourceTypeHandler, Set<String>> extensionsAllowed = new HashMap<ResourceTypeHandler, Set<String>>();
-	private static Map<ResourceTypeHandler, Set<String>> extensionsDenied = new HashMap<ResourceTypeHandler, Set<String>>();
+	private static Map<ResourceType, Set<String>> extensionsAllowed = new HashMap<ResourceType, Set<String>>();
+	private static Map<ResourceType, Set<String>> extensionsDenied = new HashMap<ResourceType, Set<String>>();
 
 	static {
 		// load defaults
-		extensionsAllowed.put(ResourceTypeHandler.FILE, Utils.getSet(PropertiesLoader
+		extensionsAllowed.put(ResourceType.FILE, Utils.getSet(PropertiesLoader
 		    .getProperty("connector.resourceType.file.extensions.allowed")));
-		extensionsDenied.put(ResourceTypeHandler.FILE, Utils.getSet(PropertiesLoader
+		extensionsDenied.put(ResourceType.FILE, Utils.getSet(PropertiesLoader
 		    .getProperty("connector.resourceType.file.extensions.denied")));
-		extensionsAllowed.put(ResourceTypeHandler.MEDIA, Utils.getSet(PropertiesLoader
+		extensionsAllowed.put(ResourceType.MEDIA, Utils.getSet(PropertiesLoader
 		    .getProperty("connector.resourceType.media.extensions.allowed")));
-		extensionsDenied.put(ResourceTypeHandler.MEDIA, Utils.getSet(PropertiesLoader
+		extensionsDenied.put(ResourceType.MEDIA, Utils.getSet(PropertiesLoader
 		    .getProperty("connector.resourceType.media.extensions.denied")));
-		extensionsAllowed.put(ResourceTypeHandler.IMAGE, Utils.getSet(PropertiesLoader
+		extensionsAllowed.put(ResourceType.IMAGE, Utils.getSet(PropertiesLoader
 		    .getProperty("connector.resourceType.image.extensions.allowed")));
-		extensionsDenied.put(ResourceTypeHandler.IMAGE, Utils.getSet(PropertiesLoader
+		extensionsDenied.put(ResourceType.IMAGE, Utils.getSet(PropertiesLoader
 		    .getProperty("connector.resourceType.image.extensions.denied")));
-		extensionsAllowed.put(ResourceTypeHandler.FLASH, Utils.getSet(PropertiesLoader
+		extensionsAllowed.put(ResourceType.FLASH, Utils.getSet(PropertiesLoader
 		    .getProperty("connector.resourceType.flash.extensions.allowed")));
-		extensionsDenied.put(ResourceTypeHandler.FLASH, Utils.getSet(PropertiesLoader
+		extensionsDenied.put(ResourceType.FLASH, Utils.getSet(PropertiesLoader
 		    .getProperty("connector.resourceType.flash.extensions.denied")));
 	}
@@ -72,5 +72,5 @@
 	 * @return Set of allowed extensions or an empty set.
 	 */
-	public static Set<String> getExtensionsAllowed(final ResourceTypeHandler type) {
+	public static Set<String> getExtensionsAllowed(final ResourceType type) {
 		return extensionsAllowed.get(type);
 	}
@@ -87,5 +87,5 @@
 	 *            Required format: <code>ext1&#124;ext2&#124;ext3</code>
 	 */
-	public static void setExtensionsAllowed(final ResourceTypeHandler type, final String extensionsList) {
+	public static void setExtensionsAllowed(final ResourceType type, final String extensionsList) {
 		if (extensionsList != null) {
 			extensionsAllowed.put(type, Utils.getSet(extensionsList));
@@ -101,5 +101,5 @@
 	 * @return Set of denied extensions or an empty set.
 	 */
-	public static Set<String> getExtensionsDenied(final ResourceTypeHandler type) {
+	public static Set<String> getExtensionsDenied(final ResourceType type) {
 		return extensionsDenied.get(type);
 	}
@@ -116,5 +116,5 @@
 	 *            Required format: <code>ext1&#124;ext2&#124;ext3</code>
 	 */
-	public static void setExtensionsDenied(final ResourceTypeHandler type, final String extensionsList) {
+	public static void setExtensionsDenied(final ResourceType type, final String extensionsList) {
 		if (extensionsList != null) {
 			extensionsDenied.put(type, Utils.getSet(extensionsList));
@@ -134,5 +134,5 @@
 	 *         is always returned if 'type' or 'extensions' is <code>null</code>.
 	 */
-	public static boolean isAllowed(final ResourceTypeHandler type, final String extension) {
+	public static boolean isAllowed(final ResourceType type, final String extension) {
 		if (type == null || extension == null)
 			return false;
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 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/LocalizedPropertiesLoader.java	(revision 2584)
@@ -30,8 +30,8 @@
 import javax.servlet.http.HttpServletRequest;
 
+import net.fckeditor.localization.LocaleResolver;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import net.fckeditor.localization.LocaleResolver;
 
 /**
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/RequestCycleHandler.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/RequestCycleHandler.java	(revision 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/RequestCycleHandler.java	(revision 2584)
@@ -21,5 +21,4 @@
 package net.fckeditor.handlers;
 
-import javax.servlet.http.HttpServletRequest;
 
 import net.fckeditor.requestcycle.UserAction;
@@ -42,5 +41,5 @@
 	static {
 		// If there are more objects to instantiate in future, we could solve the following by reflection!
-		
+				
 		// 1. try to instantiate the UserAction object
 		String fqcn = PropertiesLoader.getProperty("connector.userActionImpl");
@@ -77,24 +76,33 @@
 	/**
 	 * Just a wrapper to
-	 * {@link UserAction#isEnabledForFileBrowsing(HttpServletRequest)}.
+	 * {@link UserAction#isEnabledForFileBrowsing()}.
 	 * 
-	 * @param request
-	 * @return {@link UserAction#isEnabledForFileBrowsing(HttpServletRequest)}
-	 *         or false if <code>userAction</code> isn't set.
+	 * @return {@link UserAction#isEnabledForFileBrowsing()}
+	 *         or false if {@link UserAction} isn't set.
 	 */
-	public static boolean isEnabledForFileBrowsing(final HttpServletRequest request) {
-		return (userAction != null && userAction.isEnabledForFileBrowsing(request));
+	public static boolean isEnabledForFileBrowsing() {
+		return (userAction != null && userAction.isEnabledForFileBrowsing());
 	}
 
 	/**
 	 * Just a wrapper to
-	 * {@link UserAction#isEnabledForFileUpload(HttpServletRequest)}.
+	 * {@link UserAction#isEnabledForFileUpload()}.
 	 * 
-	 * @param request
-	 * @return {@link UserAction#isEnabledForFileUpload(HttpServletRequest)} or
-	 *         false if <code>userAction</code> isn't set.
+	 * @return {@link UserAction#isEnabledForFileUpload()} or
+	 *         false if {@link UserAction} isn't set.
 	 */
-	public static boolean isEnabledForFileUpload(final HttpServletRequest request) {
-		return (userAction != null && userAction.isEnabledForFileUpload(request));
+	public static boolean isEnabledForFileUpload() {
+		return (userAction != null && userAction.isEnabledForFileUpload());
+	}
+
+	/**
+	 * Just a wrapper to
+	 * {@link UserAction#isEnabledForFolderCreation()}.
+	 * 
+	 * @return {@link UserAction#isEnabledForFolderCreation()} or
+	 *         false if {@link UserAction} isn't set.
+	 */
+	public static boolean isEnabledForFolderCreation() {
+		return (userAction != null && userAction.isEnabledForFolderCreation());
 	}
 
@@ -104,14 +112,10 @@
 	 * 
 	 * @param request
-	 * @return {@link UserPathBuilder#getUserFilesPath(HttpServletRequest)} or
+	 * @return {@link UserPathBuilder#getUserFilesPath()} or
 	 *         <code>null</code> if <code>userPathBuilder</code> is
 	 *         <code>null</code>.
 	 */
-	public static String getUserFilePath(final HttpServletRequest request) {
-		return (userPathBuilder != null) ? userPathBuilder.getUserFilesPath(request) : null;
-	}
-	
-	public static String getLocalUserFilePath() {
-		return (userPathBuilder != null) ? userPathBuilder.getLocalUserFilesPath() : null;
+	public static String getUserFilesPath() {
+		return (userPathBuilder != null) ? userPathBuilder.getUserFilesPath() : null;
 	}
 }
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/ResourceType.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/ResourceType.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/ResourceType.java	(revision 2584)
@@ -0,0 +1,150 @@
+/*
+ * 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.HashMap;
+import java.util.Map;
+
+import net.fckeditor.tool.Utils;
+
+/**
+ * Common resource type holder without any implementation (connector) specific stuff.
+ *
+ * @version $Id$
+ */
+public class ResourceType {
+	private String name;
+	private String path;
+	private static Map<String, ResourceType> types = new HashMap<String, ResourceType>(4);
+		
+	public static final ResourceType FILE = new ResourceType("file", PropertiesLoader.getProperty("connector.resourceType.file.path"));
+	public static final ResourceType FLASH = new ResourceType("flash", PropertiesLoader.getProperty("connector.resourceType.flash.path"));
+	public static final ResourceType IMAGE = new ResourceType("image", PropertiesLoader.getProperty("connector.resourceType.image.path"));
+	public static final ResourceType MEDIA = new ResourceType("media", PropertiesLoader.getProperty("connector.resourceType.media.path"));
+	
+	static {
+		types.put(FILE.getName(), FILE);
+		types.put(FLASH.getName(), FLASH);
+		types.put(IMAGE.getName(), IMAGE);
+		types.put(MEDIA.getName(), MEDIA);
+	}
+	
+	private ResourceType(final String name, final String path) {
+		this.name = name;
+		this.path = path;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public String getPath() {
+		return path;
+	}
+	
+	/**
+	 * Getter for a {@link ResourceType} for a specified string. <br>
+	 * The comparison isn't case sensitive!
+	 * 
+	 * @param name A resource type to retrieve.
+	 * @return A {@link ResourceType} object holding the value
+	 *         represented by the string argument.
+	 * @throws IllegalArgumentException
+	 *            If 'name' is <code>null</code>, empty, or does not exist.
+	 */
+	public static ResourceType valueOf(final String name) {
+		if (Utils.isEmpty(name))
+			throw new IllegalArgumentException();
+
+		ResourceType rt = types.get(name.toLowerCase());
+		if (rt == null)
+			throw new IllegalArgumentException();
+		return rt;
+	}
+	
+	/**
+	 * Checks if a specified string represents a valid resource type.<br>
+	 * The comparison isn't case sensitive!
+	 * 
+	 * @param name
+	 *            A resource type string to check.
+	 * @return <code>true</code> if the string representation is valid else
+	 *         <code>false</code>.
+	 */
+	public static boolean isValid(final String name) {
+		return (Utils.isEmpty(name)) ? false : types.containsKey(name.toLowerCase());
+	}
+
+	/**
+	 * A wrapper for {@link #valueOf(String)}. It returns <code>null</code>
+	 * instead of throwing an exception.<br>
+	 * The comparison isn't case sensitive!
+	 * 
+	 * @param name
+	 *            A resource type string to check.
+	 * @return A {@link ResourceType} object holding the value
+	 *         represented by the string argument, or <code>null</code>.
+	 */
+	public static ResourceType getResourceType(final String name) {
+		try {
+			return ResourceType.valueOf(name.toLowerCase());
+		} catch (Exception e) {
+			return null;
+		}
+	}
+	
+	/**
+	 * Tries to determine ResourceType from string and return {@link #FILE} if
+	 * provided string is invalid.<br><br>
+	 * The comparison isn't case sensitive!
+	 * 
+	 * @param name
+	 * @return resource type
+	 */
+	public static ResourceType getDefaultResourceType(final String name) {
+		if (Utils.isEmpty(name))
+			return null;
+		ResourceType rt = getResourceType(name);
+		return rt == null ? FILE : rt;
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if (obj == null || !(obj instanceof ResourceType))
+			return false;
+		else {
+			ResourceType rt = (ResourceType)obj;
+			return name.equals(rt.getName());
+		}
+	}
+	
+	/*
+	 * (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		return name.hashCode();
+	}
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/ResourceTypeHandler.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/handlers/ResourceTypeHandler.java	(revision 2578)
+++ 	(revision )
@@ -1,179 +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.HashMap;
-import java.util.Map;
-
-import net.fckeditor.tool.Utils;
-
-/**
- * Handler for different resource types.
- * 
- * @version $Id$
- */
-public class ResourceTypeHandler {
-
-	private String name;
-	private static Map<String, ResourceTypeHandler> types = new HashMap<String, ResourceTypeHandler>(
-	        4);
-	private static Map<ResourceTypeHandler, String> paths = new HashMap<ResourceTypeHandler, String>(
-	        4);
-	public static final ResourceTypeHandler FILE = new ResourceTypeHandler("File");
-	public static final ResourceTypeHandler FLASH = new ResourceTypeHandler("Flash");
-	public static final ResourceTypeHandler IMAGE = new ResourceTypeHandler("Image");
-	public static final ResourceTypeHandler MEDIA = new ResourceTypeHandler("Media");
-
-	static {
-		// initialize the resource types
-		types.put(FILE.getName(), FILE);
-		types.put(FLASH.getName(), FLASH);
-		types.put(IMAGE.getName(), IMAGE);
-		types.put(MEDIA.getName(), MEDIA);
-
-		// initialize the sub folders for each resource type
-		paths.put(FILE, PropertiesLoader.getProperty("connector.resourceType.file.path"));
-		paths.put(IMAGE, PropertiesLoader.getProperty("connector.resourceType.image.path"));
-		paths.put(FLASH, PropertiesLoader.getProperty("connector.resourceType.flash.path"));
-		paths.put(MEDIA, PropertiesLoader.getProperty("connector.resourceType.media.path"));
-	}
-
-	private ResourceTypeHandler(final String name) {
-		this.name = name;
-	}
-
-	/**
-	 * Getter for the name.
-	 * 
-	 * @return name
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * Getter for the resource type path (sub folder).
-	 * 
-	 * @return The path (sub folder).
-	 */
-	public String getPath() {
-		return paths.get(this);
-	}
-
-	/**
-	 * Getter for a {@link ResourceTypeHandler} for a specified string.
-	 * 
-	 * @param name
-	 *            A resource type to retrieve.
-	 * @return A {@link ResourceTypeHandler} object holding the value
-	 *         represented by the string argument.
-	 * @throws IllegalArgumentException
-	 *            If 'name' is <code>null</code>, empty, or does not exist.
-	 */
-	public static ResourceTypeHandler valueOf(final String name) throws IllegalArgumentException {
-		if (Utils.isEmpty(name))
-			throw new IllegalArgumentException();
-
-		ResourceTypeHandler rt = types.get(name);
-		if (rt == null)
-			throw new IllegalArgumentException();
-		return rt;
-	}
-
-	/**
-	 * 
-	 * Checks if a specified string represents a valid resource type.
-	 * 
-	 * @param name
-	 *            A resource type string to check.
-	 * @return <code>true</code> if the string representation is valid else
-	 *         <code>false</code>.
-	 */
-	public static boolean isValid(final String name) {
-		return types.containsKey(name);
-	}
-
-	/**
-	 * Tries to determine ResourceType from string and return {@link #FILE} if
-	 * provided string is invalid.
-	 * 
-	 * @param name
-	 * @return resource type
-	 */
-	public static ResourceTypeHandler getDefaultResourceType(final String name) {
-		ResourceTypeHandler rt = getResourceType(name);
-		return rt == null ? FILE : rt;
-	}
-
-	/**
-	 * A wrapper for {@link #valueOf(String)}. It returns <code>null</code>
-	 * instead of throwing an exception.
-	 * 
-	 * @param name
-	 *            A resource type string to check.
-	 * @return A {@link ResourceTypeHandler} object holding the value
-	 *         represented by the string argument, or <code>null</code>.
-	 */
-	public static ResourceTypeHandler getResourceType(final String name) {
-		try {
-			return ResourceTypeHandler.valueOf(name);
-		} catch (Exception e) {
-			return null;
-		}
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see java.lang.Object#equals(java.lang.Object)
-	 */
-	@Override
-	public boolean equals(Object obj) {
-		if (obj == null)
-			return false;
-		try {
-			ResourceTypeHandler rt = (ResourceTypeHandler) obj;
-			return name.equals(rt.getName());
-		} catch (ClassCastException e) {
-			return false;
-		}
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see java.lang.Object#toString()
-	 */
-	@Override
-	public int hashCode() {
-		return name.hashCode();
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see java.lang.Object#toString()
-	 */
-	@Override
-	public String toString() {
-		return name;
-	}
-}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/Context.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/Context.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/Context.java	(revision 2584)
@@ -0,0 +1,130 @@
+/*
+ * 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.requestcycle;
+
+import javax.servlet.http.HttpServletRequest;
+
+import net.fckeditor.handlers.CommandHandler;
+import net.fckeditor.handlers.ConnectorHandler;
+import net.fckeditor.handlers.ResourceType;
+import net.fckeditor.tool.Utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Holds basic parameters and associated methods for each request.
+ *
+ * @version $Id$
+ */
+public class Context {
+	private static final Logger logger = LoggerFactory.getLogger(Context.class);
+	
+	private String typeStr;
+	private String commandStr;
+	private String currentFolderStr;
+	
+	protected Context(final HttpServletRequest request) {
+		commandStr = request.getParameter("Command");
+		typeStr = request.getParameter("Type");
+		currentFolderStr = request.getParameter("CurrentFolder");
+		
+		// checks to meet specs in http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Server_Side_Integration#File_Browser_Requests
+		if (currentFolderStr != null && !currentFolderStr.startsWith("/"))
+			currentFolderStr = "/".concat(currentFolderStr);
+	}
+	
+	public boolean checkQuickUpload() {
+		if (Utils.isEmpty(commandStr) && Utils.isEmpty(currentFolderStr)) {
+			commandStr = "QuickUpload";
+			currentFolderStr = "/";
+			return true;
+		}
+		return false;
+	}
+	
+	/**
+	 * @return the typeStr
+	 */
+	public String getTypeStr() {
+		return typeStr;
+	}
+	
+	public ResourceType getDefaultResourceType() {
+		return ResourceType.getDefaultResourceType(typeStr);
+	}
+	
+	/**
+	 * @return the commandStr
+	 */
+	public String getCommandStr() {
+		return commandStr;
+	}
+	
+	public CommandHandler getCommand() {
+		return CommandHandler.valueOf(commandStr);
+	}
+	
+	/**
+	 * @return the currentFolderStr
+	 */
+	public String getCurrentFolderStr() {
+		return currentFolderStr;
+	}
+	
+	public void logBaseParameters() {
+		logger.debug("Parameter Command: {}", commandStr);
+		logger.debug("Parameter Type: {}", typeStr);
+		logger.debug("Parameter CurrentFolder: {}", currentFolderStr);
+	}
+	
+	/**
+	 * @return
+	 */
+	public String buildCurrentTypeDir() {
+		StringBuffer sb = new StringBuffer();
+		if (Utils.isNotEmpty(typeStr))
+			sb.append(getDefaultResourceType().getPath());
+		if (Utils.isNotEmpty(currentFolderStr))
+			sb.append(currentFolderStr);
+		if (!sb.toString().endsWith("/"))
+			sb.append("/");
+		return sb.toString();
+	}
+	
+	public String buildUrl(final String baseDir) {
+    	StringBuffer sb = new StringBuffer();
+    	HttpServletRequest request = ThreadLocalData.getServletRequest();
+
+		if (Utils.isNotEmpty(ConnectorHandler.getBaseUrl())) {
+			sb.append(ConnectorHandler.getBaseUrl());
+		} else if (ConnectorHandler.isFullUrl()) {
+    		String address = request.getRequestURL().toString();
+    		sb.append(address.substring(0, address.indexOf('/', 8)));
+    	}
+    	    	
+    	sb.append(baseDir);
+    	String currentTypeDir = buildCurrentTypeDir();
+    	if (!currentTypeDir.equals("/"))
+    		sb.append(buildCurrentTypeDir());
+    	return sb.toString();
+	}
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/ThreadLocalData.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/ThreadLocalData.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/ThreadLocalData.java	(revision 2584)
@@ -0,0 +1,61 @@
+/*
+ * 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.requestcycle;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Container for {@link ThreadLocal}s.<br>
+ *
+ * @version $Id$
+ */
+public class ThreadLocalData {
+	private static ThreadLocal<HttpServletRequest> servletRequest = null;
+	private static ThreadLocal<Context> context = null;
+	
+	public static void beginRequest(final HttpServletRequest servletRequest) {
+		if (servletRequest == null)
+			throw new IllegalArgumentException();
+		if (ThreadLocalData.servletRequest == null)
+			ThreadLocalData.servletRequest = new ThreadLocal<HttpServletRequest>();
+		ThreadLocalData.servletRequest.set(servletRequest);
+		if (ThreadLocalData.context == null)
+			ThreadLocalData.context = new ThreadLocal<Context>();
+		ThreadLocalData.context.set(new Context(servletRequest));
+	}
+	
+	public static HttpServletRequest getServletRequest() {
+		return (servletRequest == null) ? null : servletRequest.get();
+	}
+	
+	 public static Context getContext() {
+		 return (context == null) ? null : context.get();
+	 }
+	
+	/**
+	 * Clear the ThreadLocals.<br>
+	 * <b>Important: To prevent memory leaks we have to make sure that this method is calling at the end of each request cycle!!!</b>
+	 */
+	public static void endRequest() {
+		servletRequest = null;
+		context = null;
+	}
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/UserAction.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/UserAction.java	(revision 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/UserAction.java	(revision 2584)
@@ -24,13 +24,18 @@
 
 
+
 /**
  * An interface which provides the authorization of server-side commands.<br />
  * The commands are:
  * <ul>
- * <li>{@link #isEnabledForFileBrowsing(HttpServletRequest)}: Enables the user
+ * <li>{@link #isEnabledForFileBrowsing()}: Enables the user
  * to browse/select files.</li>
- * <li>{@link #isEnabledForFileUpload(HttpServletRequest)}: Enables the user
+ * <li>{@link #isEnabledForFileUpload()}: Enables the user
  * to upload files.</li>
+ * <li>{@link #isEnabledForFolderCreation()} Enables the user
+ * to create folders.</li>
  * </ul>
+ * <strong>If your implementation needs {@link HttpServletRequest} e.g. to get a
+ * session variable, you can get it by calling {@link ThreadLocalData#getServletRequest()}.</strong>
  * 
  * @version $Id$
@@ -40,28 +45,26 @@
 	/**
 	 * Authenticates/enables the current user for uploading files.<br />
-	 * If the implementation doesn't bother you, just return <code>true</code>.
 	 * 
-	 * @param request
-	 *            Servlet request from user
 	 * @return <code>true</code> if user can upload to the server, or
 	 *         <code>false</code>
 	 */
-	public boolean isEnabledForFileUpload(final HttpServletRequest request);
+	public boolean isEnabledForFileUpload();
 
 	/**
 	 * Authenticates/enables the current user for browsing files.<br />
-	 * If the implementation doesn't bother you, just return <code>true</code>.
 	 * 
-	 * @param request
-	 *            Servlet request from user
 	 * @return <code>true</code> if user can browse the server, or
 	 *         <code>false</code>
 	 */
-	public boolean isEnabledForFileBrowsing(final HttpServletRequest request);
+	public boolean isEnabledForFileBrowsing();
 	
+
 	/**
-	 * TODO document me!
+	 * Authenticates/enables the current user to create folders.<br />
+	 * 
+	 * @return <code>true</code> if user can create folders on the server, or
+	 *         <code>false</code>
 	 */
-	public boolean isEnabledForFolderCreation(final HttpServletRequest request);
+	public boolean isEnabledForFolderCreation();
 
 }
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/UserPathBuilder.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/UserPathBuilder.java	(revision 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/UserPathBuilder.java	(revision 2584)
@@ -44,10 +44,18 @@
 	 * <li>The path has to be within the context.</li>
 	 * </ul>
+	 * <strong>If your implementation needs {@link HttpServletRequest} e.g. to get a
+	 * session variable, you can get it by calling {@link ThreadLocalData#getServletRequest()}. </strong>
 	 * 
 	 * @param request
 	 * @return <code>UserFilesPath</code> for the current user.
 	 */
-	public String getUserFilesPath(final HttpServletRequest request);
+	public String getUserFilesPath();
 	
+	/**
+	 * Path needed to map resources to paths outside context of your webapp.
+	 * If the implementation don't bother you, just return <code>null</code>.
+	 * 
+	 * @return
+	 */
 	public String getLocalUserFilesPath();
 }
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/ContextPathBuilder.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/ContextPathBuilder.java	(revision 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/ContextPathBuilder.java	(revision 2584)
@@ -21,7 +21,6 @@
 package net.fckeditor.requestcycle.impl;
 
-import javax.servlet.http.HttpServletRequest;
-
 import net.fckeditor.handlers.ConnectorHandler;
+import net.fckeditor.requestcycle.ThreadLocalData;
 import net.fckeditor.requestcycle.UserPathBuilder;
 
@@ -35,16 +34,13 @@
 public class ContextPathBuilder implements UserPathBuilder {
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see net.fckeditor.requestcycle.UserPathBuilder#getUserFilesPath(javax.servlet.http.HttpServletRequest)
+	/* (non-Javadoc)
+	 * @see net.fckeditor.requestcycle.UserPathBuilder#getUserFilesPath()
 	 */
-	public String getUserFilesPath(final HttpServletRequest request) {
-		return request.getContextPath()
-				+ ConnectorHandler.getDefaultUserFilesPath();
+	public String getUserFilesPath() {
+		String path = ThreadLocalData.getServletRequest().getContextPath().concat(ConnectorHandler.getDefaultUserFilesPath());
+		return path;
 	}
 	
-	/*
-	 * (non-Javadoc)
+	/* (non-Javadoc)
 	 * @see net.fckeditor.requestcycle.UserPathBuilder#getLocalUserFilesPath()
 	 */
@@ -52,4 +48,3 @@
 		return ConnectorHandler.getDefaultUserFilesPath();
 	}
-
 }
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/DisabledUserAction.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/DisabledUserAction.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/DisabledUserAction.java	(revision 2584)
@@ -0,0 +1,57 @@
+/*
+ * 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.requestcycle.impl;
+
+
+import net.fckeditor.requestcycle.UserAction;
+
+/**
+ * Standard implementation for {@link UserAction}. It always returns
+ * <code>false</code>.
+ * 
+ * @version $Id$
+ */
+public class DisabledUserAction implements UserAction {
+
+	/*
+	 * (non-Javadoc)
+	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFileBrowsing()
+	 */
+	public boolean isEnabledForFileBrowsing() {
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFileUpload()
+	 */
+	public boolean isEnabledForFileUpload() {
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFolderCreation()
+	 */
+	public boolean isEnabledForFolderCreation() {
+		return false;
+	}
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/EnabledUserAction.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/EnabledUserAction.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/EnabledUserAction.java	(revision 2584)
@@ -0,0 +1,57 @@
+/*
+ * 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.requestcycle.impl;
+
+
+import net.fckeditor.requestcycle.UserAction;
+
+/**
+ * Standard implementation for {@link UserAction}. It always returns
+ * <code>true</code>.
+ * 
+ * @version $Id$
+ */
+public class EnabledUserAction implements UserAction {
+
+	/*
+	 * (non-Javadoc)
+	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFileBrowsing()
+	 */
+	public boolean isEnabledForFileBrowsing() {
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFileUpload()
+	 */
+	public boolean isEnabledForFileUpload() {
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFolderCreation()
+	 */
+	public boolean isEnabledForFolderCreation() {
+		return true;
+	}
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/FalseUserAction.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/FalseUserAction.java	(revision 2578)
+++ 	(revision )
@@ -1,63 +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.requestcycle.impl;
-
-import javax.servlet.http.HttpServletRequest;
-
-import net.fckeditor.requestcycle.UserAction;
-
-/**
- * Standard implementation for {@link UserAction}. It always returns
- * <code>false</code>.
- * 
- * @version $Id$
- */
-public class FalseUserAction implements UserAction {
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFileBrowsing(javax.servlet.http.HttpServletRequest)
-	 */
-	public boolean isEnabledForFileBrowsing(final HttpServletRequest request) {
-		return false;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFileUpload(javax.servlet.http.HttpServletRequest)
-	 */
-	public boolean isEnabledForFileUpload(final HttpServletRequest request) {
-		return false;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFolderCreation(javax.servlet.http.HttpServletRequest)
-	 */
-	public boolean isEnabledForFolderCreation(final HttpServletRequest request) {
-		return false;
-	}
-	
-	
-
-}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/TrueUserAction.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/TrueUserAction.java	(revision 2578)
+++ 	(revision )
@@ -1,60 +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.requestcycle.impl;
-
-import javax.servlet.http.HttpServletRequest;
-
-import net.fckeditor.requestcycle.UserAction;
-
-/**
- * Standard implementation for {@link UserAction}. It always returns
- * <code>false</code>.
- * 
- * @version $Id$
- */
-public class TrueUserAction implements UserAction {
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFileBrowsing(javax.servlet.http.HttpServletRequest)
-	 */
-	public boolean isEnabledForFileBrowsing(final HttpServletRequest request) {
-		return true;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFileUpload(javax.servlet.http.HttpServletRequest)
-	 */
-	public boolean isEnabledForFileUpload(final HttpServletRequest request) {
-		return true;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFolderCreation(javax.servlet.http.HttpServletRequest)
-	 */
-	public boolean isEnabledForFolderCreation(HttpServletRequest request) {
-		return true;
-	}
-}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/UserActionImpl.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/UserActionImpl.java	(revision 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/requestcycle/impl/UserActionImpl.java	(revision 2584)
@@ -21,5 +21,4 @@
 package net.fckeditor.requestcycle.impl;
 
-import javax.servlet.http.HttpServletRequest;
 
 import net.fckeditor.requestcycle.UserAction;
@@ -29,5 +28,5 @@
  * <code>true</code>.
  * 
- * @see TrueUserAction
+ * @see EnabledUserAction
  * @version $Id$
  */
@@ -38,5 +37,5 @@
 	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFileBrowsing(javax.servlet.http.HttpServletRequest)
 	 */
-	public boolean isEnabledForFileBrowsing(final HttpServletRequest request) {
+	public boolean isEnabledForFileBrowsing() {
 		return true;
 	}
@@ -45,5 +44,5 @@
 	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFileUpload(javax.servlet.http.HttpServletRequest)
 	 */
-	public boolean isEnabledForFileUpload(final HttpServletRequest request) {
+	public boolean isEnabledForFileUpload() {
 		return true;
 	}
@@ -53,5 +52,5 @@
 	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFolderCreation(javax.servlet.http.HttpServletRequest)
 	 */
-	public boolean isEnabledForFolderCreation(HttpServletRequest request) {
+	public boolean isEnabledForFolderCreation() {
 		return true;
 	}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/response/GetResponse.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/response/GetResponse.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/response/GetResponse.java	(revision 2584)
@@ -0,0 +1,285 @@
+/*
+ * 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.response;
+
+import java.io.StringWriter;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import net.fckeditor.connector.Connector;
+import net.fckeditor.handlers.CommandHandler;
+import net.fckeditor.handlers.LocalizedPropertiesLoader;
+import net.fckeditor.handlers.ResourceType;
+import net.fckeditor.requestcycle.ThreadLocalData;
+import net.fckeditor.tool.Utils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Creates an XML response for every <code>GET</code> request of the Connector
+ * servlet. This class maps directly to the XML layout described <a
+ * href="http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Server_Side_Integration#The_Commands">here</a>.
+ *
+ * @version $Id$
+ */
+public class GetResponse {
+
+	private Document document;
+	private Element errorElement;
+	private Element foldersElement;
+	private Element filesElement;
+	
+	/** Error number OK */
+	public static final int EN_OK = 0;
+	
+	/** Error number ERROR */
+	public static final int EN_ERROR = 1;
+
+	/** Error number ALREADY EXISTS */
+	public static final int EN_ALREADY_EXISTS = 101;
+
+	/** Error number INVALID FOLDER NAME */
+	public static final int EN_INVALID_FOLDER_NAME = 102;
+
+	/** Error number SECURITY ERROR */
+	public static final int EN_SECURITY_ERROR = 103;
+
+	/** Error number UNKNOWN ERROR */
+	public static final int EN_UKNOWN = 110;
+	
+
+	/**
+	 * 
+	 * Use this constructor if want to respond a negative/error message with
+	 * custom text.
+	 * 
+	 * @param number
+	 * @param text
+	 */
+	public GetResponse(int number, String text) {
+		try {
+			DocumentBuilderFactory factory = DocumentBuilderFactory
+					.newInstance();
+			DocumentBuilder builder = factory.newDocumentBuilder();
+			document = builder.newDocument();
+		} catch (ParserConfigurationException e) {
+			throw new RuntimeException(e);
+		}
+
+		Element root = document.createElement("Connector");
+		document.appendChild(root);
+		setError(number, text);
+	}
+	
+	/**
+	 * Use this constructor if want to respond a positive message.
+	 * 
+	 * @param command
+	 * @param resourceType
+	 * @param currentFolder
+	 * @param constructedUrl
+	 */
+	public GetResponse(CommandHandler command, ResourceType resourceType, 
+			String currentFolder, String constructedUrl) {
+	
+		try {
+			DocumentBuilderFactory factory = DocumentBuilderFactory
+					.newInstance();
+			DocumentBuilder builder = factory.newDocumentBuilder();
+			document = builder.newDocument();
+		} catch (ParserConfigurationException e) {
+			throw new RuntimeException(e);
+		}
+	
+		Element root = document.createElement("Connector");
+		document.appendChild(root);
+		root.setAttribute("command", command.toString());
+		root.setAttribute("resourceType", resourceType.getName());
+	
+		Element currentFolderElement = document.createElement("CurrentFolder");
+		currentFolderElement.setAttribute("path", currentFolder);
+	
+		currentFolderElement.setAttribute("url", constructedUrl);
+		root.appendChild(currentFolderElement);
+	
+	}
+
+	/**
+	 * Use this constructor if want to respond a negative/error message only.
+	 * 
+	 * @param number
+	 */
+	public GetResponse(int number) {
+		this(number, null);
+	}
+	
+	/**
+	 * Sets an error number with a custom message.
+	 * 
+	 * @param number
+	 * @param text
+	 */
+	public void setError(int number, String text) {
+
+		if (errorElement == null) {
+			errorElement = document.createElement("Error");
+			document.getDocumentElement().appendChild(errorElement);
+		}
+
+		errorElement.setAttribute("number", String.valueOf(number));
+		if (Utils.isNotEmpty(text))
+			errorElement.setAttribute("text", text);
+
+	}
+
+	/**
+	 * Sets an error number.
+	 * 
+	 * @param number
+	 */
+	public void setError(int number) {
+		setError(number, null);
+	}
+
+	/**
+	 * Lists all folders as XML tags.
+	 * @param dir
+	 */
+	public void setFolders(final List<String> dirs) {
+		if (foldersElement != null) {
+			Element parent = (Element) foldersElement.getParentNode();
+			parent.removeChild(foldersElement);
+		}
+
+		foldersElement = document.createElement("Folders");
+		document.getDocumentElement().appendChild(foldersElement);
+
+		for (String file : dirs) {
+			Element folderElement = document.createElement("Folder");
+			folderElement.setAttribute("name", file);
+			foldersElement.appendChild(folderElement);
+		}
+	}
+	
+	/**
+	 * Lists all files XML tags.
+	 * 
+	 * @param Map, key is the file name and value is the size of the file in bytes
+	 */
+	public void setFiles(final List<Map<String, Object>> files) {
+		if (filesElement != null) {
+			Element parent = (Element) filesElement.getParentNode();
+			parent.removeChild(filesElement);
+		}
+
+		filesElement = document.createElement("Files");
+		document.getDocumentElement().appendChild(filesElement);
+		
+		long length = 1L;
+		long tempLength;
+		
+		for (Map<String, Object> file : files) {
+			Element fileElement = document.createElement("File");
+			fileElement.setAttribute("name", (String) file.get(Connector.KEY_NAME));
+			tempLength = (Long) file.get(Connector.KEY_SIZE);
+			if (tempLength > 1024)
+				length = tempLength/1024;
+			fileElement.setAttribute("size", String.valueOf(length));
+			filesElement.appendChild(fileElement);
+		}
+	}
+	
+	@Override
+	public String toString() {
+		document.getDocumentElement().normalize();
+		TransformerFactory factory = TransformerFactory.newInstance();
+
+		StringWriter sw = new StringWriter();
+
+		try {
+			Transformer transformer = factory.newTransformer();
+
+			DOMSource source = new DOMSource(document);
+			StreamResult result = new StreamResult(sw);
+
+			transformer.transform(source, result);
+		} catch (TransformerException e) {
+			throw new RuntimeException(e);
+		}
+
+		return sw.toString();
+	}
+	
+	public static GetResponse getOK() {
+		return new GetResponse(EN_OK);
+	}
+	
+	public static GetResponse getErrorInvalidFolderName() {
+		return new GetResponse(EN_INVALID_FOLDER_NAME);
+	}
+	
+	public static GetResponse getErrorInvalidCommand() {
+		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(ThreadLocalData.getServletRequest());
+		return new GetResponse(EN_ERROR, lpl.getInvalidCommand());
+	}
+	
+	public static GetResponse getErrorInvalidType() {
+		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(ThreadLocalData.getServletRequest());
+		return new GetResponse(EN_ERROR, lpl.getInvalidType());
+	}
+	
+	public static GetResponse getErrorInvalidCurrentFolder() {
+		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(ThreadLocalData.getServletRequest());
+		return new GetResponse(EN_ERROR, lpl.getInvalidCurrentFolder());
+	}
+	
+	public static GetResponse getErrorFolderAlreadyExists() {
+		return new GetResponse(EN_ALREADY_EXISTS);
+	}
+	
+	public static GetResponse getErrorSecurity() {
+		return new GetResponse(EN_SECURITY_ERROR);
+	}
+	
+	public static GetResponse getErrorFileBrowsingDisabled() {
+		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(ThreadLocalData.getServletRequest());
+		return new GetResponse(EN_ERROR, lpl.getFileBrowsingDisabled());
+	}
+
+	public static GetResponse getErrorFolderCreationDisabled() {
+		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(ThreadLocalData.getServletRequest());
+		return new GetResponse(EN_ERROR, lpl.getFolderCreationDisabled());
+	}
+	
+	public static GetResponse getErrorUnknown() {
+		return new GetResponse(EN_UKNOWN);
+	}
+}
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/response/UploadResponse.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/response/UploadResponse.java	(revision 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/response/UploadResponse.java	(revision 2584)
@@ -21,4 +21,6 @@
 package net.fckeditor.response;
 
+import net.fckeditor.handlers.LocalizedPropertiesLoader;
+import net.fckeditor.requestcycle.ThreadLocalData;
 import net.fckeditor.tool.Utils;
 
@@ -38,5 +40,5 @@
  * The UploadResponse constructor behaves the same way by simply calling it
  * with:<br/>
- * <code>UploadResponse ur = new UploadResonse(SC_SOME_ERROR,"/some/url/file.img","file.img","no error"):</code>
+ * <code>UploadResponse ur = new UploadResponse(SC_SOME_ERROR,"/some/url/file.img","file.img","no error"):</code>
  * </p>
  * 
@@ -123,4 +125,32 @@
 		}
 	}
+	
+	public static UploadResponse getErrorSecurity() {
+		return new UploadResponse(SC_SECURITY_ERROR);
+	}
+	
+	public static UploadResponse getErrorInvalidExtension() {
+		return new UploadResponse(SC_INVALID_EXTENSION);
+	}
+	
+	public static UploadResponse getErrorInvalidCommand() {
+		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(ThreadLocalData.getServletRequest());
+		return new UploadResponse(SC_ERROR, null, null, lpl.getInvalidCommand());
+	}
+	
+	public static UploadResponse getErrorInvalidType() {
+		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(ThreadLocalData.getServletRequest());
+		return new UploadResponse(SC_ERROR, null, null, lpl.getInvalidType());
+	}
+	
+	public static UploadResponse getErrorInvalidCurrentFolder() {
+		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(ThreadLocalData.getServletRequest());
+		return new UploadResponse(SC_ERROR, null, null, lpl.getInvalidCurrentFolder());
+	}
+
+	public static UploadResponse getErrorFileUploadDisabled() {
+		LocalizedPropertiesLoader lpl = LocalizedPropertiesLoader.getInstance(ThreadLocalData.getServletRequest());
+		return new UploadResponse(SC_ERROR, null, null, lpl.getFileUploadDisabled());
+	}
 
 	/**
@@ -132,8 +162,6 @@
 		sb.append("<script type=\"text/javascript\">\n");
 		// Compressed version of the document.domain automatic fix script.
-		// The original script can be found at [fckeditor
-		// dir]/_dev/domain_fix_template.js
-		sb
-				.append("(function(){var d=document.domain;while (true){try{var A=window.parent.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();\n");
+		// The original script can be found at [fckeditor_dir]/_dev/domain_fix_template.js
+		sb.append("(function(){var d=document.domain;while (true){try{var A=window.parent.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();\n");
 		sb.append("window.parent.OnUploadCompleted(");
 
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/response/XmlResponse.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/response/XmlResponse.java	(revision 2578)
+++ 	(revision )
@@ -1,253 +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.response;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.StringWriter;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import net.fckeditor.handlers.CommandHandler;
-import net.fckeditor.handlers.ResourceTypeHandler;
-import net.fckeditor.tool.Utils;
-
-import org.apache.commons.io.filefilter.DirectoryFileFilter;
-import org.apache.commons.io.filefilter.FileFileFilter;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * Creates an XML response for every <code>GET</code> request of the Connector
- * servlet. This class maps directly to the XML layout descibed <a
- * href="http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Server_Side_Integration#The_Commands">here</a>.
- * 
- * @version $Id$
- * 
- */
-public class XmlResponse {
-
-	private Document document;
-	private Element errorElement;
-	private Element foldersElement;
-	private Element filesElement;
-	
-	/** Error number OK */
-	public static final int EN_OK = 0;
-	
-	/** Error number ERROR */
-	public static final int EN_ERROR = 1;
-
-	/** Error number ALREADY EXISTS */
-	public static final int EN_ALREADY_EXISTS = 101;
-
-	/** Error number INVALID FOLDER NAME */
-	public static final int EN_INVALID_FOLDER_NAME = 102;
-
-	/** Error number SECURITY ERROR */
-	public static final int EN_SECURITY_ERROR = 103;
-
-	/** Error number UNKNOWN ERROR */
-	public static final int EN_UKNOWN = 110;
-
-	/**
-	 * Use this constructor if want to respond a positive message.
-	 * 
-	 * @param command
-	 * @param resourceType
-	 * @param currentFolder
-	 * @param constructedUrl
-	 */
-	public XmlResponse(CommandHandler command, ResourceTypeHandler resourceType, 
-			String currentFolder, String constructedUrl) {
-
-		try {
-			DocumentBuilderFactory factory = DocumentBuilderFactory
-					.newInstance();
-			DocumentBuilder builder = factory.newDocumentBuilder();
-			document = builder.newDocument();
-		} catch (ParserConfigurationException e) {
-			throw new RuntimeException(e);
-		}
-
-		Element root = document.createElement("Connector");
-		document.appendChild(root);
-		root.setAttribute("command", command.toString());
-		root.setAttribute("resourceType", resourceType.toString());
-
-		Element currentFolderElement = document.createElement("CurrentFolder");
-		currentFolderElement.setAttribute("path", currentFolder);
-
-		currentFolderElement.setAttribute("url", constructedUrl);
-		root.appendChild(currentFolderElement);
-
-	}
-	
-	/**
-	 * 
-	 * Use this constructor if want to respond a negative/error message with
-	 * custom text.
-	 * 
-	 * @param number
-	 * @param text
-	 */
-	public XmlResponse(int number, String text) {
-		try {
-			DocumentBuilderFactory factory = DocumentBuilderFactory
-					.newInstance();
-			DocumentBuilder builder = factory.newDocumentBuilder();
-			document = builder.newDocument();
-		} catch (ParserConfigurationException e) {
-			throw new RuntimeException(e);
-		}
-
-		Element root = document.createElement("Connector");
-		document.appendChild(root);
-		setError(number, text);
-	}
-	
-	/**
-	 * Use this constructor if want to respond a negative/error message only.
-	 * 
-	 * @param number
-	 */
-	public XmlResponse(int number) {
-		this(number, null);
-	}
-
-	/**
-	 * Sets an error number with a custom message.
-	 * 
-	 * @param number
-	 * @param text
-	 */
-	public void setError(int number, String text) {
-
-		if (errorElement == null) {
-			errorElement = document.createElement("Error");
-			document.getDocumentElement().appendChild(errorElement);
-		}
-
-		errorElement.setAttribute("number", String.valueOf(number));
-		if (Utils.isNotEmpty(text))
-			errorElement.setAttribute("text", text);
-
-	}
-
-	/**
-	 * Sets an error number.
-	 * 
-	 * @param number
-	 */
-	public void setError(int number) {
-		setError(number, null);
-	}
-
-	/**
-	 * Lists all folders in the given dir as XML tags.
-	 * @param dir
-	 */
-	public void setFolders(File dir) {
-
-		if (foldersElement != null) {
-			Element parent = (Element) foldersElement.getParentNode();
-			parent.removeChild(foldersElement);
-		}
-
-		foldersElement = document.createElement("Folders");
-		document.getDocumentElement().appendChild(foldersElement);
-
-		String[] fileList = dir.list(DirectoryFileFilter.DIRECTORY);
-		for (String file : fileList) {
-			Element folderElement = document.createElement("Folder");
-			folderElement.setAttribute("name", file);
-			foldersElement.appendChild(folderElement);
-		}
-	}
-	
-	/**
-	 * Lists all files in the given dir as XML tags.
-	 * 
-	 * @param dir
-	 */
-	public void setFiles(File dir) {
-		
-		if (filesElement != null) {
-			Element parent = (Element) filesElement.getParentNode();
-			parent.removeChild(filesElement);
-		}
-
-		filesElement = document.createElement("Files");
-		document.getDocumentElement().appendChild(filesElement);
-		
-		File[] fileList = dir.listFiles((FileFilter) FileFileFilter.FILE);
-		long length;
-		for (File file : fileList) {
-			Element fileElement = document.createElement("File");
-			fileElement.setAttribute("name", file.getName());
-			if (file.length() < 1024)
-				length = 1L;
-			else 
-				length = file.length()/1024;
-			fileElement.setAttribute("size", String.valueOf(length));
-			filesElement.appendChild(fileElement);
-		}
-	}
-	
-	/**
-	 * Lists all folders and files in the given dir as XML tags.
-	 * 
-	 * @param dir
-	 */	
-	public void setFoldersAndFiles(File dir) {
-		setFolders(dir);
-		setFiles(dir);
-	}
-	
-	@Override
-	public String toString() {
-		document.getDocumentElement().normalize();
-		TransformerFactory factory = TransformerFactory.newInstance();
-
-		StringWriter sw = new StringWriter();
-
-		try {
-			Transformer transformer = factory.newTransformer();
-
-			DOMSource source = new DOMSource(document);
-			StreamResult result = new StreamResult(sw);
-
-			transformer.transform(source, result);
-		} catch (TransformerException e) {
-			throw new RuntimeException(e);
-		}
-
-		return sw.toString();
-	}
-
-}
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 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/tags/CheckTag.java	(revision 2584)
@@ -82,5 +82,5 @@
 
 		if (command.equals(FILE_UPLOAD)) {
-			if (RequestCycleHandler.isEnabledForFileUpload(request))
+			if (RequestCycleHandler.isEnabledForFileUpload())
 				response = lpl.getFileUploadEnabled();
 			else
@@ -89,5 +89,5 @@
 
 		if (command.equals(FILE_BROWSING)) {
-			if (RequestCycleHandler.isEnabledForFileBrowsing(request))
+			if (RequestCycleHandler.isEnabledForFileBrowsing())
 				response = lpl.getFileBrowsingEnabled();
 			else
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/tool/UtilsFile.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/tool/UtilsFile.java	(revision 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/tool/UtilsFile.java	(revision 2584)
@@ -24,5 +24,5 @@
 import java.io.InputStream;
 
-import javax.servlet.http.HttpServletRequest;
+import net.fckeditor.handlers.ConnectorHandler;
 
 import org.apache.commons.io.FilenameUtils;
@@ -30,8 +30,4 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import net.fckeditor.handlers.ConnectorHandler;
-import net.fckeditor.handlers.RequestCycleHandler;
-import net.fckeditor.handlers.ResourceTypeHandler;
 
 /**
@@ -149,19 +145,19 @@
 		}
 	}
-	
-	/**
-	 * Compose server-side response path.
-	 * 
-	 * @param request
-	 * @param resourceType
-	 * @return server-side path of <code>resourceType</code>.
-	 */
-	public static String constructServerSidePath(HttpServletRequest request,
-			ResourceTypeHandler resourceType) {
-		StringBuffer sb = new StringBuffer(RequestCycleHandler.getLocalUserFilePath());
-		sb.append(resourceType.getPath());
 
-		return sb.toString();
+	public static File getUniqueFile(final File file) {
+		if (!file.exists())
+			return file;
+		
+		File tmpFile = new File(file.getAbsolutePath());
+		File dir = tmpFile.getParentFile();
+		int count = 1;
+		String extension = FilenameUtils.getExtension(tmpFile.getName());
+		String baseName = FilenameUtils.getBaseName(tmpFile.getName());
+		do {
+			tmpFile = new File(dir, baseName + "(".concat(String.valueOf(count)).concat(").").concat(extension));
+			count++;
+		} while (tmpFile.exists());
+		return tmpFile;
 	}
-
 }
Index: FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/tool/UtilsResponse.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/tool/UtilsResponse.java	(revision 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/java/net/fckeditor/tool/UtilsResponse.java	(revision 2584)
@@ -24,5 +24,5 @@
 
 import net.fckeditor.handlers.ConnectorHandler;
-import net.fckeditor.handlers.ResourceTypeHandler;
+import net.fckeditor.requestcycle.ThreadLocalData;
 
 /**
@@ -36,30 +36,22 @@
 	 * Constructs a URL from different parameters. This method is about to
 	 * change in version 2.5.
-	 * 
-	 * @param request
-	 * @param resourceType
-	 * @param urlPath
-	 * @param fullUrl
-	 * @return constructed url
+	 * TODO has to be improved
 	 */
-    public static String constructResponseUrl(HttpServletRequest request,
-    		ResourceTypeHandler resourceType, String urlPath,
-    		boolean fullUrl) {
-    		
-    	StringBuffer sb = new StringBuffer();
-    	
-    	if (fullUrl) {
-    		String address = request.getRequestURL().toString();
-    		sb.append(address.substring(0, address.indexOf('/', 8)));
-    	}
-    	    	
-    	sb.append(ConnectorHandler.getUserFilesPath(request));
-    	sb.append(resourceType.getPath());
-    	
-    	if (Utils.isNotEmpty(urlPath))
-    		sb.append(urlPath);
-    	
-    	return sb.toString();
-    }
+	public static String constructResponseUrl(String filePath, String resourceTypePath, String urlPath) {
+		StringBuffer sb = new StringBuffer();
+		
+		if (Utils.isNotEmpty(ConnectorHandler.getBaseUrl())) {
+			sb.append(ConnectorHandler.getBaseUrl());
+		}
+		    	
+		sb.append(filePath);
+		if (Utils.isNotEmpty(resourceTypePath))
+			sb.append(resourceTypePath);
+		
+		if (Utils.isNotEmpty(urlPath))
+			sb.append(urlPath);
+		
+		return sb.toString();
+	}
 
 }
Index: FCKeditor.Java/trunk/java-core/src/main/resources/net/fckeditor/handlers/default.properties
===================================================================
--- FCKeditor.Java/trunk/java-core/src/main/resources/net/fckeditor/handlers/default.properties	(revision 2578)
+++ FCKeditor.Java/trunk/java-core/src/main/resources/net/fckeditor/handlers/default.properties	(revision 2584)
@@ -62,5 +62,5 @@
 
 # default implementations
-connector.userActionImpl = net.fckeditor.requestcycle.impl.FalseUserAction
+connector.userActionImpl = net.fckeditor.requestcycle.impl.DisabledUserAction
 connector.userPathBuilderImpl = net.fckeditor.requestcycle.impl.ContextPathBuilder
 localization.localeResolverImpl = net.fckeditor.localization.impl.AcceptLanguageHeaderResolver
Index: FCKeditor.Java/trunk/java-core/src/test/java/net/fckeditor/handlers/ExtensionsHandlerTest.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/test/java/net/fckeditor/handlers/ExtensionsHandlerTest.java	(revision 2578)
+++ FCKeditor.Java/trunk/java-core/src/test/java/net/fckeditor/handlers/ExtensionsHandlerTest.java	(revision 2584)
@@ -35,5 +35,5 @@
 	@Test
 	public void testIsAllowed01() {
-		ResourceTypeHandler type = ResourceTypeHandler.FILE;
+		ResourceType type = ResourceType.FILE;
 		ExtensionsHandler.setExtensionsAllowed(type, "a");
 		ExtensionsHandler.setExtensionsDenied(type, "b");
@@ -47,5 +47,5 @@
 	@Test
 	public void testIsAllowed02() {
-		ResourceTypeHandler type = ResourceTypeHandler.FILE;
+		ResourceType type = ResourceType.FILE;
 		ExtensionsHandler.setExtensionsAllowed(type, "a|b|c");
 		assertTrue(ExtensionsHandler.isAllowed(type, "a"));
Index: FCKeditor.Java/trunk/java-core/src/test/java/net/fckeditor/handlers/ResourceTypeHandlerTest.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/test/java/net/fckeditor/handlers/ResourceTypeHandlerTest.java	(revision 2578)
+++ 	(revision )
@@ -1,89 +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 static org.junit.Assert.*;
-import net.fckeditor.handlers.PropertiesLoader;
-import net.fckeditor.handlers.ResourceTypeHandler;
-
-import org.junit.Test;
-
-/**
- * Tests for {@link ResourceTypeHandler}.
- * 
- * @version $Id: ResourceTypeHandlerTest.java 1585 2008-02-21 18:13:09Z th-schwarz $
- */
-public class ResourceTypeHandlerTest {
-
-	@Test
-	public void getType01() throws Exception {
-		assertNull(ResourceTypeHandler.getResourceType("xyz"));
-	}
-
-	@Test
-	public void getType02() throws Exception {
-		assertEquals(ResourceTypeHandler.FILE, ResourceTypeHandler.getResourceType("File"));
-	}
-
-	@Test
-	public void getType03() throws Exception {
-		assertEquals(ResourceTypeHandler.IMAGE, ResourceTypeHandler.getResourceType("Image"));
-	}
-
-	@Test
-	public void isValid01() throws Exception {
-		assertFalse(ResourceTypeHandler.isValid("1234"));
-	}
-
-	@Test
-	public void isValid02() throws Exception {
-		assertFalse(ResourceTypeHandler.isValid("fLash"));
-	}
-
-	@Test
-	public void isValid03() throws Exception {
-		assertFalse(ResourceTypeHandler.isValid("MeDiA"));
-	}
-
-	@Test
-	public void getTypeDefault01() throws Exception {
-		assertEquals(ResourceTypeHandler.FILE, ResourceTypeHandler
-				.getDefaultResourceType("wrong-type"));
-	}
-
-	@Test
-	public void getTypeDefault02() throws Exception {
-		assertNotSame(ResourceTypeHandler.FLASH, ResourceTypeHandler
-				.getDefaultResourceType("flAsh"));
-	}
-
-	@Test
-	public void getSubDirForType01() throws Exception {
-		assertEquals(PropertiesLoader.getProperty("connector.resourceType.file.path"), 
-				ResourceTypeHandler.getDefaultResourceType(null).getPath());
-	}
-
-	@Test
-	public void getSubDirForType02() throws Exception {
-		assertEquals(PropertiesLoader.getProperty("connector.resourceType.image.path"), 
-				ResourceTypeHandler.getResourceType("Image").getPath());
-	}
-}
Index: FCKeditor.Java/trunk/java-core/src/test/java/net/fckeditor/handlers/ResourceTypeTest.java
===================================================================
--- FCKeditor.Java/trunk/java-core/src/test/java/net/fckeditor/handlers/ResourceTypeTest.java	(revision 2584)
+++ FCKeditor.Java/trunk/java-core/src/test/java/net/fckeditor/handlers/ResourceTypeTest.java	(revision 2584)
@@ -0,0 +1,77 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link ResourceTypeHandler}.
+ * 
+ * @version $Id: ResourceTypeTest.java 1585 2008-02-21 18:13:09Z th-schwarz $
+ */
+public class ResourceTypeTest {
+
+	@Test
+	public void getType01() throws Exception {
+		assertNull(ResourceType.getResourceType("xyz"));
+	}
+
+	@Test
+	public void getType02() throws Exception {
+		assertEquals(ResourceType.FILE, ResourceType.getResourceType("File"));
+	}
+
+	@Test
+	public void getType03() throws Exception {
+		assertEquals(ResourceType.IMAGE, ResourceType.getResourceType("ImaGe"));
+	}
+	@Test
+	public void isValid01() throws Exception {
+		assertFalse(ResourceType.isValid("1234"));
+	}
+
+	@Test
+	public void isValid02() throws Exception {
+		assertTrue(ResourceType.isValid("fLash"));
+	}
+
+	@Test
+	public void isValid03() throws Exception {
+		assertTrue(ResourceType.isValid("MeDiA"));
+	}
+
+	@Test
+	public void getTypeDefault01() throws Exception {
+		assertEquals(ResourceType.FILE, ResourceType
+				.getDefaultResourceType("wrong-type"));
+	}
+
+	@Test
+	public void getTypeDefault02() throws Exception {
+		assertEquals(ResourceType.FLASH, ResourceType
+				.getDefaultResourceType("flAsh"));
+	}
+}
Index: FCKeditor.Java/trunk/java-demo/src/main/resources/fckeditor.properties
===================================================================
--- FCKeditor.Java/trunk/java-demo/src/main/resources/fckeditor.properties	(revision 2578)
+++ FCKeditor.Java/trunk/java-demo/src/main/resources/fckeditor.properties	(revision 2584)
@@ -1,1 +1,2 @@
-connector.userActionImpl=net.fckeditor.requestcycle.impl.UserActionImpl
+connector.userActionImpl=net.fckeditor.requestcycle.impl.EnabledUserAction
+connector.implementation=net.fckeditor.connector.impl.SimpleFileSystemConnector
