class CloudFileServiceOfLocalImpl implements CloudFileService {
    private final String bucketDef;
    private final File root;
    private final ReentrantLock SYNC_LOCK = new ReentrantLock();

    public CloudFileServiceOfLocalImpl(String bucketDef, Props props) {
        String endpoint = props.getProperty("endpoint");

        this.bucketDef = bucketDef;
        this.root = new File(endpoint);

        if (root.exists() == false) {
            root.mkdirs();
        }
    }

    @Override
    public boolean exists(String bucket, String key) throws CloudFileException {
        if (Utils.isEmpty(bucket)) {
            bucket = bucketDef;
        }

        try {
            return getFile(bucket, key).exists();
        } catch (Throwable e) {
            throw new CloudFileException(e);
        }
    }

    @Override
    public String getTempUrl(String bucket, String key, Date expiration) throws CloudFileException {
        throw new UnsupportedOperationException();
    }

    @Override
    public Media get(String bucket, String key) throws CloudFileException {<FILL_FUNCTION_BODY>}

    @Override
    public Result put(String bucket, String key, Media media) throws CloudFileException {
        if (Utils.isEmpty(bucket)) {
            bucket = bucketDef;
        }

        try {
            File file = getFile(bucket, key);
            if (file.exists() == false) {
                file.createNewFile();
            }

            try (OutputStream stream = new FileOutputStream(file, false)) {
                IoUtil.transferTo(media.body(), stream);
            }

            return Result.succeed(file.getAbsolutePath());
        } catch (Throwable e) {
            throw new CloudFileException(e);
        }
    }

    @Override
    public Result delete(String bucket, String key) throws CloudFileException {
        if (Utils.isEmpty(bucket)) {
            bucket = bucketDef;
        }

        try {
            File file = getFile(bucket, key);
            if (file.exists()) {
                if (file.delete() == false) {
                    return Result.failure();
                }
            }

            return Result.succeed(file.getAbsolutePath());
        } catch (Throwable e) {
            throw new CloudFileException(e);
        }
    }

    private File getFile(String bucket, String key) {
        if (Utils.isEmpty(bucket)) {
            bucket = "DEFAULT_BUCKET";
        }

        File dir = new File(root, bucket);

        SYNC_LOCK.lock();

        try {
            if (dir.exists() == false) {
                if (dir.exists() == false) {
                    dir.mkdirs();
                }
            }

            int last = key.lastIndexOf('/');
            if (last > 0) {
                String dir2Str = key.substring(0, last);
                File dir2Tmp = new File(dir, dir2Str);
                if (dir2Tmp.exists() == false) {
                    if (dir2Tmp.exists() == false) {
                        dir2Tmp.mkdirs();
                    }
                }
            }
        } finally {
            SYNC_LOCK.unlock();
        }

        File file = new File(dir, key);

        return file;
    }
}

        if (Utils.isEmpty(bucket)) {
            bucket = bucketDef;
        }

        try {
            File file = getFile(bucket, key);

            if (file.exists()) {
                String contentType = Utils.mime(file.getName());
                return new Media(new FileInputStream(file), contentType);
            } else {
                return null;
            }
        } catch (Throwable e) {
            throw new CloudFileException(e);
        }
    
<no_super_class>