@Override
  @Transactional
  public HDocument saveDocument(
      String projectSlug,
      String iterationSlug,
      Resource sourceDoc,
      Set<String> extensions,
      boolean copyTrans) {
    // Only active iterations allow the addition of a document
    HProjectIteration hProjectIteration = projectIterationDAO.getBySlug(projectSlug, iterationSlug);

    // Check permission
    identity.checkPermission(hProjectIteration, "import-template");

    String docId = sourceDoc.getName();

    HDocument document = documentDAO.getByDocIdAndIteration(hProjectIteration, docId);
    HLocale hLocale = this.localeServiceImpl.validateSourceLocale(sourceDoc.getLang());

    boolean changed = false;
    int nextDocRev;
    if (document == null) { // must be a create operation
      nextDocRev = 1;
      changed = true;
      // TODO check that entity name matches id parameter
      document = new HDocument(sourceDoc.getName(), sourceDoc.getContentType(), hLocale);
      document.setProjectIteration(hProjectIteration);
      hProjectIteration.getDocuments().put(docId, document);
      document = documentDAO.makePersistent(document);
    } else if (document.isObsolete()) { // must also be a create operation
      nextDocRev = document.getRevision() + 1;
      changed = true;
      document.setObsolete(false);
      // not sure if this is needed
      hProjectIteration.getDocuments().put(docId, document);
    } else { // must be an update operation
      nextDocRev = document.getRevision() + 1;
    }

    changed |=
        resourceUtils.transferFromResource(sourceDoc, document, extensions, hLocale, nextDocRev);
    documentDAO.flush();

    long actorId = authenticatedAccount.getPerson().getId();
    if (changed) {
      documentUploadedEvent.fireAfterSuccess(
          new DocumentUploadedEvent(actorId, document.getId(), true, hLocale.getLocaleId()));
      clearStatsCacheForUpdatedDocument(document);
    }

    if (copyTrans && nextDocRev == 1) {
      copyTranslations(document);
    }

    return document;
  }
  @Override
  public ProcessStatus startSourceDocCreation(
      final String idNoSlash,
      final String projectSlug,
      final String iterationSlug,
      final Resource resource,
      final Set<String> extensions,
      final boolean copytrans) {
    HProjectIteration hProjectIteration =
        retrieveAndCheckIteration(projectSlug, iterationSlug, true);

    resourceUtils.validateExtensions(extensions); // gettext, comment

    HDocument document = documentDAO.getByDocIdAndIteration(hProjectIteration, resource.getName());

    // already existing non-obsolete document.
    if (document != null) {
      if (!document.isObsolete()) {
        // updates must happen through PUT on the actual resource
        ProcessStatus status = new ProcessStatus();
        status.setStatusCode(ProcessStatusCode.Failed);
        status.getMessages().add("A document with name " + resource.getName() + " already exists.");
        return status;
      }
    }

    String name = "SourceDocCreation: " + projectSlug + "-" + iterationSlug + "-" + idNoSlash;
    AsyncTaskHandle<HDocument> handle = new AsyncTaskHandle<HDocument>();
    Serializable taskId = asyncTaskHandleManager.registerTaskHandle(handle);
    documentServiceImpl.saveDocumentAsync(
        projectSlug, iterationSlug, resource, extensions, copytrans, true, handle);

    return getProcessStatus(taskId.toString()); // TODO Change to return 202
    // Accepted,
    // with a url to get the
    // progress
  }