class FileSystemResource extends AbstractResource implements WritableResource {

    private final File file;

    private final String path;

    /**
     * Create a new {@code FileSystemResource} from a {@link File} handle.
     * <p>
     * Note: When building relative resources via {@link #createRelative}, the
     * relative path will apply <i>at the same directory level</i>: e.g. new
     * File("C:/dir1"), relative path "dir2" -> "C:/dir2"! If you prefer to have
     * relative paths built underneath the given root directory, use the
     * {@link #FileSystemResource(String) constructor with a file path} to
     * append a trailing slash to the root path: "C:/dir1/", which indicates
     * this directory as root for all relative paths.
     * 
     * @param file
     *            a File handle
     */
    public FileSystemResource(File file) {
        Assert.notNull(file, "File must not be null");
        this.file = file;
        this.path = StringUtils.cleanPath(file.getPath());
    }

    /**
     * Create a new {@code FileSystemResource} from a file path.
     * <p>
     * Note: When building relative resources via {@link #createRelative}, it
     * makes a difference whether the specified resource base path here ends
     * with a slash or not. In the case of "C:/dir1/", relative paths will be
     * built underneath that root: e.g. relative path "dir2" -> "C:/dir1/dir2".
     * In the case of "C:/dir1", relative paths will apply at the same directory
     * level: relative path "dir2" -> "C:/dir2".
     * 
     * @param path
     *            a file path
     */
    public FileSystemResource(String path) {
        Assert.notNull(path, "Path must not be null");
        this.file = new File(path);
        this.path = StringUtils.cleanPath(path);
    }

    /**
     * Return the file path for this resource.
     */
    public final String getPath() {
        return this.path;
    }

    /**
     * This implementation returns whether the underlying file exists.
     * 
     * @see java.io.File#exists()
     */
    @Override
    public boolean exists() {
        return this.file.exists();
    }

    /**
     * This implementation checks whether the underlying file is marked as
     * readable (and corresponds to an actual file with content, not to a
     * directory).
     * 
     * @see java.io.File#canRead()
     * @see java.io.File#isDirectory()
     */
    @Override
    public boolean isReadable() {
        return (this.file.canRead() && !this.file.isDirectory());
    }

    /**
     * This implementation opens a FileInputStream for the underlying file.
     * 
     * @see java.io.FileInputStream
     */
    @Override
    public InputStream getInputStream() throws IOException {
        return new FileInputStream(this.file);
    }

    /**
     * This implementation returns a URL for the underlying file.
     * 
     * @see java.io.File#toURI()
     */
    @Override
    public URL getURL() throws IOException {
        return this.file.toURI().toURL();
    }

    /**
     * This implementation returns a URI for the underlying file.
     * 
     * @see java.io.File#toURI()
     */
    @Override
    public URI getURI() throws IOException {
        return this.file.toURI();
    }

    /**
     * This implementation returns the underlying File reference.
     */
    @Override
    public File getFile() {
        return this.file;
    }

    /**
     * This implementation returns the underlying File's length.
     */
    @Override
    public long contentLength() throws IOException {
        return this.file.length();
    }

    /**
     * This implementation creates a FileSystemResource, applying the given path
     * relative to the path of the underlying file of this resource descriptor.
     * 
     * @see org.hotswap.agent.util.spring.util.springframework.util.StringUtils#applyRelativePath(String,
     *      String)
     */
    @Override
    public Resource createRelative(String relativePath) {
        String pathToUse = StringUtils.applyRelativePath(this.path, relativePath);
        return new FileSystemResource(pathToUse);
    }

    /**
     * This implementation returns the name of the file.
     * 
     * @see java.io.File#getName()
     */
    @Override
    public String getFilename() {
        return this.file.getName();
    }

    /**
     * This implementation returns a description that includes the absolute path
     * of the file.
     * 
     * @see java.io.File#getAbsolutePath()
     */
    @Override
    public String getDescription() {
        return "file [" + this.file.getAbsolutePath() + "]";
    }

    // implementation of WritableResource

    /**
     * This implementation checks whether the underlying file is marked as
     * writable (and corresponds to an actual file with content, not to a
     * directory).
     * 
     * @see java.io.File#canWrite()
     * @see java.io.File#isDirectory()
     */
    @Override
    public boolean isWritable() {
        return (this.file.canWrite() && !this.file.isDirectory());
    }

    /**
     * This implementation opens a FileOutputStream for the underlying file.
     * 
     * @see java.io.FileOutputStream
     */
    @Override
    public OutputStream getOutputStream() throws IOException {
        return new FileOutputStream(this.file);
    }

    /**
     * This implementation compares the underlying File references.
     */
    @Override
    public boolean equals(Object obj) {<FILL_FUNCTION_BODY>}

    /**
     * This implementation returns the hash code of the underlying File
     * reference.
     */
    @Override
    public int hashCode() {
        return this.path.hashCode();
    }

}

        return (obj == this || (obj instanceof FileSystemResource && this.path.equals(((FileSystemResource) obj).path)));
    
<methods>public non-sealed void <init>() ,public long contentLength() throws java.io.IOException,public org.hotswap.agent.util.spring.io.resource.Resource createRelative(java.lang.String) throws java.io.IOException,public boolean equals(java.lang.Object) ,public boolean exists() ,public java.io.File getFile() throws java.io.IOException,public java.lang.String getFilename() ,public java.net.URI getURI() throws java.io.IOException,public java.net.URL getURL() throws java.io.IOException,public int hashCode() ,public boolean isOpen() ,public boolean isReadable() ,public long lastModified() throws java.io.IOException,public java.lang.String toString() <variables>