@SuppressWarnings("unchecked")
  private ApplicationArchive processApplicationArchiveFileUpload(
      ApplicationArchive archive, List<ProcessingEvent> events) {

    GlobalSettings settings = modelManager.getGlobalSettings();
    File tempFile = new File(archive.getNewFileUploaded());
    Long size = tempFile.length();

    String pathError = settings.validateTemporaryStoragePath();
    if (pathError != null) {
      logger.error(
          "There is an issue with the global settings temporary storage path: "
              + settings.validateTemporaryStoragePath()
              + "\n {}",
          pathError);
      events.add(
          new MessagesEvent(
              "There is an issue with the global settings temporary storage path: "
                  + settings.validateTemporaryStoragePath()
                  + " - "
                  + pathError));
      return null;
    }

    // determine the md5 hash of the uploaded file
    // and rename the temp file by the hash
    FileInputStream is = null;
    File destinationFile = null;
    try {

      // if the archive is pre-existing and not the same,
      // then determine if the web-view and zip should be deleted
      // that is, they are not used by any other versions
      if (archive.getId() != null) {
        ArchiveFileHelper.maintainFileSystemCleanliness(modelManager, fileManager, archive, events);
      }

      String hashValue = null;
      ApplicationArchive archiveExists = null;
      try {
        is = new FileInputStream(tempFile);
        hashValue = Utils.hashInputStream("MD5", is);
        archiveExists =
            modelManager
                .getModelService()
                .findApplicationArchiveByHashAndAlgorithm(
                    archive.getApplication(), hashValue, "MD5");
        if (archiveExists != null) {
          if (!tempFile.delete()) {
            String mesg = String.format("Failed to delete temporary file %s", tempFile.getName());
            logger.error(mesg);
            events.add(new MessagesEvent(mesg));
          }
          return archiveExists;
        } else {
          // if an archive of the hash/alg doesn't exist,
          // then we don't want to accidentally change an existing one.
          archive = archive.clone();
          archive.setId(null);
        }
      } catch (DigestException de) {
        throw new PersistenceException(de);
      } finally {
        is.close();
      }

      archive.setHashAlgorithm("MD5");
      archive.setHash(hashValue);

      destinationFile = archive.getFile(settings.getTemporaryStoragePath());

      // if the upload destination exists, then try to delete and overwrite
      // even though they are theoretically the same.
      if (destinationFile.exists() && !destinationFile.delete()) {
        String mesg =
            String.format(
                "Failed to delete old file (theoretically the same anyways, so proceeding) %s",
                destinationFile.getName());
        logger.error(mesg);
        events.add(new MessagesEvent(mesg));
        if (!tempFile.delete()) {
          mesg = String.format("Failed to delete temporary file %s", tempFile.getName());
          logger.error(mesg);
          events.add(new MessagesEvent(mesg));
        }
      }

      // if it didn't exist or it was successfully deleted,
      // then rename the upload to our destination and unzip it
      // into the web-view directory
      else if (tempFile.renameTo(destinationFile)) {

        String mesg =
            String.format(
                "Uploaded temporary file %s successfully renamed to %s",
                tempFile.getName(), destinationFile.getName());
        logger.debug(mesg);
        events.add(new MessagesEvent(mesg));
        ArchiveFileHelper.unzipFile(modelManager, fileManager, archive, destinationFile, events);
      } else {
        String mesg =
            String.format(
                "Failed to renamed file %s to %s", tempFile.getName(), destinationFile.getName());
        logger.error(mesg);
        events.add(new MessagesEvent(mesg));
        return null;
      }
    } catch (IOException ioe) {
      events.add(new MessagesEvent(ioe.getMessage()));
      return null;
    }

    // determine the compressed and uncompressed size of the zip archive
    try {
      archive.setBytesLength(size.intValue());
      ZipFile zipFile = null;
      try {
        zipFile = new ZipFile(destinationFile);
        Integer uncompressedSize = ZipUtils.getUncompressedSize(zipFile).intValue();
        archive.setBytesLengthUncompressed(new Long(uncompressedSize).intValue());
      } finally {
        if (zipFile != null) {
          zipFile.close();
        }
      }
    } catch (IOException ioe) {
      logger.error(
          "An exception occurred while calculating the uncompressed size of the archive: {}", ioe);
      events.add(
          new MessagesEvent(
              String.format(
                  "An exception occurred while calculating the uncompressed size of the archive: %s",
                  ioe.getMessage())));
      return null;
    }

    archive.setUrl(ApplicationArchive.URL_TEMPLATE);

    return archive;
  }