public function upload_document($docj, PaperOption $o)
 {
     global $Conf;
     // look for an existing document with same sha1;
     // check existing docid's sha1
     $docid = get($docj, "docid");
     if ($docid) {
         $oldj = $this->document_to_json($o->id, $docid);
         if (get($docj, "sha1") && get($oldj, "sha1") !== $docj->sha1) {
             $docid = null;
         }
     } else {
         if (!$docid && $this->paperid > 0 && get($docj, "sha1")) {
             $result = Dbl::qe("select paperStorageId from PaperStorage where paperId=? and documentType=? and sha1=?", $this->paperid, $o->id, $docj->sha1);
             if ($row = edb_row($result)) {
                 $docid = $row[0];
             }
         }
     }
     if ($docid) {
         $docj->docid = $docid;
         return;
     }
     // check filter
     if (get($docj, "filter") && is_int($docj->filter)) {
         if (is_int(get($docj, "original_id"))) {
             $result = Dbl::qe("select paperStorageId, timestamp, sha1 from PaperStorage where paperStorageId=?", $docj->original_id);
         } else {
             if (is_string(get($docj, "original_sha1"))) {
                 $result = Dbl::qe("select paperStorageId, timestamp, sha1 from PaperStorage where paperId=? and sha1=?", $this->paperid, $docj->original_sha1);
             } else {
                 if ($o->id == DTYPE_SUBMISSION || $o->id == DTYPE_FINAL) {
                     $result = Dbl::qe("select PaperStorage.paperStorageId, PaperStorage.timestamp, PaperStorage.sha1 from PaperStorage join Paper on (Paper.paperId=PaperStorage.paperId and Paper." . ($o->id == DTYPE_SUBMISSION ? "paperStorageId" : "finalPaperStorageId") . "=PaperStorage.paperStorageId) where Paper.paperId=?", $this->paperid);
                 } else {
                     $result = null;
                 }
             }
         }
         if ($row = edb_orow($result)) {
             $docj->original_id = (int) $row->paperStorageId;
             $docj->original_timestamp = (int) $row->timestamp;
             $docj->original_sha1 = $row->sha1;
             if (get($docj, "preserve_timestamp")) {
                 $docj->timestamp = (int) $docj->original_timestamp;
             }
         } else {
             unset($docj->original_id);
         }
     }
     // if no sha1 match, upload
     $docclass = new HotCRPDocument($o->id);
     $upload = null;
     if ($docclass->load($docj)) {
         $upload = $docclass->upload($docj, (object) array("paperId" => $this->paperid));
     }
     if ($upload && get($upload, "paperStorageId") > 1) {
         foreach (array("size", "sha1", "mimetype", "timestamp") as $k) {
             $docj->{$k} = $upload->{$k};
         }
         $this->uploaded_documents[] = $docj->docid = $upload->paperStorageId;
     } else {
         $docj->docid = 1;
         $this->set_option_error_html($o, $upload ? $upload->error_html : "empty document");
     }
 }