/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package java.io;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.AccessController;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

import org.apache.harmony.luni.internal.io.FileCanonPathCache;
import org.apache.harmony.luni.util.DeleteOnExit;
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.PriviAction;
import org.apache.harmony.luni.util.Util;

/**
 * An "abstract" representation of a file system entity identified by a
 * pathname. The pathname may be absolute (relative to the root directory
 * of the file system) or relative to the current directory in which the program
 * is running.
 * <p>
 * This class provides methods for querying/changing information about the file
 * as well as directory listing capabilities if the file represents a directory.
 * <p>
 * When manipulating file paths, the static fields of this class may be used to
 * determine the platform specific separators.
 * 
 * @see java.io.Serializable
 * @see java.lang.Comparable
 */
public class File implements Serializable, Comparable<File> {

    private static final long serialVersionUID = 301077366599181567L;

    private static final String EMPTY_STRING = ""; //$NON-NLS-1$

    private String path;

    transient byte[] properPath;

    /**
     * The system dependent file separator character.
     */
    public static final char separatorChar;

    /**
     * The system dependent file separator string. The initial value of this
     * field is the system property "file.separator".
     */
    public static final String separator;

    /**
     * The system dependent path separator character.
     */
    public static final char pathSeparatorChar;

    /**
     * The system dependent path separator string. The initial value of this
     * field is the system property "path.separator".
     */
    public static final String pathSeparator;

    /* Temp file counter */
    private static int counter;

    private static boolean caseSensitive;

    private static native void oneTimeInitialization();

    static {
        oneTimeInitialization();

        // The default protection domain grants access to these properties
        separatorChar = System.getProperty("file.separator", "\\").charAt(0); //$NON-NLS-1$ //$NON-NLS-2$
        pathSeparatorChar = System.getProperty("path.separator", ";").charAt(0); //$NON-NLS-1$//$NON-NLS-2$
        separator = new String(new char[] { separatorChar }, 0, 1);
        pathSeparator = new String(new char[] { pathSeparatorChar }, 0, 1);
        caseSensitive = isCaseSensitiveImpl();
    }

    /**
     * Constructs a new file using the specified directory and name.
     * 
     * @param dir
     *            the directory where the file is stored.
     * @param name
     *            the file's name.
     * @throws NullPointerException
     *             if {@code name} is {@code null}.
     */
    public File(File dir, String name) {
        if (name == null) {
            throw new NullPointerException();
        }
        if (dir == null) {
            this.path = fixSlashes(name);
        } else {
            this.path = calculatePath(dir.getPath(), name);
        }
    }

    /**
     * Constructs a new file using the specified path.
     * 
     * @param path
     *            the path to be used for the file.
     */
    public File(String path) {
        // path == null check & NullPointerException thrown by fixSlashes
        this.path = fixSlashes(path);
    }

    /**
     * Constructs a new File using the specified directory path and file name,
     * placing a path separator between the two.
     * 
     * @param dirPath
     *            the path to the directory where the file is stored.
     * @param name
     *            the file's name.
     * @throws NullPointerException
     *             if {@code name} is {@code null}.
     */
    public File(String dirPath, String name) {
        if (name == null) {
            throw new NullPointerException();
        }
        if (dirPath == null) {
            this.path = fixSlashes(name);
        } else {
            this.path = calculatePath(dirPath, name);
        }
    }

    /**
     * Constructs a new File using the path of the specified URI. {@code uri}
     * needs to be an absolute and hierarchical Unified Resource Identifier with
     * file scheme and non-empty path component, but with undefined authority,
     * query or fragment components.
     * 
     * @param uri
     *            the Unified Resource Identifier that is used to construct this
     *            file.
     * @throws IllegalArgumentException
     *             if {@code uri} does not comply with the conditions above.
     * @see #toURI
     * @see java.net.URI
     */
    public File(URI uri) {
        // check pre-conditions
        checkURI(uri);
        this.path = fixSlashes(uri.getPath());
    }

    private String calculatePath(String dirPath, String name) {
        dirPath = fixSlashes(dirPath);
        if (!name.equals(EMPTY_STRING) || dirPath.equals(EMPTY_STRING)) {
            // Remove all the proceeding separator chars from name
            name = fixSlashes(name);

            int separatorIndex = 0;
            while ((separatorIndex < name.length())
                    && (name.charAt(separatorIndex) == separatorChar)) {
                separatorIndex++;
            }
            if (separatorIndex > 0) {
                name = name.substring(separatorIndex, name.length());
            }

            // Ensure there is a separator char between dirPath and name
            if (dirPath.length() > 0
                    && (dirPath.charAt(dirPath.length() - 1) == separatorChar)) {
                return dirPath + name;
            }
            return dirPath + separatorChar + name;
        }

        return dirPath;
    }

    @SuppressWarnings("nls")
    private void checkURI(URI uri) {
        if (!uri.isAbsolute()) {
            throw new IllegalArgumentException(Msg.getString("K031a", uri));
        } else if (!uri.getRawSchemeSpecificPart().startsWith("/")) {
            throw new IllegalArgumentException(Msg.getString("K031b", uri));
        }

        String temp = uri.getScheme();
        if (temp == null || !temp.equals("file")) {
            throw new IllegalArgumentException(Msg.getString("K031c", uri));
        }

        temp = uri.getRawPath();
        if (temp == null || temp.length() == 0) {
            throw new IllegalArgumentException(Msg.getString("K031d", uri));
        }

        if (uri.getRawAuthority() != null) {
            throw new IllegalArgumentException(Msg.getString("K031e",
                    new String[] { "authority", uri.toString() }));
        }

        if (uri.getRawQuery() != null) {
            throw new IllegalArgumentException(Msg.getString("K031e",
                    new String[] { "query", uri.toString() }));
        }

        if (uri.getRawFragment() != null) {
            throw new IllegalArgumentException(Msg.getString("K031e",
                    new String[] { "fragment", uri.toString() }));
        }
    }

    private static native byte[][] rootsImpl();

    private static native boolean isCaseSensitiveImpl();

    /**
     * Lists the file system roots. The Java platform may support zero or more
     * file systems, each with its own platform-dependent root. Further, the
     * canonical pathname of any file on the system will always begin with one
     * of the returned file system roots.
     * 
     * @return the array of file system roots.
     */
    public static File[] listRoots() {
        byte[][] rootsList = rootsImpl();
        if (rootsList == null) {
            return new File[0];
        }
        File result[] = new File[rootsList.length];
        for (int i = 0; i < rootsList.length; i++) {
            result[i] = new File(Util.toString(rootsList[i]));
        }
        return result;
    }

    /**
     * The purpose of this method is to take a path and fix the slashes up. This
     * includes changing them all to the current platforms fileSeparator and
     * removing duplicates.
     */
    private String fixSlashes(String origPath) {
        int uncIndex = 1;
        int length = origPath.length(), newLength = 0;
        if (separatorChar == '/') {
            uncIndex = 0;
        } else if (length > 2 && origPath.charAt(1) == ':') {
            uncIndex = 2;
        }

        boolean foundSlash = false;
        char newPath[] = origPath.toCharArray();
        for (int i = 0; i < length; i++) {
            char pathChar = newPath[i];
            if ((separatorChar == '\\' && pathChar == '\\')
                || pathChar == '/') {
                /* UNC Name requires 2 leading slashes */
                if ((foundSlash && i == uncIndex) || !foundSlash) {
                    newPath[newLength++] = separatorChar;
                    foundSlash = true;
                }
            } else {
                // check for leading slashes before a drive
                if (pathChar == ':'
                        && uncIndex > 0
                        && (newLength == 2 || (newLength == 3 && newPath[1] == separatorChar))
                        && newPath[0] == separatorChar) {
                    newPath[0] = newPath[newLength - 1];
                    newLength = 1;
                    // allow trailing slash after drive letter
                    uncIndex = 2;
                }
                newPath[newLength++] = pathChar;
                foundSlash = false;
            }
        }
        // remove trailing slash
        if (foundSlash
                && (newLength > (uncIndex + 1) || (newLength == 2 && newPath[0] != separatorChar))) {
            newLength--;
        }

        return new String(newPath, 0, newLength);
    }

    /**
     * Indicates whether the current context is allowed to read from this file.
     * 
     * @return {@code true} if this file can be read, {@code false} otherwise.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies the
     *             read request.
     */
    public boolean canRead() {
        if (path.length() == 0) {
            return false;
        }
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        byte[] pp = properPath(true);
        return existsImpl(pp) && !isWriteOnlyImpl(pp);
    }

    /**
     * Indicates whether the current context is allowed to write to this file.
     * 
     * @return {@code true} if this file can be written, {@code false}
     *         otherwise.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies the
     *             write request.
     */
    public boolean canWrite() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkWrite(path);
        }

        // Cannot use exists() since that does an unwanted read-check.
        boolean exists = false;
        if (path.length() > 0) {
            exists = existsImpl(properPath(true));
        }
        return exists && !isReadOnlyImpl(properPath(true));
    }

    /**
     * Returns the relative sort ordering of the paths for this file and the
     * file {@code another}. The ordering is platform dependent.
     * 
     * @param another
     *            a file to compare this file to
     * @return an int determined by comparing the two paths. Possible values are
     *         described in the Comparable interface.
     * @see Comparable
     */
    public int compareTo(File another) {
        if (caseSensitive) {
            return this.getPath().compareTo(another.getPath());
        }
        return this.getPath().compareToIgnoreCase(another.getPath());
    }

    /**
     * Deletes this file. Directories must be empty before they will be deleted.
     * 
     * @return {@code true} if this file was deleted, {@code false} otherwise.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies the
     *             request.
     * @see java.lang.SecurityManager#checkDelete
     */
    public boolean delete() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkDelete(path);
        }
        byte[] propPath = properPath(true);
        if ((path.length() != 0) && isDirectoryImpl(propPath)) {
            return deleteDirImpl(propPath);
        }
        return deleteFileImpl(propPath);
    }

    private native boolean deleteDirImpl(byte[] filePath);

    private native boolean deleteFileImpl(byte[] filePath);

    /**
     * Schedules this file to be automatically deleted once the virtual machine
     * terminates. This will only happen when the virtual machine terminates
     * normally as described by the Java Language Specification section 12.9.
     * 
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies the
     *             request.
     */
    public void deleteOnExit() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkDelete(path);
        }

        DeleteOnExit.addFile(Util.toUTF8String(properPath(true)));
    }

    /**
     * Compares {@code obj} to this file and returns {@code true} if they
     * represent the <em>same</em> object using a path specific comparison.
     * 
     * @param obj
     *            the object to compare this file with.
     * @return {@code true} if {@code obj} is the same as this object,
     *         {@code false} otherwise.
     */
    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof File)) {
            return false;
        }
        if (!caseSensitive) {
            return path.equalsIgnoreCase(((File) obj).getPath());
        }
        return path.equals(((File) obj).getPath());
    }

    /**
     * Returns a boolean indicating whether this file can be found on the
     * underlying file system.
     * 
     * @return {@code true} if this file exists, {@code false} otherwise.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies read
     *             access to this file.
     * @see #getPath
     * @see java.lang.SecurityManager#checkRead(FileDescriptor)
     */
    public boolean exists() {
        if (path.length() == 0) {
            return false;
        }
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        return existsImpl(properPath(true));
    }

    private native boolean existsImpl(byte[] filePath);

    /**
     * Returns the absolute path of this file.
     * 
     * @return the absolute file path.
     * 
     * @see java.lang.SecurityManager#checkPropertyAccess
     */
    public String getAbsolutePath() {
        byte[] absolute = properPath(false);
        return Util.toUTF8String(absolute);
    }

    /**
     * Returns a new file constructed using the absolute path of this file.
     * 
     * @return a new file from this file's absolute path.
     * @see java.lang.SecurityManager#checkPropertyAccess
     */
    public File getAbsoluteFile() {
        return new File(this.getAbsolutePath());
    }

    /**
     * Returns the absolute path of this file with all references resolved. An
     * <em>absolute</em> path is one that begins at the root of the file
     * system. The canonical path is one in which all references have been
     * resolved. For the cases of '..' and '.', where the file system supports
     * parent and working directory respectively, these are removed and replaced
     * with a direct directory reference. If the file does not exist,
     * getCanonicalPath() may not resolve any references and simply returns an
     * absolute path name or throws an IOException.
     * 
     * @return the canonical path of this file.
     * @throws IOException
     *             if an I/O error occurs.
     * @see java.lang.SecurityManager#checkPropertyAccess
     */
    public String getCanonicalPath() throws IOException {
        byte[] result = properPath(false);
        String absPath = Util.toUTF8String(result);
        String canonPath = FileCanonPathCache.get(absPath);

        if (canonPath != null) {
            return canonPath;
        }
        if(separatorChar == '/') {
            // resolve the full path first
            result = resolveLink(result, result.length, false);
            // resolve the parent directories
            result = resolve(result);
        }
        int numSeparators = 1;
        for (int i = 0; i < result.length; i++) {
            if (result[i] == separatorChar) {
                numSeparators++;
            }
        }
        int sepLocations[] = new int[numSeparators];
        int rootLoc = 0;
        if (separatorChar != '/') {
            if (result[0] == '\\') {
                rootLoc = (result.length > 1 && result[1] == '\\') ? 1 : 0;
            } else {
                rootLoc = 2; // skip drive i.e. c:
            }
        }
        byte newResult[] = new byte[result.length + 1];
        int newLength = 0, lastSlash = 0, foundDots = 0;
        sepLocations[lastSlash] = rootLoc;
        for (int i = 0; i <= result.length; i++) {
            if (i < rootLoc) {
                newResult[newLength++] = result[i];
            } else {
                if (i == result.length || result[i] == separatorChar) {
                    if (i == result.length && foundDots == 0) {
                        break;
                    }
                    if (foundDots == 1) {
                        /* Don't write anything, just reset and continue */
                        foundDots = 0;
                        continue;
                    }
                    if (foundDots > 1) {
                        /* Go back N levels */
                        lastSlash = lastSlash > (foundDots - 1) ? lastSlash
                                - (foundDots - 1) : 0;
                        newLength = sepLocations[lastSlash] + 1;
                        foundDots = 0;
                        continue;
                    }
                    sepLocations[++lastSlash] = newLength;
                    newResult[newLength++] = (byte) separatorChar;
                    continue;
                }
                if (result[i] == '.') {
                    foundDots++;
                    continue;
                }
                /* Found some dots within text, write them out */
                if (foundDots > 0) {
                    for (int j = 0; j < foundDots; j++) {
                        newResult[newLength++] = (byte) '.';
                    }
                }
                newResult[newLength++] = result[i];
                foundDots = 0;
            }
        }
        // remove trailing slash
        if (newLength > (rootLoc + 1)
                && newResult[newLength - 1] == separatorChar) {
            newLength--;
        }
        newResult[newLength] = 0;
        newResult = getCanonImpl(newResult);
        newLength = newResult.length;
        canonPath = Util.toUTF8String(newResult, 0, newLength);
        FileCanonPathCache.put(absPath, canonPath);
        return canonPath;
    }
    
    /*
     * Resolve symbolic links in the parent directories.
     */
    private byte[] resolve(byte[] newResult) throws IOException {
        int last = 1, nextSize, linkSize;
        byte[] linkPath = newResult, bytes;
        boolean done, inPlace;
        for (int i = 1; i <= newResult.length; i++) {
            if (i == newResult.length || newResult[i] == separatorChar) {
                done = i >= newResult.length - 1;
                // if there is only one segment, do nothing
                if (done && linkPath.length == 1) {
                    return newResult;
                }
                inPlace = false;
                if (linkPath == newResult) {
                    bytes = newResult;
                    // if there are no symbolic links, terminate the C string
                    // instead of copying
                    if (!done) {
                        inPlace = true;
                        newResult[i] = '\0';
                    }
                } else {
                    nextSize = i - last + 1;
                    linkSize = linkPath.length;
                    if (linkPath[linkSize - 1] == separatorChar) {
                        linkSize--;
                    }
                    bytes = new byte[linkSize + nextSize];
                    System.arraycopy(linkPath, 0, bytes, 0, linkSize);
                    System.arraycopy(newResult, last - 1, bytes, linkSize,
                            nextSize);
                    // the full path has already been resolved
                }
                if (done) {
                    return bytes;
                }
                linkPath = resolveLink(bytes, inPlace ? i : bytes.length, true);
                if (inPlace) {
                    newResult[i] = '/';
                }
                last = i + 1;
            }
        }
        throw new InternalError();
    }

    /*
     * Resolve a symbolic link. While the path resolves to an existing path,
     * keep resolving. If an absolute link is found, resolve the parent
     * directories if resolveAbsolute is true.
     */
    private byte[] resolveLink(byte[] pathBytes, int length,
            boolean resolveAbsolute) throws IOException {
        boolean restart = false;
        byte[] linkBytes, temp;
        do {
            linkBytes = getLinkImpl(pathBytes);
            if (linkBytes == pathBytes) {
                break;
            }
            if (linkBytes[0] == separatorChar) {
                // link to an absolute path, if resolving absolute paths,
                // resolve the parent dirs again
                restart = resolveAbsolute;
                pathBytes = linkBytes;
            } else {
                int last = length - 1;
                while (pathBytes[last] != separatorChar) {
                    last--;
                }
                last++;
                temp = new byte[last + linkBytes.length];
                System.arraycopy(pathBytes, 0, temp, 0, last);
                System.arraycopy(linkBytes, 0, temp, last, linkBytes.length);
                pathBytes = temp;
            }
            length = pathBytes.length;
        } while (existsImpl(pathBytes));
        // resolve the parent directories
        if (restart) {
            return resolve(pathBytes);
        }
        return pathBytes;
    }

    /**
     * Returns a new file created using the canonical path of this file.
     * Equivalent to {@code new File(this.getCanonicalPath())}.
     * 
     * @return the new file constructed from this file's canonical path.
     * @throws IOException
     *             if an I/O error occurs.
     * @see java.lang.SecurityManager#checkPropertyAccess
     */
    public File getCanonicalFile() throws IOException {
        return new File(getCanonicalPath());
    }

    private native byte[] getCanonImpl(byte[] filePath);

    /**
     * Returns the name of the file or directory represented by this file.
     * 
     * @return this file's name or an empty string if there is no name part in
     *         the file's path.
     */
    public String getName() {
        int separatorIndex = path.lastIndexOf(separator);
        return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1,
                path.length());
    }

    /**
     * Returns the pathname of the parent of this file. This is the path up to
     * but not including the last name. {@code null} is returned if there is no
     * parent.
     * 
     * @return this file's parent pathname or {@code null}.
     */
    public String getParent() {
        int length = path.length(), firstInPath = 0;
        if (separatorChar == '\\' && length > 2 && path.charAt(1) == ':') {
            firstInPath = 2;
        }
        int index = path.lastIndexOf(separatorChar);
        if (index == -1 && firstInPath > 0) {
            index = 2;
        }
        if (index == -1 || path.charAt(length - 1) == separatorChar) {
            return null;
        }
        if (path.indexOf(separatorChar) == index
                && path.charAt(firstInPath) == separatorChar) {
            return path.substring(0, index + 1);
        }
        return path.substring(0, index);
    }

    /**
     * Returns a new file made from the pathname of the parent of this file.
     * This is the path up to but not including the last name. {@code null} is
     * returned when there is no parent.
     * 
     * @return a new file representing this file's parent or {@code null}.
     */
    public File getParentFile() {
        String tempParent = getParent();
        if (tempParent == null) {
            return null;
        }
        return new File(tempParent);
    }

    /**
     * Returns the path of this file.
     * 
     * @return this file's path.
     */
    public String getPath() {
        return path;
    }
    
	/**
	 * Answers the partition size indicated by the path name.
	 * 
	 * @return the partition size counted in bytes, 0L if the path does not
	 *         exist
	 */
	public long getTotalSpace() {
		SecurityManager security = System.getSecurityManager();
		if (security != null) {
			security.checkPermission(new RuntimePermission(
					"getFileSystemAttributes")); //$NON-NLS-1$
		}
		return getTotalSpaceImpl(properPath(true));
	}

	private native long getTotalSpaceImpl(byte[] filePath);
	
	/**
	 * Answers the available bytes of the partition indicated by the path name.
	 * This method checks write permission and other restrictions and offers a
	 * more precise estimate than getFreeSpace(). If the operating system does
	 * not support this information, the result will be the same as the one
	 * returned by getFreeSpace().
	 * 
	 * @return the available bytes of the partition considering platform
	 *         dependent permissions
	 */
	public long getUsableSpace() {
		SecurityManager security = System.getSecurityManager();
		if (security != null) {
			security.checkPermission(new RuntimePermission(
					"getFileSystemAttributes")); //$NON-NLS-1$
		}
		return getUsableSpaceImpl(properPath(true));
	}

	private native long getUsableSpaceImpl(byte[] filePath);

	/**
	 * Answers the available bytes of the partition indicated by the path name.
	 * 
	 * @return the available bytes of the partition
	 */
	public long getFreeSpace() {
		SecurityManager security = System.getSecurityManager();
		if (security != null) {
			security.checkPermission(new RuntimePermission(
					"getFileSystemAttributes")); //$NON-NLS-1$
		}
		return getFreeSpaceImpl(properPath(true));
	}

	private native long getFreeSpaceImpl(byte[] filePath);

    /**
     * Returns an integer hash code for the receiver. Any two objects for which
     * {@code equals} returns {@code true} must return the same hash code.
     * 
     * @return this files's hash value.
     * @see #equals
     */
    @Override
    public int hashCode() {
        if (caseSensitive) {
            return path.hashCode() ^ 1234321;
        }
        return path.toLowerCase().hashCode() ^ 1234321;
    }

    /**
     * Indicates if this file's pathname is absolute. Whether a pathname is
     * absolute is platform specific. On UNIX, absolute paths must start with
     * the character '/'; on Windows it is absolute if either it starts with
     * '\\' (to represent a file server), or a letter followed by a colon.
     * 
     * @return {@code true} if this file's pathname is absolute, {@code false}
     *         otherwise.
     * @see #getPath
     */
    public boolean isAbsolute() {
        if (File.separatorChar == '\\') {
            // for windows
            if (path.length() > 1 && path.charAt(0) == File.separatorChar
                    && path.charAt(1) == File.separatorChar) {
                return true;
            }
            if (path.length() > 2) {
                if (Character.isLetter(path.charAt(0)) && path.charAt(1) == ':'
                        && (path.charAt(2) == '/' || path.charAt(2) == '\\')) {
                    return true;
                }
            }
            return false;
        }

        // for Linux
        return (path.length() > 0 && path.charAt(0) == File.separatorChar);
    }

    /**
     * Indicates if this file represents a <em>directory</em> on the
     * underlying file system.
     * 
     * @return {@code true} if this file is a directory, {@code false}
     *         otherwise.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies read
     *             access to this file.
     */
    public boolean isDirectory() {
        if (path.length() == 0) {
            return false;
        }
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        return isDirectoryImpl(properPath(true));
    }

    private native boolean isDirectoryImpl(byte[] filePath);

    /**
     * Indicates if this file represents a <em>file</em> on the underlying
     * file system.
     * 
     * @return {@code true} if this file is a file, {@code false} otherwise.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies read
     *             access to this file.
     */
    public boolean isFile() {
        if (path.length() == 0) {
            return false;
        }
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        return isFileImpl(properPath(true));
    }

    private native boolean isFileImpl(byte[] filePath);

    /**
     * Returns whether or not this file is a hidden file as defined by the
     * operating system. The notion of "hidden" is system-dependent. For Unix
     * systems a file is considered hidden if its name starts with a ".". For
     * Windows systems there is an explicit flag in the file system for this
     * purpose.
     * 
     * @return {@code true} if the file is hidden, {@code false} otherwise.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies read
     *             access to this file.
     */
    public boolean isHidden() {
        if (path.length() == 0) {
            return false;
        }
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        return isHiddenImpl(properPath(true));
    }

    private native boolean isHiddenImpl(byte[] filePath);

    private native boolean isReadOnlyImpl(byte[] filePath);

    private native boolean isWriteOnlyImpl(byte[] filePath);

    private native byte[] getLinkImpl(byte[] filePath);

    /**
     * Returns the time when this file was last modified, measured in
     * milliseconds since January 1st, 1970, midnight.
     * 
     * @return the time when this file was last modified.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies read
     *             access to this file.
     */
    public long lastModified() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        long result = lastModifiedImpl(properPath(true));
        /* Temporary code to handle both return cases until natives fixed */
        if (result == -1 || result == 0) {
            return 0;
        }
        return result;
    }

    private native long lastModifiedImpl(byte[] filePath);

    /**
     * Sets the time this file was last modified, measured in milliseconds since
     * January 1st, 1970, midnight.
     * 
     * @param time
     *            the last modification time for this file.
     * @return {@code true} if the operation is successful, {@code false}
     *         otherwise.
     * @throws IllegalArgumentException
     *             if {@code time < 0}.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies write
     *             access to this file.
     */
    public boolean setLastModified(long time) {
        if (time < 0) {
            throw new IllegalArgumentException(Msg.getString("K006a")); //$NON-NLS-1$
        }
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkWrite(path);
        }
        return (setLastModifiedImpl(properPath(true), time));
    }

    private native boolean setLastModifiedImpl(byte[] path, long time);

    /**
     * Marks this file or directory to be read-only as defined by the operating
     * system.
     * 
     * @return {@code true} if the operation is successful, {@code false}
     *         otherwise.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies write
     *             access to this file.
     */
    public boolean setReadOnly() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkWrite(path);
        }
        return (setReadOnlyImpl(properPath(true)));
    }

    private native boolean setReadOnlyImpl(byte[] path);

    /**
	 * Manipulates the read permission of the abstract path designated by this
	 * file object.
	 * 
	 * @param readable
	 *            To allow read permission if true, otherwise disallow
	 * @param ownerOnly
	 *            To manipulate read permission only for owner if true,
	 *            otherwise for everyone. The manipulation will apply to
	 *            everyone regardless of this value if the underlying system
	 *            does not distinguish owner and other users.
	 * @return true if and only if the operation succeeded. If the user does not
	 *         have permission to change the access permissions of this abstract
	 *         pathname the operation will fail. If the underlying file system
	 *         does not support read permission and the value of readable is
	 *         false, this operation will fail.
	 * @throws SecurityException -
	 *             If a security manager exists and
	 *             SecurityManager.checkWrite(java.lang.String) disallows write
	 *             permission to this file object
	 * @since 1.6
	 */
	public boolean setReadable(boolean readable, boolean ownerOnly) {
		checkWrite();
		return (setReadableImpl(properPath(true), readable, ownerOnly));
	}

	/**
	 * A convenience method for setReadable(boolean, boolean). An invocation of
	 * this method is the same as file.setReadable(readable, true).
	 * 
	 * @param readable
	 *            To allow read permission if true, otherwise disallow
	 * @return true if and only if the operation succeeded. If the user does not
	 *         have permission to change the access permissions of this abstract
	 *         pathname the operation will fail. If the underlying file system
	 *         does not support read permission and the value of readable is
	 *         false, this operation will fail.
	 * @throws SecurityException -
	 *             If a security manager exists and
	 *             SecurityManager.checkWrite(java.lang.String) disallows write
	 *             permission to this file object
	 * @since 1.6
	 */
	public boolean setReadable(boolean readable) {
		return setReadable(readable, true);
	}
	
	private native boolean setReadableImpl(byte[] path, boolean readable,
			boolean ownerOnly);
	
	/**
	 * Manipulates the write permission of the abstract path designated by this
	 * file object.
	 * 
	 * @param writable
	 *            To allow write permission if true, otherwise disallow
	 * @param ownerOnly
	 *            To manipulate write permission only for owner if true,
	 *            otherwise for everyone. The manipulation will apply to
	 *            everyone regardless of this value if the underlying system
	 *            does not distinguish owner and other users.
	 * @return true if and only if the operation succeeded. If the user does not
	 *         have permission to change the access permissions of this abstract
	 *         pathname the operation will fail.
	 * @throws SecurityException -
	 *             If a security manager exists and
	 *             SecurityManager.checkWrite(java.lang.String) disallows write
	 *             permission to this file object
	 * @since 1.6
	 */
	public boolean setWritable(boolean writable, boolean ownerOnly) {
		checkWrite();
		return (setWritableImpl(properPath(true), writable, ownerOnly));
	}

	private native boolean setWritableImpl(byte[] path, boolean writable,
			boolean ownerOnly);

	/**
	 * A convenience method for setWritable(boolean, boolean). An invocation of
	 * this method is the same as file.setWritable(writable, true).
	 * 
	 * @param writable
	 *            To allow write permission if true, otherwise disallow
	 * @return true if and only if the operation succeeded. If the user does not
	 *         have permission to change the access permissions of this abstract
	 *         pathname the operation will fail.
	 * @throws SecurityException -
	 *             If a security manager exists and
	 *             SecurityManager.checkWrite(java.lang.String) disallows write
	 *             permission to this file object
	 * @since 1.6
	 */
	public boolean setWritable(boolean writable) {
		return setWritable(writable, true);
	}
	
    /**
     * Returns the length of this file in bytes.
     * 
     * @return the number of bytes in this file.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies read
     *             access to this file.
     */
    public long length() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        return lengthImpl(properPath(true));
    }

    private native long lengthImpl(byte[] filePath);

    /**
     * Returns an array of strings with the file names in the directory
     * represented by this file. The result is {@code null} if this file is not
     * a directory.
     * <p>
     * The entries {@code .} and {@code ..} representing the current and parent
     * directory are not returned as part of the list.
     *
     * @return an array of strings with file names or {@code null}.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies read
     *             access to this file.
     * @see #isDirectory
     * @see java.lang.SecurityManager#checkRead(FileDescriptor)
     */
    public java.lang.String[] list() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }

        if (path.length() == 0) {
            return null;
        }

        byte[] bs = properPath(true);
        if (!isDirectoryImpl(bs) || !existsImpl(bs) || isWriteOnlyImpl(bs)) {
            return null;
        }

        byte[][] implList = listImpl(bs);
        if (implList == null) {
            // empty list
            return new String[0];
        }
        String result[] = new String[implList.length];
        for (int index = 0; index < implList.length; index++) {
            result[index] = Util.toUTF8String(implList[index]);
        }
        return result;
    }

    /**
     * Returns an array of files contained in the directory represented by this
     * file. The result is {@code null} if this file is not a directory. The
     * paths of the files in the array are absolute if the path of this file is
     * absolute, they are relative otherwise.
     * 
     * @return an array of files or {@code null}.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies read
     *             access to this file.
     * @see #list
     * @see #isDirectory
     */
    public File[] listFiles() {
        String[] tempNames = list();
        if (tempNames == null) {
            return null;
        }
        int resultLength = tempNames.length;
        File results[] = new File[resultLength];
        for (int i = 0; i < resultLength; i++) {
            results[i] = new File(this, tempNames[i]);
        }
        return results;
    }

    /**
     * Gets a list of the files in the directory represented by this file. This
     * list is then filtered through a FilenameFilter and files with matching
     * names are returned as an array of files. Returns {@code null} if this
     * file is not a directory. If {@code filter} is {@code null} then all
     * filenames match.
     * <p>
     * The entries {@code .} and {@code ..} representing the current and parent
     * directories are not returned as part of the list.
     *
     * @param filter
     *            the filter to match names against, may be {@code null}.
     * @return an array of files or {@code null}.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies read
     *             access to this file.
     * @see #list(FilenameFilter filter)
     * @see #getPath
     * @see #isDirectory
     * @see java.lang.SecurityManager#checkRead(FileDescriptor)
     */
    public File[] listFiles(FilenameFilter filter) {
        String[] tempNames = list(filter);
        if (tempNames == null) {
            return null;
        }
        int resultLength = tempNames.length;
        File results[] = new File[resultLength];
        for (int i = 0; i < resultLength; i++) {
            results[i] = new File(this, tempNames[i]);
        }
        return results;
    }

    /**
     * Gets a list of the files in the directory represented by this file. This
     * list is then filtered through a FileFilter and matching files are
     * returned as an array of files. Returns {@code null} if this file is not a
     * directory. If {@code filter} is {@code null} then all files match.
     * <p>
     * The entries {@code .} and {@code ..} representing the current and parent
     * directories are not returned as part of the list.
     *
     * @param filter
     *            the filter to match names against, may be {@code null}.
     * @return an array of files or {@code null}.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies read
     *             access to this file.
     * @see #getPath
     * @see #isDirectory
     * @see java.lang.SecurityManager#checkRead(FileDescriptor)
     */
    public File[] listFiles(FileFilter filter) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }

        if (path.length() == 0) {
            return null;
        }

        byte[] bs = properPath(true);
        if (!isDirectoryImpl(bs) || !existsImpl(bs) || isWriteOnlyImpl(bs)) {
            return null;
        }

        byte[][] implList = listImpl(bs);
        if (implList == null) {
            return new File[0];
        }
        List<File> tempResult = new ArrayList<File>();
        for (int index = 0; index < implList.length; index++) {
            String aName = Util.toString(implList[index]);
            File aFile = new File(this, aName);
            if (filter == null || filter.accept(aFile)) {
                tempResult.add(aFile);
            }
        }
        return tempResult.toArray(new File[tempResult.size()]);
    }

    /**
     * Gets a list of the files in the directory represented by this file. This
     * list is then filtered through a FilenameFilter and the names of files
     * with matching names are returned as an array of strings. Returns
     * {@code null} if this file is not a directory. If {@code filter} is
     * {@code null} then all filenames match.
     * <p>
     * The entries {@code .} and {@code ..} representing the current and parent
     * directories are not returned as part of the list.
     * 
     * @param filter
     *            the filter to match names against, may be {@code null}.
     * @return an array of files or {@code null}.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies read
     *             access to this file.
     * @see #getPath
     * @see #isDirectory
     * @see java.lang.SecurityManager#checkRead(FileDescriptor)
     */
    public java.lang.String[] list(FilenameFilter filter) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }

        if (path.length() == 0) {
            return null;
        }

        byte[] bs = properPath(true);
        if (!isDirectoryImpl(bs) || !existsImpl(bs) || isWriteOnlyImpl(bs)) {
            return null;
        }

        byte[][] implList = listImpl(bs);
        if (implList == null) {
            // empty list
            return new String[0];
        }
        List<String> tempResult = new ArrayList<String>();
        for (int index = 0; index < implList.length; index++) {
            String aName = Util.toString(implList[index]);
            if (filter == null || filter.accept(this, aName)) {
                tempResult.add(aName);
            }
        }

        return tempResult.toArray(new String[tempResult.size()]);
    }

    private synchronized static native byte[][] listImpl(byte[] path);

    /**
     * Creates the directory named by the trailing filename of this file. Does
     * not create the complete path required to create this directory.
     * 
     * @return {@code true} if the directory has been created, {@code false}
     *         otherwise.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies write
     *             access for this file.
     * @see #mkdirs
     */
    public boolean mkdir() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkWrite(path);
        }
        return mkdirImpl(properPath(true));
    }

    private native boolean mkdirImpl(byte[] filePath);

    /**
     * Creates the directory named by the trailing filename of this file,
     * including the complete directory path required to create this directory.
     * 
     * @return {@code true} if the necessary directories have been created,
     *         {@code false} if the target directory already exists or one of
     *         the directories can not be created.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies write
     *             access for this file.
     * @see #mkdir
     */
    public boolean mkdirs() {
        /* If the terminal directory already exists, answer false */
        if (exists()) {
            return false;
        }

        /* If the receiver can be created, answer true */
        if (mkdir()) {
            return true;
        }

        String parentDir = getParent();
        /* If there is no parent and we were not created, answer false */
        if (parentDir == null) {
            return false;
        }

        /* Otherwise, try to create a parent directory and then this directory */
        return (new File(parentDir).mkdirs() && mkdir());
    }

    /**
     * Creates a new, empty file on the file system according to the path
     * information stored in this file.
     * 
     * @return {@code true} if the file has been created, {@code false} if it
     *         already exists.
     * @throws IOException
     *             if an I/O error occurs or the directory does not exist where
     *             the file should have been created.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies write
     *             access for this file.
     */
    public boolean createNewFile() throws IOException {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkWrite(path);
        }
        if (0 == path.length()) {
            throw new IOException(Msg.getString("KA012")); //$NON-NLS-1$
        }
        int result = newFileImpl(properPath(true));
        switch (result) {
            case 0:
                return true;
            case 1:
                return false;
            default:
                throw new IOException(Msg.getString("K01c2", path)); //$NON-NLS-1$
        }
    }

    private native int newFileImpl(byte[] filePath);

    /**
     * Creates an empty temporary file using the given prefix and suffix as part
     * of the file name. If suffix is {@code null}, {@code .tmp} is used. This
     * method is a convenience method that calls
     * {@link #createTempFile(String, String, File)} with the third argument
     * being {@code null}.
     * 
     * @param prefix
     *            the prefix to the temp file name.
     * @param suffix
     *            the suffix to the temp file name.
     * @return the temporary file.
     * @throws IOException
     *             if an error occurs when writing the file.
     */
    public static File createTempFile(String prefix, String suffix)
            throws IOException {
        return createTempFile(prefix, suffix, null);
    }

    /**
     * Creates an empty temporary file in the given directory using the given
     * prefix and suffix as part of the file name.
     * 
     * @param prefix
     *            the prefix to the temp file name.
     * @param suffix
     *            the suffix to the temp file name.
     * @param directory
     *            the location to which the temp file is to be written, or
     *            {@code null} for the default location for temporary files,
     *            which is taken from the "java.io.tmpdir" system property. It
     *            may be necessary to set this property to an existing, writable
     *            directory for this method to work properly.
     * @return the temporary file.
     * @throws IllegalArgumentException
     *             if the length of {@code prefix} is less than 3.
     * @throws IOException
     *             if an error occurs when writing the file.
     */
    @SuppressWarnings("nls")
    public static File createTempFile(String prefix, String suffix,
            File directory) throws IOException {
        // Force a prefix null check first
        if (prefix.length() < 3) {
            throw new IllegalArgumentException(Msg.getString("K006b"));
        }
        String newSuffix = suffix == null ? ".tmp" : suffix;
        File tmpDirFile;
        if (directory == null) {
            String tmpDir = AccessController.doPrivileged(
                new PriviAction<String>("java.io.tmpdir", "."));
            tmpDirFile = new File(tmpDir);
        } else {
            tmpDirFile = directory;
        }
        File result;
        do {
            result = genTempFile(prefix, newSuffix, tmpDirFile);
        } while (!result.createNewFile());
        return result;
    }

    private static File genTempFile(String prefix, String suffix, File directory) {
        if (counter == 0) {
            int newInt = new SecureRandom().nextInt();
            counter = ((newInt / 65535) & 0xFFFF) + 0x2710;
        }
        StringBuilder newName = new StringBuilder();
        newName.append(prefix);
        newName.append(counter++);
        newName.append(suffix);
        return new File(directory, newName.toString());
    }

    /**
     * Returns a string representing the proper path for this file. If this file
     * path is absolute, the user.dir property is not prepended, otherwise it
     * is.
     * 
     * @param internal
     *            is user.dir internal.
     * @return the proper path.
     */
    byte[] properPath(boolean internal) {
        if (properPath != null) {
            return properPath;
        }

        if (isAbsolute()) {
            byte[] pathBytes = Util.getUTF8Bytes(path);
            return properPath = pathBytes;
        }
        // Check security by getting user.dir when the path is not absolute
        String userdir;
        if (internal) {
            userdir = AccessController.doPrivileged(new PriviAction<String>(
                    "user.dir")); //$NON-NLS-1$
        } else {
            userdir = System.getProperty("user.dir"); //$NON-NLS-1$
        }

        if (path.length() == 0) {
            return properPath = Util.getUTF8Bytes(userdir);
        }
        int length = userdir.length();

        // Handle windows-like path
        if (path.charAt(0) == '\\') {
            if (length > 1 && userdir.charAt(1) == ':') {
                return properPath = Util.getUTF8Bytes(userdir.substring(0, 2)
                        + path);
            }
            path = path.substring(1);
        }

        // Handle separator
        String result = userdir;
        if (userdir.charAt(length - 1) != separatorChar) {
            if (path.charAt(0) != separatorChar) {
                result += separator;
            }
        } else if (path.charAt(0) == separatorChar) {
            result = result.substring(0, length - 2);

        }
        result += path;
        return properPath = Util.getUTF8Bytes(result);
    }

    /**
     * Renames this file to the name represented by the {@code dest} file. This
     * works for both normal files and directories.
     * 
     * @param dest
     *            the file containing the new name.
     * @return {@code true} if the File was renamed, {@code false} otherwise.
     * @throws SecurityException
     *             if a {@code SecurityManager} is installed and it denies write
     *             access for this file or the {@code dest} file.
     */
    public boolean renameTo(java.io.File dest) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkWrite(path);
            security.checkWrite(dest.path);
        }
        return renameToImpl(properPath(true), dest.properPath(true));
    }

    private native boolean renameToImpl(byte[] pathExist, byte[] pathNew);

    /**
     * Returns a string containing a concise, human-readable description of this
     * file.
     * 
     * @return a printable representation of this file.
     */
    @Override
    public String toString() {
        return path;
    }

    /**
     * Returns a Uniform Resource Identifier for this file. The URI is system
     * dependent and may not be transferable between different operating / file
     * systems.
     * 
     * @return an URI for this file.
     */
    @SuppressWarnings("nls")
    public URI toURI() {
        String name = getAbsoluteName();
        try {
            if (!name.startsWith("/")) {
                // start with sep.
                return new URI("file", null, new StringBuilder(
                        name.length() + 1).append('/').append(name).toString(),
                        null, null);
            } else if (name.startsWith("//")) {
                return new URI("file", "", name, null); // UNC path
            }
            return new URI("file", null, name, null, null);
        } catch (URISyntaxException e) {
            // this should never happen
            return null;
        }
    }

    /**
     * Returns a Uniform Resource Locator for this file. The URL is system
     * dependent and may not be transferable between different operating / file
     * systems.
     * 
     * @return a URL for this file.
     * @throws java.net.MalformedURLException
     *             if the path cannot be transformed into a URL.
     *
     * @deprecated use {@link #toURI} and {@link java.net.URI#toURL} to get
     * correct escaping of illegal characters.
     */
    @Deprecated
    @SuppressWarnings("nls")
    public URL toURL() throws java.net.MalformedURLException {
        String name = getAbsoluteName();
        if (!name.startsWith("/")) {
            // start with sep.
            return new URL(
                    "file", EMPTY_STRING, -1, new StringBuilder(name.length() + 1) //$NON-NLS-1$ 
                            .append('/').append(name).toString(), null);
        } else if (name.startsWith("//")) {
            return new URL("file:" + name); // UNC path
        }
        return new URL("file", EMPTY_STRING, -1, name, null);
    }

    private String getAbsoluteName() {
        File f = getAbsoluteFile();
        String name = f.getPath();

        if (f.isDirectory() && name.charAt(name.length() - 1) != separatorChar) {
            // Directories must end with a slash
            name = new StringBuilder(name.length() + 1).append(name)
                    .append('/').toString();
        }
        if (separatorChar != '/') { // Must convert slashes.
            name = name.replace(separatorChar, '/');
        }
        return name;
    }

    private void writeObject(ObjectOutputStream stream) throws IOException {
        stream.defaultWriteObject();
        stream.writeChar(separatorChar);

    }

    private void readObject(ObjectInputStream stream) throws IOException,
            ClassNotFoundException {
        stream.defaultReadObject();
        char inSeparator = stream.readChar();
        path = path.replace(inSeparator, separatorChar);
    }
    
    /**
	 * Manipulates the execute permission of the abstract path designated by
	 * this file object.
	 * 
	 * @param executable
	 *            To allow execute permission if true, otherwise disallow
	 * @param ownerOnly
	 *            To manipulate execute permission only for owner if true,
	 *            otherwise for everyone. The manipulation will apply to
	 *            everyone regardless of this value if the underlying system
	 *            does not distinguish owner and other users.
	 * @return true if and only if the operation succeeded. If the user does not
	 *         have permission to change the access permissions of this abstract
	 *         pathname the operation will fail. If the underlying file system
	 *         does not support execute permission and the value of executable
	 *         is false, this operation will fail.
	 * @throws SecurityException -
	 *             If a security manager exists and
	 *             SecurityManager.checkWrite(java.lang.String) disallows write
	 *             permission to this file object
	 * @since 1.6
	 */
	public boolean setExecutable(boolean executable, boolean ownerOnly) {
		checkWrite();
		return (setExecutableImpl(properPath(true), executable, ownerOnly));
	}

	/**
	 * A convenience method for setExecutable(boolean, boolean). An invocation
	 * of this method is the same as file.setExecutable(executable, true).
	 * 
	 * @param executable
	 *            To allow execute permission if true, otherwise disallow
	 * @return true if and only if the operation succeeded. If the user does not
	 *         have permission to change the access permissions of this abstract
	 *         pathname the operation will fail. If the underlying file system
	 *         does not support execute permission and the value of executable
	 *         is false, this operation will fail.
	 * @throws SecurityException -
	 *             If a security manager exists and
	 *             SecurityManager.checkWrite(java.lang.String) disallows write
	 *             permission to this file object
	 * @since 1.6
	 */
	public boolean setExecutable(boolean executable) {
		return setExecutable(executable, true);
	}

	private native boolean setExecutableImpl(byte[] path, boolean executable,
			boolean ownerOnly);
	
	  

    /**
     * Answers a boolean indicating whether or not the current context is
     * allowed to execute this File.
     * 
     * @return <code>true</code> if this File can be executed,
     *         <code>false</code> otherwise.
     * 
     * @throws SecurityException
     *             If a security manager exists and
     *             SecurityManager.checkExec(java.lang.String) disallows read
     *             permission to this file object
     * @see java.lang.SecurityManager#checkExec(String)
     * 
     * @since 1.6
     */
    public boolean canExecute() {
        checkExec();
        return exists() && isExecutableImpl(properPath(true));
    }

    private native boolean isExecutableImpl(byte[] filePath);

    private void checkExec() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkExec(path);
        }
    }

    private void checkWrite() {
		SecurityManager security = System.getSecurityManager();
		if (security != null) {
			security.checkWrite(path);
		}
	}

}
