anchor.diff:                       :if-exists :supersede)
       (with-standard-io-syntax
         (format o "#!/bin/sh
  -lispctl eval ~A `pwd` \"$0\" \"$@\"
  +lispctl eval ~S `pwd` \"$0\" \"$@\"
   "
  -              (uiop/run-program:escape-sh-token (write-to-string form)))))
  +              (uiop/run-program:escape-sh-token (if (stringp form)
  +                                                    form
  +                                                    (write-to-string form))))))
     (uiop/run-program:run-program `("chmod" "+x" ,name)))
   
  -(defun install (name &optional (bindir *default-bindir*))
  -  (unless (probe-file name)
  -    (error "File ~A does not exist." name))
  -  (let ((target (merge-pathnames name bindir)))
  -    (ensure-directories-exist target)
  -    (uiop/filesystem:rename-file-overwriting-target name target)))
  +(defun server-user-directory (server)
  +  (server-name server))
  +
  +(defun install (software server &optional (bindir (default-bindir (server-user-directory server))))
  +  (let* ((soft (read-software-list (server-user-directory server)))
  +         (name (second (assoc :name software)))
  +         (file (merge-pathnames name)))
  +    (when (member name soft
  +                  :key (lambda (s)
  +                         (second (assoc :name s)))
  +                  :test #'equal)
  +      (error "Installation error: ~A has already been installed." name))
  +    (unless (probe-file file)
  +      (error "Installation error: file ~A does not exist." file))
  +    (let ((target (merge-pathnames name bindir)))
  +      (when (probe-file target)
  +        (error "Installation error: file ~A already exists." target))
  +      (ensure-directories-exist target)
  +      (rename-file name target)
  +      (let ((new-soft `(((:file ,target)
  +                         (:time ,(file-write-date target))
  +                         ,@software) ,@soft)))
  +        (dump-dependencies (software-dependencies new-soft) (server-user-directory server))
  +        (dump-software-list new-soft (server-user-directory server))))))
  +
  +(defun uninstall (name server)
  +  (let* ((soft (read-software-list (server-user-directory server)))
  +         (software (find name soft
  +                         :key (lambda (s)
  +                                (second (assoc :name s)))
  +                         :test #'equal)))
  +    (unless software
  +      (error "Deinstallation error: ~A has not been installed." name))
  +    (setf soft (delete name soft
  +                       :key (lambda (s)
  +                              (second (assoc :name s)))
  +                       :test #'equal))
  +    (dump-software-list soft (server-user-directory server))
  +    (dump-dependencies (software-dependencies soft) (server-user-directory server))
  +    (let* ((file (second (assoc :file software)))
  +           (time (second (assoc :time software)))
  +           (actual-time (if file
  +                            (file-write-date file)
  +                            nil)))
  +      (cond ((and file
  +                  (not (probe-file file)))
  +             (warn "File ~A does not exist." file))
  +            ((not (and time actual-time))
  +             (warn "Cannot check if ~A has been modified since installation.  You can remove it manually." file))
  +            ((/= time actual-time) (warn "File ~A has been modified since installation.  You can remove it manually." file))
  +            (t (delete-file file))))))
  
positive.code: 
  (defun rc-file (user-directory)
    (merge-pathnames #p"rc.lisp" user-directory))
  
  (defun script-function (function)
    (lambda (args
  
negative.code:       (when server
          (stop-server server)
          (setf *servers* (remove server *servers*))))
      (mapc #'asdf:require-system (read-dependencies user-directory))
      (ensure-directories-exist (socket-file user-directory))
      (handler-case
        (delete-file socket-file)
  