let remove path =
    let rec remove_aux path =
      file_info path
      >>= begin function
      | `Absent -> return ()
      | `Block_device
      | `Character_device
      | `Symlink _
      | `Fifo
      | `Socket
      | `Regular_file _-> wrap_deferred_system (`Remove path) (fun () -> Lwt_unix.unlink path)
      | `Directory ->
        let `Stream next_dir = list_directory path in
        let rec loop () =
          next_dir ()
          >>= begin function
          | Some ".."
          | Some "." -> loop ()
          | Some name ->
            remove_aux (Filename.concat path name)
            >>= fun () ->
            loop ()
          | None -> return ()
          end
        in
        loop ()
        >>= fun () ->
        wrap_deferred_system (`Remove path) (fun () -> Lwt_unix.rmdir path)
      end
    in
    remove_aux path
    >>< begin function
    | `Ok () -> return ()
    | `Error (`System_exn e) -> fail (`System (`Remove path, `Exn e))
    | `Error (`System e) -> fail (`System e)
    end