class FileService extends BasicService implements OwnerAPISupport<File> {

	@POST
	@Path("/files")
	public Response uploadFile() {
		String fileName = null;
		long fileSize = 0;
		FileItem document = null;
		byte[] content = null; // FIXME: this will kill the server for huge files, switch to streaming

		if (!ServletFileUpload.isMultipartContent(request)) {
			// plain upload
			fileSize = request.getContentLength();
			fileName = request.getHeader("filename");
			if (fileName == null) {
				throwBadRequest("Header 'filename' is missing in request.");
			}
			try {
				content = IOUtils.readFully(request.getInputStream(), request.getContentLength());
			} catch (IOException e) {
				logger.error("File could not be read.", e);
				return RESPONSE_BAD;
			}
		} else {
			// multipart/form encoded
			try {
				document = UploadHandler.getUploadedDocument(request);
			} catch (FileUploadException e) {
				logger.error("File could not be uploaded.", e);
				return RESPONSE_BAD;
			}
			fileName = document.getName();
			fileSize = document.getSize();
			content = document.get();
		}

		fileName = org.apache.commons.io.FilenameUtils.getName(fileName);
		String key = Math.abs(new Random().nextInt()) + "_" + fileName;
		if (!fileName.contains(".")) {
			if (document != null) {
				document.delete();
			}
			throwBadRequest("File type could not be determined.");
		}
		String fileType = FilenameUtils.getExtension(fileName).toLowerCase();
		if (!mimeTypes.containsKey(fileType)) {
			if (document != null) {
				document.delete();
			}
			throwBadRequest("Unsupported file type.");
		}
		try {
			getECM().uploadDocument(key, content, mimeTypes.get(fileType));
			fileName = FilenameUtils.getBaseName(fileName);
			File file = createFile(fileName, fileType, key, fileSize);

			addContentMetadata(file, new ByteArrayInputStream(content));

			if (document != null) {
				document.delete();
			}
		} catch (CmisNameConstraintViolationException e) {
			logger.error("Filename exception.", e);
			return RESPONSE_BAD;
		}
		deleteThumbnails(key);

		return RESPONSE_OK;
	}

}