class DocumentServiceImpl extends RemoteServiceServlet implements DocumentService {

	@Override
	public GUIDocument save(GUIDocument document) throws ServerException {
		Session session = ServiceUtil.validateSession(getThreadLocalRequest());

		try {
			DocumentDAO docDao = (DocumentDAO) Context.get().getBean(DocumentDAO.class);
			if (document.getId() != 0) {
				if (document.getDocRef() != null) {
					Document alias = docDao.findById(document.getDocRef());
					docDao.initialize(alias);
					alias.setFileName(document.getFileName());
					alias.setType(FilenameUtils.getExtension(alias.getFileName()).toLowerCase());
					boolean stored = docDao.store(alias);
					if (!stored)
						throw new Exception("Document not stored");
				}

				Document doc = docDao.findById(document.getId());
				docDao.initialize(doc);
				String originalDocFilename = doc.getFileName();
				doc.setCustomId(document.getCustomId());
				doc.setComment(document.getComment());

				try {
					Document docVO = toDocument(document);
					docVO.setTenantId(session.getTenantId());
					if (document.getDocRef() != null) {
						docVO.setFileName(originalDocFilename);
						docVO.setType(FilenameUtils.getExtension(originalDocFilename).toLowerCase());
					}

					// Fix the name of multiple attributes
					if (document.getAttributes() != null)
						for (GUIAttribute att : document.getAttributes()) {
							if (att.isMultiple()) {
								NumberFormat nf = new DecimalFormat("0000");
								List<GUIAttribute> values = document.getValues(att.getName());
								values.remove(0);
								int index = 1;
								for (GUIAttribute val : values) {
									val.setName(att.getName() + "-" + nf.format(index++));
								}
							}
						}

					// Create the document history event
					DocumentHistory transaction = new DocumentHistory();
					transaction.setSession(session);
					transaction.setEvent(DocumentEvent.CHANGED.toString());
					transaction.setComment(document.getComment());

					DocumentManager documentManager = (DocumentManager) Context.get().getBean(DocumentManager.class);
					documentManager.update(doc, docVO, transaction);

					if (document.getDocRef() != null)
						return getById(document.getDocRef());
					else
						return getById(document.getId());
				} catch (Throwable t) {
					log.error(t.getMessage(), t);
					throw new RuntimeException(t.getMessage(), t);
				}
			} else
				return null;
		} catch (Throwable t) {
			return (GUIDocument) ServiceUtil.throwServerException(session, log, t);
		}
	}

}