class FilePathWrapper extends FilePath {

    private FilePath base;

    @Override
    public FilePathWrapper getPath(String path) {
        return create(path, unwrap(path));
    }

    /**
     * Create a wrapped path instance for the given base path.
     *
     * @param base the base path
     * @return the wrapped path
     */
    public FilePathWrapper wrap(FilePath base) {<FILL_FUNCTION_BODY>}

    @Override
    public FilePath unwrap() {
        return unwrap(name);
    }

    private FilePathWrapper create(String path, FilePath base) {
        try {
            FilePathWrapper p = getClass().getDeclaredConstructor().newInstance();
            p.name = path;
            p.base = base;
            return p;
        } catch (Exception e) {
            throw new IllegalArgumentException("Path: " + path, e);
        }
    }

    protected String getPrefix() {
        return getScheme() + ":";
    }

    /**
     * Get the base path for the given wrapped path.
     *
     * @param path the path including the scheme prefix
     * @return the base file path
     */
    protected FilePath unwrap(String path) {
        return FilePath.get(path.substring(getScheme().length() + 1));
    }

    protected FilePath getBase() {
        return base;
    }

    @Override
    public boolean canWrite() {
        return base.canWrite();
    }

    @Override
    public void createDirectory() {
        base.createDirectory();
    }

    @Override
    public boolean createFile() {
        return base.createFile();
    }

    @Override
    public void delete() {
        base.delete();
    }

    @Override
    public boolean exists() {
        return base.exists();
    }

    @Override
    public FilePath getParent() {
        return wrap(base.getParent());
    }

    @Override
    public boolean isAbsolute() {
        return base.isAbsolute();
    }

    @Override
    public boolean isDirectory() {
        return base.isDirectory();
    }

    @Override
    public long lastModified() {
        return base.lastModified();
    }

    @Override
    public FilePath toRealPath() {
        return wrap(base.toRealPath());
    }

    @Override
    public List<FilePath> newDirectoryStream() {
        List<FilePath> list = base.newDirectoryStream();
        for (int i = 0, len = list.size(); i < len; i++) {
            list.set(i, wrap(list.get(i)));
        }
        return list;
    }

    @Override
    public void moveTo(FilePath newName, boolean atomicReplace) {
        base.moveTo(((FilePathWrapper) newName).base, atomicReplace);
    }

    @Override
    public InputStream newInputStream() throws IOException {
        return base.newInputStream();
    }

    @Override
    public OutputStream newOutputStream(boolean append) throws IOException {
        return base.newOutputStream(append);
    }

    @Override
    public FileChannel open(String mode) throws IOException {
        return base.open(mode);
    }

    @Override
    public boolean setReadOnly() {
        return base.setReadOnly();
    }

    @Override
    public long size() {
        return base.size();
    }

    @Override
    public FilePath createTempFile(String suffix, boolean deleteOnExit, boolean inTempDir)
            throws IOException {
        return wrap(base.createTempFile(suffix, deleteOnExit, inTempDir));
    }
}

        return base == null ? null : create(getPrefix() + base.name, base);
    
<methods>public non-sealed void <init>() ,public abstract boolean canWrite() ,public abstract void createDirectory() ,public abstract boolean createFile() ,public com.lealone.storage.fs.FilePath createTempFile(java.lang.String, boolean, boolean) throws java.io.IOException,public abstract void delete() ,public abstract boolean exists() ,public static com.lealone.storage.fs.FilePath get(java.lang.String) ,public java.lang.String getName() ,public abstract com.lealone.storage.fs.FilePath getParent() ,public abstract com.lealone.storage.fs.FilePath getPath(java.lang.String) ,public abstract java.lang.String getScheme() ,public abstract boolean isAbsolute() ,public abstract boolean isDirectory() ,public abstract long lastModified() ,public abstract void moveTo(com.lealone.storage.fs.FilePath, boolean) ,public abstract List<com.lealone.storage.fs.FilePath> newDirectoryStream() ,public abstract java.io.InputStream newInputStream() throws java.io.IOException,public abstract java.io.OutputStream newOutputStream(boolean) throws java.io.IOException,public abstract java.nio.channels.FileChannel open(java.lang.String) throws java.io.IOException,public static void register(com.lealone.storage.fs.FilePath) ,public abstract boolean setReadOnly() ,public abstract long size() ,public abstract com.lealone.storage.fs.FilePath toRealPath() ,public java.lang.String toString() ,public static void unregister(com.lealone.storage.fs.FilePath) ,public com.lealone.storage.fs.FilePath unwrap() <variables>private static com.lealone.storage.fs.FilePath defaultProvider,public java.lang.String name,private static Map<java.lang.String,com.lealone.storage.fs.FilePath> providers,private static java.lang.String tempRandom,private static long tempSequence