protected function saveUploadFile(ObjectId $oid, $valueName, array $data) {
    if ($data['name'] != '') {
      $response = $this->getResponse();
      $message = $this->getMessage();
      $fileUtil = $this->getFileUtil();

      // upload request -> see if upload was succesfull
      if ($data['tmp_name'] == 'none') {
        $response->addError(ApplicationError::get('GENERAL_ERROR',
          ['message' => $message->getText("Upload failed for %0%.", [$data['name']])]));
        return null;
      }

      // check if file was actually uploaded
      if (!is_uploaded_file($data['tmp_name'])) {
        $message = $message->getText("Possible file upload attack: filename %0%.", [$data['name']]);
        $response->addError(ApplicationError::get('GENERAL_ERROR', ['message' => $message]));
        return null;
      }

      // get upload directory
      $uploadDir = $this->getUploadDir($oid, $valueName);

      // get the name for the uploaded file
      $uploadFilename = $uploadDir.$this->getUploadFilename($oid, $valueName, $data['name']);

      // check file validity
      if (!$this->checkFile($oid, $valueName, $uploadFilename, $data['type'])) {
        return null;
      }

      // get upload parameters
      $override = $this->shouldOverride($oid, $valueName, $uploadFilename);

      // upload file (mimeTypes parameter is set to null, because the mime type is already checked by checkFile method)
      try {
        return $fileUtil->uploadFile($data, $uploadFilename, null, $override);
      } catch (\Exception $ex) {
        $response->addError(ApplicationError::fromException($ex));
        return null;
      }
    }
    return null;
  }