class AbstractFileResolvingResource extends AbstractResource {

    /**
     * This implementation returns a File reference for the underlying class
     * path resource, provided that it refers to a file in the file system.
     * 
     * @see org.hotswap.agent.util.spring.util.springframework.util.ResourceUtils#getFile(java.net.URL,
     *      String)
     */
    @Override
    public File getFile() throws IOException {
        URL url = getURL();
        if (url.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
            return VfsResourceDelegate.getResource(url).getFile();
        }
        return ResourceUtils.getFile(url, getDescription());
    }

    /**
     * This implementation determines the underlying File (or jar file, in case
     * of a resource in a jar/zip).
     */
    @Override
    protected File getFileForLastModifiedCheck() throws IOException {
        URL url = getURL();
        if (ResourceUtils.isJarURL(url)) {
            URL actualUrl = ResourceUtils.extractJarFileURL(url);
            if (actualUrl.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
                return VfsResourceDelegate.getResource(actualUrl).getFile();
            }
            return ResourceUtils.getFile(actualUrl, "Jar URL");
        } else {
            return getFile();
        }
    }

    /**
     * This implementation returns a File reference for the underlying class
     * path resource, provided that it refers to a file in the file system.
     * 
     * @see org.hotswap.agent.util.spring.util.springframework.util.ResourceUtils#getFile(java.net.URI,
     *      String)
     */
    protected File getFile(URI uri) throws IOException {
        if (uri.getScheme().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
            return VfsResourceDelegate.getResource(uri).getFile();
        }
        return ResourceUtils.getFile(uri, getDescription());
    }

    @Override
    public boolean exists() {
        try {
            URL url = getURL();
            if (ResourceUtils.isFileURL(url)) {
                // Proceed with file system resolution...
                return getFile().exists();
            } else {
                // Try a URL connection content-length header...
                URLConnection con = url.openConnection();
                customizeConnection(con);
                HttpURLConnection httpCon = (con instanceof HttpURLConnection ? (HttpURLConnection) con : null);
                if (httpCon != null) {
                    int code = httpCon.getResponseCode();
                    if (code == HttpURLConnection.HTTP_OK) {
                        return true;
                    } else if (code == HttpURLConnection.HTTP_NOT_FOUND) {
                        return false;
                    }
                }
                if (con.getContentLength() >= 0) {
                    return true;
                }
                if (httpCon != null) {
                    // no HTTP OK status, and no content-length header: give up
                    httpCon.disconnect();
                    return false;
                } else {
                    // Fall back to stream existence: can we open the stream?
                    try (InputStream is = getInputStream()) {
                        return true;
                    }
                }
            }
        } catch (IOException ex) {
            return false;
        }
    }

    @Override
    public boolean isReadable() {
        try {
            URL url = getURL();
            if (ResourceUtils.isFileURL(url)) {
                // Proceed with file system resolution...
                File file = getFile();
                return (file.canRead() && !file.isDirectory());
            } else {
                return true;
            }
        } catch (IOException ex) {
            return false;
        }
    }

    @Override
    public long contentLength() throws IOException {
        URL url = getURL();
        if (ResourceUtils.isFileURL(url)) {
            // Proceed with file system resolution...
            return getFile().length();
        } else {
            // Try a URL connection content-length header...
            URLConnection con = url.openConnection();
            customizeConnection(con);
            return con.getContentLength();
        }
    }

    @Override
    public long lastModified() throws IOException {<FILL_FUNCTION_BODY>}

    /**
     * Customize the given {@link URLConnection}, obtained in the course of an
     * {@link #exists()}, {@link #contentLength()} or {@link #lastModified()}
     * call.
     * <p>
     * Calls {@link ResourceUtils#useCachesIfNecessary(URLConnection)} and
     * delegates to {@link #customizeConnection(HttpURLConnection)} if possible.
     * Can be overridden in subclasses.
     * 
     * @param con
     *            the URLConnection to customize
     * @throws IOException
     *             if thrown from URLConnection methods
     */
    protected void customizeConnection(URLConnection con) throws IOException {
        ResourceUtils.useCachesIfNecessary(con);
        if (con instanceof HttpURLConnection) {
            customizeConnection((HttpURLConnection) con);
        }
    }

    /**
     * Customize the given {@link HttpURLConnection}, obtained in the course of
     * an {@link #exists()}, {@link #contentLength()} or {@link #lastModified()}
     * call.
     * <p>
     * Sets request method "HEAD" by default. Can be overridden in subclasses.
     * 
     * @param con
     *            the HttpURLConnection to customize
     * @throws IOException
     *             if thrown from HttpURLConnection methods
     */
    protected void customizeConnection(HttpURLConnection con) throws IOException {
        con.setRequestMethod("HEAD");
    }

    /**
     * Inner delegate class, avoiding a hard JBoss VFS API dependency at
     * runtime.
     */
    private static class VfsResourceDelegate {

        public static Resource getResource(URL url) throws IOException {
            return new VfsResource(VfsUtils.getRoot(url));
        }

        public static Resource getResource(URI uri) throws IOException {
            return new VfsResource(VfsUtils.getRoot(uri));
        }
    }

}

        URL url = getURL();
        if (ResourceUtils.isFileURL(url) || ResourceUtils.isJarURL(url)) {
            // Proceed with file system resolution...
            return super.lastModified();
        } else {
            // Try a URL connection last-modified header...
            URLConnection con = url.openConnection();
            customizeConnection(con);
            return con.getLastModified();
        }
    
<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>