diff --git a/src/java/org/apache/fulcrum/upload/DefaultUploadService.java b/src/java/org/apache/fulcrum/upload/DefaultUploadService.java
index f8b0b39..af5a9c0 100644
--- a/src/java/org/apache/fulcrum/upload/DefaultUploadService.java
+++ b/src/java/org/apache/fulcrum/upload/DefaultUploadService.java
@@ -1,6 +1,5 @@
 package org.apache.fulcrum.upload;
 
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -20,7 +19,6 @@
  * under the License.
  */
 
-
 import java.io.File;
 import java.io.IOException;
 import java.util.List;
@@ -44,409 +42,366 @@
 import org.apache.commons.fileupload.servlet.ServletFileUpload;
 
 /**
- * <p> This class is an implementation of {@link UploadService}.
+ * <p>
+ * This class is an implementation of {@link UploadService}.
  *
- * <p> Files will be stored in temporary disk storage on in memory,
- * depending on request size, and will be available from the {@link
- * org.apache.fulcrum.util.parser.ParameterParser} as {@link
- * org.apache.commons.fileupload.FileItem} objects.
+ * <p>
+ * Files will be stored in temporary disk storage on in memory, depending on
+ * request size, and will be available from the
+ * <code>org.apache.fulcrum.util.parser.ParameterParser</code> as
+ * <code>org.apache.commons.fileupload.FileItem</code> objects.
  *
- * <p>This implementation of {@link UploadService} handles multiple
- * files per single html form, sent using multipart/form-data encoding
- * type, as specified by RFC 1867.  Use {@link
- * org.apache.fulcrum.parser.ParameterParser#getFileItems(String)} to
- * acquire an array of {@link
- * org.apache.commons.fileupload.FileItem} objects associated with given
- * html form.
+ * <p>
+ * This implementation of {@link UploadService} handles multiple files per
+ * single html form, sent using multipart/form-data encoding type, as specified
+ * by RFC 1867. Use
+ * <code>org.apache.fulcrum.parser.ParameterParser#getFileItems(String)</code> to
+ * acquire an array of <code>org.apache.commons.fileupload.FileItem</code> objects
+ * associated with given html form.
  *
  * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
  * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
  * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
  * @version $Id$
  */
-public class DefaultUploadService
-    extends AbstractLogEnabled
-    implements UploadService, Initializable, Configurable, Contextualizable
-{
-    /** A File Item Factory object for the actual uploading */
-    private DiskFileItemFactory itemFactory;
+public class DefaultUploadService extends AbstractLogEnabled
+		implements UploadService, Initializable, Configurable, Contextualizable {
+	/** A File Item Factory object for the actual uploading */
+	private DiskFileItemFactory itemFactory;
 
-    private int sizeThreshold;
-    private int sizeMax;
+	private int sizeThreshold;
+	private int sizeMax;
 
-    private String repositoryPath;
-    private String headerEncoding;
+	private String repositoryPath;
+	private String headerEncoding;
 
-    /**
-     * The application root
-     */
-    private String applicationRoot;
+	/**
+	 * The application root
+	 */
+	private String applicationRoot;
 
-    /**
-     * The maximum allowed upload size
-     */
-    @Override
-	public long getSizeMax()
-    {
-        return sizeMax;
-    }
+	/**
+	 * The maximum allowed upload size
+	 */
+	@Override
+	public long getSizeMax() {
+		return sizeMax;
+	}
 
-    /**
-     * The threshold beyond which files are written directly to disk.
-     */
-    @Override
-	public long getSizeThreshold()
-    {
-        return itemFactory.getSizeThreshold();
-    }
+	/**
+	 * The threshold beyond which files are written directly to disk.
+	 */
+	@Override
+	public long getSizeThreshold() {
+		return itemFactory.getSizeThreshold();
+	}
 
-    /**
-     * The location used to temporarily store files that are larger
-     * than the size threshold.
-     */
-    @Override
-	public String getRepository()
-    {
-        return itemFactory.getRepository().getAbsolutePath();
-    }
+	/**
+	 * The location used to temporarily store files that are larger than the size
+	 * threshold.
+	 */
+	@Override
+	public String getRepository() {
+		return itemFactory.getRepository().getAbsolutePath();
+	}
 
-    /**
-     * @return Returns the headerEncoding.
-     */
-    @Override
-	public String getHeaderEncoding()
-    {
-        return headerEncoding;
-    }
+	/**
+	 * @return Returns the headerEncoding.
+	 */
+	@Override
+	public String getHeaderEncoding() {
+		return headerEncoding;
+	}
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The servlet request to be parsed.
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    @Override
-	public List<FileItem> parseRequest(HttpServletRequest req)
-        throws ServiceException
-    {
-        return parseRequest(req, this.sizeMax, this.itemFactory);
-    }
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req The servlet request to be parsed.
+	 * @throws ServiceException Problems reading/parsing the request or storing the
+	 *                          uploaded file(s).
+	 */
+	@Override
+	public List<FileItem> parseRequest(HttpServletRequest req) throws ServiceException {
+		return parseRequest(req, this.sizeMax, this.itemFactory);
+	}
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The servlet request to be parsed.
-     * @param path The location where the files should be stored.
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    @Override
-	public List<FileItem> parseRequest(HttpServletRequest req, String path)
-        throws ServiceException
-    {
-        return parseRequest(req, this.sizeThreshold, this.sizeMax, path);
-    }
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req  The servlet request to be parsed.
+	 * @param path The location where the files should be stored.
+	 * @throws ServiceException Problems reading/parsing the request or storing the
+	 *                          uploaded file(s).
+	 */
+	@Override
+	public List<FileItem> parseRequest(HttpServletRequest req, String path) throws ServiceException {
+		return parseRequest(req, this.sizeThreshold, this.sizeMax, path);
+	}
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The servlet request to be parsed.
-     * @param sizeThreshold the max size in bytes to be stored in memory
-     * @param sizeMax the maximum allowed upload size in bytes
-     * @param path The location where the files should be stored.
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    @Override
-	public List<FileItem> parseRequest(HttpServletRequest req, int sizeThreshold,
-                                  int sizeMax, String path)
-            throws ServiceException
-    {
-        return parseRequest(req, sizeMax, new DiskFileItemFactory(sizeThreshold, new File(path)));
-    }
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req           The servlet request to be parsed.
+	 * @param sizeThreshold the max size in bytes to be stored in memory
+	 * @param sizeMax       the maximum allowed upload size in bytes
+	 * @param path          The location where the files should be stored.
+	 * @return list of file items
+	 * @throws ServiceException Problems reading/parsing the request or storing the
+	 *                          uploaded file(s).
+	 */
+	@Override
+	public List<FileItem> parseRequest(HttpServletRequest req, int sizeThreshold, int sizeMax, String path)
+			throws ServiceException {
+		return parseRequest(req, sizeMax, new DiskFileItemFactory(sizeThreshold, new File(path)));
+	}
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The servlet request to be parsed.
-     * @param sizeMax the maximum allowed upload size in bytes
-     * @param factory the file item factory to use
-     *
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    protected List<FileItem> parseRequest(HttpServletRequest req, int sizeMax, DiskFileItemFactory factory)
-            throws ServiceException
-    {
-        try
-        {
-            ServletFileUpload fileUpload = new ServletFileUpload(factory);
-            fileUpload.setSizeMax(sizeMax);
-            fileUpload.setHeaderEncoding(headerEncoding);
-            return fileUpload.parseRequest(req);
-        }
-        catch (FileUploadException e)
-        {
-            throw new ServiceException(UploadService.ROLE, e.getMessage(), e);
-        }
-    }
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req     The servlet request to be parsed.
+	 * @param sizeMax the maximum allowed upload size in bytes
+	 * @param factory the file item factory to use
+	 * @return list of file items
+	 * @throws ServiceException Problems reading/parsing the request or storing the
+	 *                          uploaded file(s).
+	 */
+	protected List<FileItem> parseRequest(HttpServletRequest req, int sizeMax, DiskFileItemFactory factory)
+			throws ServiceException {
+		try {
+			ServletFileUpload fileUpload = new ServletFileUpload(factory);
+			fileUpload.setSizeMax(sizeMax);
+			fileUpload.setHeaderEncoding(headerEncoding);
+			return fileUpload.parseRequest(req);
+		} catch (FileUploadException e) {
+			throw new ServiceException(UploadService.ROLE, e.getMessage(), e);
+		}
+	}
 
-    /**
-     * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.
-     *
-     * @param req The servlet request to be parsed.
-     *
-     * @return An iterator to instances of <code>FileItemStream</code>
-     *         parsed from the request, in the order that they were
-     *         transmitted.
-     *
-     * @throws ServiceException if there are problems reading/parsing
-     *                             the request or storing files. This
-     *                             may also be a network error while
-     *                             communicating with the client or a
-     *                             problem while storing the uploaded
-     *                             content.
-     */
-    @Override
-	public FileItemIterator getItemIterator(HttpServletRequest req) throws ServiceException
-    {
-        ServletFileUpload upload = new ServletFileUpload();
-        try
-        {
-            return upload.getItemIterator(req);
-        }
-        catch (FileUploadException e)
-        {
-            throw new ServiceException(UploadService.ROLE, e.getMessage(), e);
-        }
-        catch (IOException e)
-        {
-            throw new ServiceException(UploadService.ROLE, e.getMessage(), e);
-        }
-    }
+	/**
+	 * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
+	 * compliant <code>multipart/form-data</code> stream.
+	 *
+	 * @param req The servlet request to be parsed.
+	 *
+	 * @return An iterator to instances of <code>FileItemStream</code> parsed from
+	 *         the request, in the order that they were transmitted.
+	 *
+	 * @throws ServiceException if there are problems reading/parsing the request or
+	 *                          storing files. This may also be a network error
+	 *                          while communicating with the client or a problem
+	 *                          while storing the uploaded content.
+	 */
+	@Override
+	public FileItemIterator getItemIterator(HttpServletRequest req) throws ServiceException {
+		ServletFileUpload upload = new ServletFileUpload();
+		try {
+			return upload.getItemIterator(req);
+		} catch (FileUploadException e) {
+			throw new ServiceException(UploadService.ROLE, e.getMessage(), e);
+		} catch (IOException e) {
+			throw new ServiceException(UploadService.ROLE, e.getMessage(), e);
+		}
+	}
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The portlet request to be parsed.
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    @Override
-	public List<FileItem> parseRequest(ActionRequest req)
-        throws ServiceException
-    {
-        return parseRequest(req, this.sizeMax, this.itemFactory);
-    }
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req The portlet request to be parsed.
+	 * @throws ServiceException Problems reading/parsing the request or storing the
+	 *                          uploaded file(s).
+	 */
+	@Override
+	public List<FileItem> parseRequest(ActionRequest req) throws ServiceException {
+		return parseRequest(req, this.sizeMax, this.itemFactory);
+	}
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The portlet request to be parsed.
-     * @param path The location where the files should be stored.
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    @Override
-	public List<FileItem> parseRequest(ActionRequest req, String path)
-        throws ServiceException
-    {
-        return parseRequest(req, this.sizeThreshold, this.sizeMax, path);
-    }
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req  The portlet request to be parsed.
+	 * @param path The location where the files should be stored.
+	 * @throws ServiceException Problems reading/parsing the request or storing the
+	 *                          uploaded file(s).
+	 */
+	@Override
+	public List<FileItem> parseRequest(ActionRequest req, String path) throws ServiceException {
+		return parseRequest(req, this.sizeThreshold, this.sizeMax, path);
+	}
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The portlet request to be parsed.
-     * @param sizeThreshold the max size in bytes to be stored in memory
-     * @param sizeMax the maximum allowed upload size in bytes
-     * @param path The location where the files should be stored.
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    @Override
-	public List<FileItem> parseRequest(ActionRequest req, int sizeThreshold,
-                                  int sizeMax, String path)
-            throws ServiceException
-    {
-        return parseRequest(req, sizeMax, new DiskFileItemFactory(sizeThreshold, new File(path)));
-    }
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req           The portlet request to be parsed.
+	 * @param sizeThreshold the max size in bytes to be stored in memory
+	 * @param sizeMax       the maximum allowed upload size in bytes
+	 * @param path          The location where the files should be stored.
+	 * @throws ServiceException Problems reading/parsing the request or storing the
+	 *                          uploaded file(s).
+	 */
+	@Override
+	public List<FileItem> parseRequest(ActionRequest req, int sizeThreshold, int sizeMax, String path)
+			throws ServiceException {
+		return parseRequest(req, sizeMax, new DiskFileItemFactory(sizeThreshold, new File(path)));
+	}
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The portlet request to be parsed.
-     * @param sizeMax the maximum allowed upload size in bytes
-     * @param factory the file item factory to use
-     *
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    protected List<FileItem> parseRequest(ActionRequest req, int sizeMax, DiskFileItemFactory factory)
-            throws ServiceException
-    {
-        try
-        {
-            PortletFileUpload fileUpload = new PortletFileUpload(factory);
-            fileUpload.setSizeMax(sizeMax);
-            fileUpload.setHeaderEncoding(headerEncoding);
-            return fileUpload.parseRequest(req);
-        }
-        catch (FileUploadException e)
-        {
-            throw new ServiceException(UploadService.ROLE, e.getMessage(), e);
-        }
-    }
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req     The portlet request to be parsed.
+	 * @param sizeMax the maximum allowed upload size in bytes
+	 * @param factory the file item factory to use
+	 * @return The list of FileItem parts uploaded
+	 * @throws ServiceException Problems reading/parsing the request or storing the
+	 *                          uploaded file(s).
+	 */
+	protected List<FileItem> parseRequest(ActionRequest req, int sizeMax, DiskFileItemFactory factory)
+			throws ServiceException {
+		try {
+			PortletFileUpload fileUpload = new PortletFileUpload(factory);
+			fileUpload.setSizeMax(sizeMax);
+			fileUpload.setHeaderEncoding(headerEncoding);
+			return fileUpload.parseRequest(req);
+		} catch (FileUploadException e) {
+			throw new ServiceException(UploadService.ROLE, e.getMessage(), e);
+		}
+	}
 
-    /**
-     * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.
-     *
-     * @param req The portlet request to be parsed.
-     *
-     * @return An iterator to instances of <code>FileItemStream</code>
-     *         parsed from the request, in the order that they were
-     *         transmitted.
-     *
-     * @throws ServiceException if there are problems reading/parsing
-     *                             the request or storing files. This
-     *                             may also be a network error while
-     *                             communicating with the client or a
-     *                             problem while storing the uploaded
-     *                             content.
-     */
-    @Override
-	public FileItemIterator getItemIterator(ActionRequest req) throws ServiceException
-    {
-        PortletFileUpload upload = new PortletFileUpload();
-        try
-        {
-            return upload.getItemIterator(req);
-        }
-        catch (FileUploadException e)
-        {
-            throw new ServiceException(UploadService.ROLE, e.getMessage(), e);
-        }
-        catch (IOException e)
-        {
-            throw new ServiceException(UploadService.ROLE, e.getMessage(), e);
-        }
-    }
+	/**
+	 * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
+	 * compliant <code>multipart/form-data</code> stream.
+	 *
+	 * @param req The portlet request to be parsed.
+	 *
+	 * @return An iterator to instances of <code>FileItemStream</code> parsed from
+	 *         the request, in the order that they were transmitted.
+	 *
+	 * @throws ServiceException if there are problems reading/parsing the request or
+	 *                          storing files. This may also be a network error
+	 *                          while communicating with the client or a problem
+	 *                          while storing the uploaded content.
+	 */
+	@Override
+	public FileItemIterator getItemIterator(ActionRequest req) throws ServiceException {
+		PortletFileUpload upload = new PortletFileUpload();
+		try {
+			return upload.getItemIterator(req);
+		} catch (FileUploadException e) {
+			throw new ServiceException(UploadService.ROLE, e.getMessage(), e);
+		} catch (IOException e) {
+			throw new ServiceException(UploadService.ROLE, e.getMessage(), e);
+		}
+	}
 
-    /**
-     * Utility method that determines whether the request contains multipart
-     * content.
-     *
-     * @param req The servlet request to be evaluated. Must be non-null.
-     *
-     * @return <code>true</code> if the request is multipart;
-     *         <code>false</code> otherwise.
-     */
-    @Override
-	public boolean isMultipart(HttpServletRequest req)
-    {
-        return ServletFileUpload.isMultipartContent(req);
-    }
+	/**
+	 * Utility method that determines whether the request contains multipart
+	 * content.
+	 *
+	 * @param req The servlet request to be evaluated. Must be non-null.
+	 *
+	 * @return <code>true</code> if the request is multipart; <code>false</code>
+	 *         otherwise.
+	 */
+	@Override
+	public boolean isMultipart(HttpServletRequest req) {
+		return ServletFileUpload.isMultipartContent(req);
+	}
 
-    /**
-     * Utility method that determines whether the request contains multipart
-     * content.
-     *
-     * @param req The portlet request to be evaluated. Must be non-null.
-     *
-     * @return <code>true</code> if the request is multipart;
-     *         <code>false</code> otherwise.
-     */
-    @Override
-	public boolean isMultipart(ActionRequest req)
-    {
-        return PortletFileUpload.isMultipartContent(req);
-    }
+	/**
+	 * Utility method that determines whether the request contains multipart
+	 * content.
+	 *
+	 * @param req The portlet request to be evaluated. Must be non-null.
+	 *
+	 * @return <code>true</code> if the request is multipart; <code>false</code>
+	 *         otherwise.
+	 */
+	@Override
+	public boolean isMultipart(ActionRequest req) {
+		return PortletFileUpload.isMultipartContent(req);
+	}
 
-    /**
-     * @see org.apache.fulcrum.ServiceBroker#getRealPath(String)
-     */
-    private String getRealPath(String path)
-    {
-        String absolutePath = null;
-        if (applicationRoot == null)
-        {
-            absolutePath = new File(path).getAbsolutePath();
-        }
-        else
-        {
-            absolutePath = new File(applicationRoot, path).getAbsolutePath();
-        }
+	/**
+	 * @see org.apache.fulcrum.ServiceBroker#getRealPath(String)
+	 */
+	private String getRealPath(String path) {
+		String absolutePath = null;
+		if (applicationRoot == null) {
+			absolutePath = new File(path).getAbsolutePath();
+		} else {
+			absolutePath = new File(applicationRoot, path).getAbsolutePath();
+		}
 
-        return absolutePath;
-    }
+		return absolutePath;
+	}
 
-    // ---------------- Avalon Lifecycle Methods ---------------------
-    /**
-     * Avalon component lifecycle method
-     */
-    @Override
-	public void configure(Configuration conf)
-    {
-        repositoryPath = conf.getAttribute(
-                UploadService.REPOSITORY_KEY,
-                UploadService.REPOSITORY_DEFAULT);
+	// ---------------- Avalon Lifecycle Methods ---------------------
+	/**
+	 * Avalon component lifecycle method
+	 */
+	@Override
+	public void configure(Configuration conf) {
+		repositoryPath = conf.getAttribute(UploadService.REPOSITORY_KEY, UploadService.REPOSITORY_DEFAULT);
 
-        headerEncoding = conf.getAttribute(
-                UploadService.HEADER_ENCODING_KEY,
-                UploadService.HEADER_ENCODING_DEFAULT);
+		headerEncoding = conf.getAttribute(UploadService.HEADER_ENCODING_KEY, UploadService.HEADER_ENCODING_DEFAULT);
 
-        sizeMax = conf.getAttributeAsInteger(
-                UploadService.SIZE_MAX_KEY,
-                UploadService.SIZE_MAX_DEFAULT);
+		sizeMax = conf.getAttributeAsInteger(UploadService.SIZE_MAX_KEY, UploadService.SIZE_MAX_DEFAULT);
 
-        sizeThreshold = conf.getAttributeAsInteger(
-                UploadService.SIZE_THRESHOLD_KEY,
-                UploadService.SIZE_THRESHOLD_DEFAULT);
-    }
+		sizeThreshold = conf.getAttributeAsInteger(UploadService.SIZE_THRESHOLD_KEY,
+				UploadService.SIZE_THRESHOLD_DEFAULT);
+	}
 
-    /**
-     * Avalon component lifecycle method
-     *
-     * Initializes the service.
-     *
-     * This method processes the repository path, to make it relative to the
-     * web application root, if necessary
-     */
-    @Override
-	public void initialize() throws Exception
-    {
-        // test for the existence of the path within the webapp directory.
-        // if it does not exist, assume the path was to be used as is.
-        String testPath = getRealPath(repositoryPath);
-        File testDir = new File(testPath);
-        if ( testDir.exists() )
-        {
-            repositoryPath = testPath;
-        }
+	/**
+	 * Avalon component lifecycle method
+	 *
+	 * Initializes the service.
+	 *
+	 * This method processes the repository path, to make it relative to the web
+	 * application root, if necessary
+	 */
+	@Override
+	public void initialize() throws Exception {
+		// test for the existence of the path within the webapp directory.
+		// if it does not exist, assume the path was to be used as is.
+		String testPath = getRealPath(repositoryPath);
+		File testDir = new File(testPath);
+		if (testDir.exists()) {
+			repositoryPath = testPath;
+		}
 
-        getLogger().debug(
-                "Upload Service: REPOSITORY_KEY => " + repositoryPath);
+		getLogger().debug("Upload Service: REPOSITORY_KEY => " + repositoryPath);
 
-        itemFactory = new DiskFileItemFactory(sizeThreshold, new File(repositoryPath));
-    }
+		itemFactory = new DiskFileItemFactory(sizeThreshold, new File(repositoryPath));
+	}
 
-    /**
-     * Avalon component lifecycle method
-     */
-    @Override
-	public void contextualize(Context context) throws ContextException
-    {
-        this.applicationRoot = context.get( "urn:avalon:home" ).toString();
-    }
+	/**
+	 * Avalon component lifecycle method
+	 */
+	@Override
+	public void contextualize(Context context) throws ContextException {
+		this.applicationRoot = context.get("urn:avalon:home").toString();
+	}
 }
diff --git a/src/java/org/apache/fulcrum/upload/UploadService.java b/src/java/org/apache/fulcrum/upload/UploadService.java
index aa66e3b..2d9a993 100644
--- a/src/java/org/apache/fulcrum/upload/UploadService.java
+++ b/src/java/org/apache/fulcrum/upload/UploadService.java
@@ -1,6 +1,5 @@
 package org.apache.fulcrum.upload;
 
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -20,7 +19,6 @@
  * under the License.
  */
 
-
 import java.util.List;
 
 import javax.portlet.ActionRequest;
@@ -31,11 +29,11 @@
 import org.apache.commons.fileupload.FileItemIterator;
 
 /**
- * <p> This service handles parsing <code>multipart/form-data</code>
- * POST requests and turning them into form fields and uploaded files.
- * This can be either performed automatically by the {@link
- * org.apache.fulcrum.parser.ParameterParser} or manually by an user
- * defined {@link org.apache.turbine.modules.Action}.
+ * <p>
+ * This service handles parsing <code>multipart/form-data</code> POST requests
+ * and turning them into form fields and uploaded files. This can be either
+ * performed automatically by the <code>org.apache.fulcrum.parser.ParameterParser</code> or manually by a user
+ * defined <code>org.apache.turbine.modules.Action</code>.
  *
  * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
  * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
@@ -44,276 +42,280 @@
 public interface UploadService
 
 {
-    /** Avalon Identifier **/
-    String ROLE = UploadService.class.getName();
+	/** Avalon Identifier **/
+	String ROLE = UploadService.class.getName();
 
-    /**
-     * HTTP header.
-     */
-    String CONTENT_TYPE = "Content-type";
+	/**
+	 * HTTP header.
+	 */
+	String CONTENT_TYPE = "Content-type";
 
-    /**
-     * HTTP header.
-     */
-    String CONTENT_DISPOSITION = "Content-disposition";
+	/**
+	 * HTTP header.
+	 */
+	String CONTENT_DISPOSITION = "Content-disposition";
 
-    /**
-     * HTTP header base type.
-     */
-    String MULTIPART = "multipart";
+	/**
+	 * HTTP header base type.
+	 */
+	String MULTIPART = "multipart";
 
-    /**
-     * HTTP header base type modifier.
-     */
-    String FORM_DATA = "form-data";
+	/**
+	 * HTTP header base type modifier.
+	 */
+	String FORM_DATA = "form-data";
 
-    /**
-     * HTTP header base type modifier.
-     */
-    String MIXED = "mixed";
+	/**
+	 * HTTP header base type modifier.
+	 */
+	String MIXED = "mixed";
 
-    /**
-     * HTTP header.
-     */
-    String MULTIPART_FORM_DATA =
-        MULTIPART + '/' + FORM_DATA;
+	/**
+	 * HTTP header.
+	 */
+	String MULTIPART_FORM_DATA = MULTIPART + '/' + FORM_DATA;
 
-    /**
-     * HTTP header.
-     */
-    String MULTIPART_MIXED = MULTIPART + '/' + MIXED;
+	/**
+	 * HTTP header.
+	 */
+	String MULTIPART_MIXED = MULTIPART + '/' + MIXED;
 
-    /**
-     * The request parameter name for overriding 'repository' property
-     * (path).
-     */
-    String REPOSITORY_PARAMETER = "path";
+	/**
+	 * The request parameter name for overriding 'repository' property (path).
+	 */
+	String REPOSITORY_PARAMETER = "path";
 
-    /**
-     * The key in UploadService properties in
-     * TurbineResources.properties 'repository' property.
-     */
-    String REPOSITORY_KEY = "repository";
+	/**
+	 * The key in UploadService properties in TurbineResources.properties
+	 * 'repository' property.
+	 */
+	String REPOSITORY_KEY = "repository";
 
-    /**
-     * <p> The default value of 'repository' property (.).  This is
-     * the directory where uploaded files will get stored temporarily.
-     * Note that "."  is whatever the servlet container chooses to be
-     * it's 'current directory'.
-     */
-    String REPOSITORY_DEFAULT = ".";
+	/**
+	 * <p>
+	 * The default value of 'repository' property (.). This is the directory where
+	 * uploaded files will get stored temporarily. Note that "." is whatever the
+	 * servlet container chooses to be it's 'current directory'.
+	 */
+	String REPOSITORY_DEFAULT = ".";
 
-    /**
-     * w The key in UploadService properties in
-     * service configuration 'sizeMax' property.
-     */
-    String SIZE_MAX_KEY = "sizeMax";
+	/**
+	 * w The key in UploadService properties in service configuration 'sizeMax'
+	 * property.
+	 */
+	String SIZE_MAX_KEY = "sizeMax";
 
-    /**
-     * <p> The default value of 'sizMax' property (1 megabyte =
-     * 1048576 bytes).  This is the maximum size of POST request that
-     * will be parsed by the uploader.  If you need to set specific
-     * limits for your users, set this property to the largest limit
-     * value, and use an action + no auto upload to enforce limits.
-     *
-     */
-    int SIZE_MAX_DEFAULT = 1048576;
+	/**
+	 * <p>
+	 * The default value of 'sizMax' property (1 megabyte = 1048576 bytes). This is
+	 * the maximum size of POST request that will be parsed by the uploader. If you
+	 * need to set specific limits for your users, set this property to the largest
+	 * limit value, and use an action + no auto upload to enforce limits.
+	 *
+	 */
+	int SIZE_MAX_DEFAULT = 1048576;
 
-    /**
-     * The key in UploadService properties in
-     * TurbineResources.properties 'sizeThreshold' property.
-     */
-    String SIZE_THRESHOLD_KEY = "sizeThreshold";
+	/**
+	 * The key in UploadService properties in TurbineResources.properties
+	 * 'sizeThreshold' property.
+	 */
+	String SIZE_THRESHOLD_KEY = "sizeThreshold";
 
-    /**
-     * <p> The default value of 'sizeThreshold' property (10
-     * kilobytes = 10240 bytes).  This is the maximum size of a POST
-     * request that will have it's components stored temporarily in
-     * memory, instead of disk.
-     */
-    int SIZE_THRESHOLD_DEFAULT = 10240;
+	/**
+	 * <p>
+	 * The default value of 'sizeThreshold' property (10 kilobytes = 10240 bytes).
+	 * This is the maximum size of a POST request that will have it's components
+	 * stored temporarily in memory, instead of disk.
+	 */
+	int SIZE_THRESHOLD_DEFAULT = 10240;
 
-    /**
-     * The key in UploadService properties in
-     * TurbineResources.properties 'headerEncoding' property.
-     */
-    String HEADER_ENCODING_KEY = "headerEncoding";
+	/**
+	 * The key in UploadService properties in TurbineResources.properties
+	 * 'headerEncoding' property.
+	 */
+	String HEADER_ENCODING_KEY = "headerEncoding";
 
-    /**
-     * <p> The default value of 'headerEncoding' property (.).
-     * The value has been decided by copying from DiskFileItem class
-     */
-    String HEADER_ENCODING_DEFAULT = "ISO-8859-1";
+	/**
+	 * <p>
+	 * The default value of 'headerEncoding' property (.). The value has been
+	 * decided by copying from DiskFileItem class
+	 */
+	String HEADER_ENCODING_DEFAULT = "ISO-8859-1";
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The servlet request to be parsed.
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    List<FileItem> parseRequest(HttpServletRequest req)
-        throws ServiceException;
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req The servlet request to be parsed.
+	 * @return list of file items
+	 * @throws ServiceException Problems reading/parsing the request or storing
+	 *                             the uploaded file(s).
+	 */
+	List<FileItem> parseRequest(HttpServletRequest req) throws ServiceException;
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The servlet request to be parsed.
-     * @param path The location where the files should be stored.
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    List<FileItem> parseRequest(HttpServletRequest req, String path)
-        throws ServiceException;
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req  The servlet request to be parsed.
+	 * @param path The location where the files should be stored.
+	 * @return List of FileItem parts
+	 * @throws ServiceException Problems reading/parsing the request or storing
+	 *                             the uploaded file(s).
+	 */
+	List<FileItem> parseRequest(HttpServletRequest req, String path) throws ServiceException;
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The servlet request to be parsed.
-     * @param sizeThreshold the max size in bytes to be stored in memory
-     * @param sizeMax the maximum allowed upload size in bytes
-     * @param path The location where the files should be stored.
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    List<FileItem> parseRequest(HttpServletRequest req, int sizeThreshold,
-        int sizeMax, String path)
-        throws ServiceException;
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req           The servlet request to be parsed.
+	 * @param sizeThreshold the max size in bytes to be stored in memory
+	 * @param sizeMax       the maximum allowed upload size in bytes
+	 * @param path          The location where the files should be stored.
+	 * @return List of FileItem parts
+	 * @throws ServiceException Problems reading/parsing the request or storing
+	 *                             the uploaded file(s).
+	 */
+	List<FileItem> parseRequest(HttpServletRequest req, int sizeThreshold, int sizeMax, String path)
+			throws ServiceException;
 
+	/**
+	 * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
+	 * compliant <code>multipart/form-data</code> stream.
+	 *
+	 * @param req The servlet request to be parsed.
+	 *
+	 * @return An iterator to instances of <code>FileItemStream</code> parsed from
+	 *         the request, in the order that they were transmitted.
+	 *
+	 * @throws ServiceException if there are problems reading/parsing the request or
+	 *                          storing files. This may also be a network error
+	 *                          while communicating with the client or a problem
+	 *                          while storing the uploaded content.
+	 */
+	FileItemIterator getItemIterator(HttpServletRequest req) throws ServiceException;
 
-    /**
-     * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.
-     *
-     * @param req The servlet request to be parsed.
-     *
-     * @return An iterator to instances of <code>FileItemStream</code>
-     *         parsed from the request, in the order that they were
-     *         transmitted.
-     *
-     * @throws ServiceException if there are problems reading/parsing
-     *                             the request or storing files. This
-     *                             may also be a network error while
-     *                             communicating with the client or a
-     *                             problem while storing the uploaded
-     *                             content.
-     */
-    FileItemIterator getItemIterator(HttpServletRequest req) throws ServiceException;
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req The portlet request to be parsed.
+	 * @return List of FileItem parts
+	 * @throws ServiceException Problems reading/parsing the request or storing
+	 *                             the uploaded file(s).
+	 */
+	List<FileItem> parseRequest(ActionRequest req) throws ServiceException;
 
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req  The portlet request to be parsed.
+	 * @param path The location where the files should be stored.
+	 * @return List of FileItem parts
+	 * @throws ServiceException Problems reading/parsing the request or storing
+	 *                             the uploaded file(s).
+	 */
+	List<FileItem> parseRequest(ActionRequest req, String path) throws ServiceException;
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The portlet request to be parsed.
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    List<FileItem> parseRequest(ActionRequest req)
-        throws ServiceException;
+	/**
+	 * <p>
+	 * Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> compliant
+	 * <code>multipart/form-data</code> stream.
+	 * </p>
+	 *
+	 * @param req           The portlet request to be parsed.
+	 * @param sizeThreshold the max size in bytes to be stored in memory
+	 * @param sizeMax       the maximum allowed upload size in bytes
+	 * @param path          The location where the files should be stored.
+	 * @return The list of FileItem parts uploaded 
+	 * @throws ServiceException Problems reading/parsing the request or storing
+	 *                             the uploaded file(s).
+	 */
+	List<FileItem> parseRequest(ActionRequest req, int sizeThreshold, int sizeMax, String path) throws ServiceException;
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The portlet request to be parsed.
-     * @param path The location where the files should be stored.
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    List<FileItem> parseRequest(ActionRequest req, String path)
-        throws ServiceException;
+	/**
+	 * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
+	 * compliant <code>multipart/form-data</code> stream.
+	 *
+	 * @param req The portlet request to be parsed.
+	 *
+	 * @return An iterator to instances of <code>FileItemStream</code> parsed from
+	 *         the request, in the order that they were transmitted.
+	 *
+	 * @throws ServiceException if there are problems reading/parsing the request or
+	 *                          storing files. This may also be a network error
+	 *                          while communicating with the client or a problem
+	 *                          while storing the uploaded content.
+	 */
+	FileItemIterator getItemIterator(ActionRequest req) throws ServiceException;
 
-    /**
-     * <p>Parses a <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.</p>
-     *
-     * @param req The portlet request to be parsed.
-     * @param sizeThreshold the max size in bytes to be stored in memory
-     * @param sizeMax the maximum allowed upload size in bytes
-     * @param path The location where the files should be stored.
-     * @exception ServiceException Problems reading/parsing the
-     * request or storing the uploaded file(s).
-     */
-    List<FileItem> parseRequest(ActionRequest req, int sizeThreshold,
-        int sizeMax, String path)
-        throws ServiceException;
+	/**
+	 * <p>
+	 * Retrieves the value of <code>size.max</code> property of the
+	 * {@link org.apache.fulcrum.upload.UploadService}.
+	 *
+	 * @return The maximum upload size.
+	 */
+	long getSizeMax();
 
+	/**
+	 * <p>
+	 * Retrieves the value of <code>size.threshold</code> property of
+	 * {@link org.apache.fulcrum.upload.UploadService}.
+	 *
+	 * @return The threshold beyond which files are written directly to disk.
+	 */
+	long getSizeThreshold();
 
-    /**
-     * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>
-     * compliant <code>multipart/form-data</code> stream.
-     *
-     * @param req The portlet request to be parsed.
-     *
-     * @return An iterator to instances of <code>FileItemStream</code>
-     *         parsed from the request, in the order that they were
-     *         transmitted.
-     *
-     * @throws ServiceException if there are problems reading/parsing
-     *                             the request or storing files. This
-     *                             may also be a network error while
-     *                             communicating with the client or a
-     *                             problem while storing the uploaded
-     *                             content.
-     */
-    FileItemIterator getItemIterator(ActionRequest req) throws ServiceException;
+	/**
+	 * <p>
+	 * Retrieves the value of the <code>repository</code> property of
+	 * {@link org.apache.fulcrum.upload.UploadService}.
+	 *
+	 * @return The repository.
+	 */
+	String getRepository();
 
+	/**
+	 * <p>
+	 * Retrieves the value of the <code>headerEncoding</code> property of
+	 * {@link org.apache.fulcrum.upload.UploadService}.
+	 *
+	 * @return Returns the headerEncoding.
+	 */
+	String getHeaderEncoding();
 
-    /**
-     * <p> Retrieves the value of <code>size.max</code> property of the
-     * {@link org.apache.fulcrum.upload.UploadService}.
-     *
-     * @return The maximum upload size.
-     */
-    long getSizeMax();
+	/**
+	 * Utility method that determines whether the request contains multipart
+	 * content.
+	 *
+	 * @param req The servlet request to be evaluated. Must be non-null.
+	 *
+	 * @return <code>true</code> if the request is multipart; <code>false</code>
+	 *         otherwise.
+	 */
+	boolean isMultipart(HttpServletRequest req);
 
-    /**
-     * <p> Retrieves the value of <code>size.threshold</code> property of
-     * {@link org.apache.fulcrum.upload.UploadService}.
-     *
-     * @return The threshold beyond which files are written directly to disk.
-     */
-    long getSizeThreshold();
-
-    /**
-     * <p> Retrieves the value of the <code>repository</code> property of
-     * {@link org.apache.fulcrum.upload.UploadService}.
-     *
-     * @return The repository.
-     */
-    String getRepository();
-
-    /**
-     * <p> Retrieves the value of the <code>headerEncoding</code> property of
-     * {@link org.apache.fulcrum.upload.UploadService}.
-     *
-     * @return Returns the headerEncoding.
-     */
-    String getHeaderEncoding();
-
-    /**
-     * Utility method that determines whether the request contains multipart
-     * content.
-     *
-     * @param req The servlet request to be evaluated. Must be non-null.
-     *
-     * @return <code>true</code> if the request is multipart;
-     *         <code>false</code> otherwise.
-     */
-    boolean isMultipart(HttpServletRequest req);
-
-    /**
-     * Utility method that determines whether the request contains multipart
-     * content.
-     *
-     * @param req The portlet request to be evaluated. Must be non-null.
-     *
-     * @return <code>true</code> if the request is multipart;
-     *         <code>false</code> otherwise.
-     */
-    boolean isMultipart(ActionRequest req);
+	/**
+	 * Utility method that determines whether the request contains multipart
+	 * content.
+	 *
+	 * @param req The portlet request to be evaluated. Must be non-null.
+	 *
+	 * @return <code>true</code> if the request is multipart; <code>false</code>
+	 *         otherwise.
+	 */
+	boolean isMultipart(ActionRequest req);
 }
