function complete_assignment($callback)
{
    global $Me;
    $assignset = new AssignmentSet($Me, false);
    $assignset->parse($_POST["file"], get($_POST, "filename"), assignment_defaults(), $callback);
    $SSel = SearchSelection::make(make_qreq(), $Me);
    $assignset->restrict_papers($SSel->selection());
    return $assignset->execute(true);
}
 static function call($name, $subname, Contact $user, $qreq, $selection)
 {
     $uf = null;
     if (isset(self::$byname[$name])) {
         $ufm = self::$byname[$name];
         if ((string) $subname !== "" && isset($ufm[$subname])) {
             $uf = $ufm[$subname];
         } else {
             if (isset($ufm[""])) {
                 $uf = $ufm[""];
             }
         }
     }
     if (is_array($selection)) {
         $selection = new SearchSelection($selection);
     }
     if (!$uf) {
         $error = "No such search action.";
     } else {
         if (!($uf[1] & SiteLoader::API_GET) && !check_post($qreq)) {
             $error = "Missing credentials.";
         } else {
             if ($uf[1] & SiteLoader::API_PAPER && $selection->is_empty()) {
                 $error = "No papers selected.";
             } else {
                 if (!$uf[0]->allow($user)) {
                     $error = "Permission error.";
                 } else {
                     $error = $uf[0]->run($user, $qreq, $selection);
                 }
             }
         }
     }
     if (is_string($error) && $qreq->ajax) {
         json_exit(["ok" => false, "error" => $error]);
     } else {
         if (is_string($error)) {
             Conf::msg_error($error);
         }
     }
     return $error;
 }
    if (isset($Qreq->assign)) {
        $Conf->warnMsg("You changed the paper search. Please review the paper list.");
    }
    unset($Qreq->assign);
    $Qreq->requery = 1;
}
if (isset($Qreq->saveassignment)) {
    $SSel = SearchSelection::make($Qreq, $Me, $Qreq->submit ? "pap" : "p");
} else {
    $SSel = new SearchSelection();
    if (!$Qreq->requery) {
        $SSel = SearchSelection::make($Qreq, $Me);
    }
    if ($SSel->is_empty()) {
        $search = new PaperSearch($Me, array("t" => $Qreq->t, "q" => $Qreq->q));
        $SSel = new SearchSelection($search->paperList());
    }
}
$SSel->sort_selection();
// rev_roundtag
if (($x = $Conf->sanitize_round_name($Qreq->rev_roundtag)) !== false) {
    $Qreq->rev_roundtag = $x;
}
// score selector
$scoreselector = array("+overAllMerit" => "", "-overAllMerit" => "");
foreach (ReviewForm::all_fields() as $f) {
    if ($f->has_options) {
        $scoreselector["+" . $f->id] = "high {$f->name_html} scores";
        $scoreselector["-" . $f->id] = "low {$f->name_html} scores";
    }
}
        redirectSelf();
    }
}
if ($Qreq->update && check_post()) {
    savePreferences($Qreq);
}
// Select papers
global $SSel;
$SSel = null;
if ($Qreq->fn === "setpref" || $Qreq->fn === "get") {
    $SSel = SearchSelection::make($Qreq, $Me);
    if ($SSel->is_empty()) {
        Conf::msg_error("No papers selected.");
    }
}
SearchSelection::clear_request();
// Set multiple paper preferences
if ($Qreq->fn === "setpref" && $SSel && !$SSel->is_empty() && check_post()) {
    if (!parse_preference($Qreq->pref)) {
        Conf::msg_error("Preferences must be small positive or negative integers.");
    } else {
        $new_qreq = new Qobject();
        foreach ($SSel->selection() as $p) {
            $new_qreq["revpref{$p}"] = $Qreq->pref;
        }
        savePreferences($new_qreq);
    }
}
// Parse paper preferences
function parseUploadedPreferences($filename, $printFilename, $reviewer)
{