function grant_row_editor()
{
    global $c, $id, $editor, $can_write_principal, $privilege_names;
    $grantrow = new Editor("Grants", "grants");
    $grantrow->SetSubmitName('savegrantrow');
    $edit_grant_clause = '';
    if (isset($_GET['edit_grant'])) {
        $edit_grant_clause = ' AND to_principal != ' . intval($_GET['edit_grant']);
    }
    $grantrow->SetLookup('to_principal', 'SELECT principal_id, displayname FROM dav_principal WHERE principal_id NOT IN (SELECT to_principal FROM grants WHERE by_principal = ' . $id . $edit_grant_clause . ') ORDER BY fullname');
    if ($can_write_principal) {
        if ($grantrow->IsSubmit()) {
            if ($grantrow->IsUpdate()) {
                $c->messages[] = translate('Updating grants by this Principal');
            } else {
                $c->messages[] = translate('Granting new privileges from this Principal');
            }
            $_POST['by_principal'] = $id;
            $to_principal = intval($_POST['to_principal']);
            $orig_to_id = intval($_POST['orig_to_id']);
            $grantrow->SetWhere('by_principal=' . $id . ' AND to_principal=' . $orig_to_id);
            if (isset($_POST['grant_privileges'])) {
                $privilege_bitpos = array_flip($privilege_names);
                $priv_names = array_keys($_POST['grant_privileges']);
                $privs_dec = privilege_to_bits($priv_names);
                $_POST['privileges'] = sprintf('%024s', decbin($privs_dec));
                $grantrow->Assign('privileges', $privs_dec);
            }
            $grantrow->Write();
            unset($_GET['to_principal']);
        } elseif (isset($_GET['delete_grant'])) {
            $qry = new AwlQuery("DELETE FROM grants WHERE by_principal=:grantor_id AND to_principal = :to_principal", array(':grantor_id' => $id, ':to_principal' => intval($_GET['delete_grant'])));
            $qry->Exec('principal-edit');
            $c->messages[] = translate('Deleted a grant from this Principal');
        }
    }
    return $grantrow;
}