/*
 * 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 org.apache.commons.vfs2.provider;


import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.vfs2.Capability;
import org.apache.commons.vfs2.FileContent;
import org.apache.commons.vfs2.FileContentInfoFactory;
import org.apache.commons.vfs2.FileName;
import org.apache.commons.vfs2.FileNotFolderException;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSelector;
import org.apache.commons.vfs2.FileSystem;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileType;
import org.apache.commons.vfs2.FileUtil;
import org.apache.commons.vfs2.NameScope;
import org.apache.commons.vfs2.RandomAccessContent;
import org.apache.commons.vfs2.Selectors;
import org.apache.commons.vfs2.operations.DefaultFileOperations;
import org.apache.commons.vfs2.operations.FileOperations;
import org.apache.commons.vfs2.util.FileObjectUtils;
import org.apache.commons.vfs2.util.RandomAccessMode;

/**
 * A partial file object implementation.
 *
 * @param <AFS> An AbstractFileSystem subclass
 */
public abstract class AbstractFileObject<AFS extends AbstractFileSystem> implements FileObject
{
    /*
     * TODO - Chop this class up - move all the protected methods to several
     * interfaces, so that structure and content can be separately overridden.
     *
     * TODO - Check caps in methods like getChildren(), etc, and give better error messages
     * (eg 'this file type does not support listing children', vs 'this is not a folder')
     */

    private static final FileName[] EMPTY_FILE_ARRAY = {};

    private static final int INITIAL_LIST_SIZE = 5;

    private final AbstractFileName fileName;
    private final AFS fs;

    private FileContent content;
    // Cached info
    private boolean attached;
    private FileType type;

    private FileObject parent;
    // Changed to hold only the name of the children and let the object
    // go into the global files cache
    // private FileObject[] children;
    private FileName[] children;

    private List<Object> objects;

    /**
     * FileServices instance.
     */
    private FileOperations operations;

    /**
     *
     * @param name the file name - muse be an instance of {@link AbstractFileName}
     * @param fs the file system
     * @throws ClassCastException if {@code name} is not an instance of {@link AbstractFileName}
     */
    protected AbstractFileObject(final AbstractFileName name,
                                 final AFS fs)
    {
        this.fileName = name;
        this.fs = fs;
        fs.fileObjectHanded(this);
    }

    /**
     * Traverses a file.
     */
    private static void traverse(final DefaultFileSelectorInfo fileInfo,
                                 final FileSelector selector,
                                 final boolean depthwise,
                                 final List<FileObject> selected)
        throws Exception
    {
        // Check the file itself
        final FileObject file = fileInfo.getFile();
        final int index = selected.size();

        // If the file is a folder, traverse it
        if (file.getType().hasChildren() && selector.traverseDescendents(fileInfo))
        {
            final int curDepth = fileInfo.getDepth();
            fileInfo.setDepth(curDepth + 1);

            // Traverse the children
            final FileObject[] children = file.getChildren();
            for (final FileObject child : children)
            {
                fileInfo.setFile(child);
                traverse(fileInfo, selector, depthwise, selected);
            }

            fileInfo.setFile(file);
            fileInfo.setDepth(curDepth);
        }

        // Add the file if doing depthwise traversal
        if (selector.includeFile(fileInfo))
        {
            if (depthwise)
            {
                // Add this file after its descendants
                selected.add(file);
            }
            else
            {
                // Add this file before its descendants
                selected.add(index, file);
            }
        }
    }

    /**
     * Attaches to the file.
     * @throws FileSystemException if an error occurs.
     */
    private void attach() throws FileSystemException
    {
        synchronized (fs)
        {
            if (attached)
            {
                return;
            }

            try
            {
                // Attach and determine the file type
                doAttach();
                attached = true;
                // now the type could already be injected by doAttach (e.g from parent to child)

                /* VFS-210: determine the type when really asked fore
                if (type == null)
                {
                    setFileType(doGetType());
                }
                if (type == null)
                {
                    setFileType(FileType.IMAGINARY);
                }
                */
            }
            catch (final Exception exc)
            {
                throw new FileSystemException("vfs.provider/get-type.error", exc, fileName);
            }

            // fs.fileAttached(this);
        }
    }

    /**
     * Queries the object if a simple rename to the filename of {@code newfile}
     * is possible.
     *
     * @param newfile the new filename
     * @return true if rename is possible
     */
    @Override
    public boolean canRenameTo(final FileObject newfile)
    {
        return fs == newfile.getFileSystem();
    }

    /**
     * Notifies the file that its children have changed.
     * @param childName The name of the child.
     * @param newType The type of the child.
     * @throws Exception if an error occurs.
     */
    protected void childrenChanged(final FileName childName, final FileType newType) throws Exception
    {
        // TODO - this may be called when not attached

        if (children != null && childName != null && newType != null)
        {
            // TODO - figure out if children[] can be replaced by list
            final ArrayList<FileName> list = new ArrayList<FileName>(Arrays.asList(children));
            if (newType.equals(FileType.IMAGINARY))
            {
                list.remove(childName);
            }
            else
            {
                list.add(childName);
            }
            children = new FileName[list.size()];
            list.toArray(children);
        }

        // removeChildrenCache();
        onChildrenChanged(childName, newType);
    }

    /**
     * Closes this file, and its content.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public void close() throws FileSystemException
    {
        FileSystemException exc = null;

        // Close the content
        if (content != null)
        {
            try
            {
                content.close();
                content = null;
            }
            catch (final FileSystemException e)
            {
                exc = e;
            }
        }

        // Detach from the file
        try
        {
            detach();
        }
        catch (final Exception e)
        {
            exc = new FileSystemException("vfs.provider/close.error", fileName, e);
        }

        if (exc != null)
        {
            throw exc;
        }
    }

    /**
     * Compares two FileObjects (ignores case).
     *
     * @param file
     *            the object to compare.
     * @return a negative integer, zero, or a positive integer when this object is less than, equal to, or greater than
     *         the given object.
     */
    @Override
    public int compareTo(final FileObject file)
    {
        if (file == null)
        {
            return 1;
        }
        return this.toString().compareToIgnoreCase(file.toString());
    }

    /**
     * Copies another file to this file.
     *
     * @param file The FileObject to copy.
     * @param selector The FileSelector.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public void copyFrom(final FileObject file, final FileSelector selector)
        throws FileSystemException
    {
        if (!file.exists())
        {
            throw new FileSystemException("vfs.provider/copy-missing-file.error", file);
        }

        // Locate the files to copy across
        final ArrayList<FileObject> files = new ArrayList<FileObject>();
        file.findFiles(selector, false, files);

        // Copy everything across
        for (final FileObject srcFile : files)
        {
            // Determine the destination file
            final String relPath = file.getName().getRelativeName(srcFile.getName());
            final FileObject destFile = resolveFile(relPath, NameScope.DESCENDENT_OR_SELF);

            // Clean up the destination file, if necessary
            if (destFile.exists() && destFile.getType() != srcFile.getType())
            {
                // The destination file exists, and is not of the same type,
                // so delete it
                // TODO - add a pluggable policy for deleting and overwriting existing files
                destFile.deleteAll();
            }

            // Copy across
            try
            {
                if (srcFile.getType().hasContent())
                {
                    FileUtil.copyContent(srcFile, destFile);
                }
                else if (srcFile.getType().hasChildren())
                {
                    destFile.createFolder();
                }
            }
            catch (final IOException e)
            {
                throw new FileSystemException("vfs.provider/copy-file.error", e, srcFile, destFile);
            }
        }
    }

    /**
     * Creates this file, if it does not exist.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public void createFile() throws FileSystemException
    {
        synchronized (fs)
        {
            try
            {
                // VFS-210: We do not want to trunc any existing file, checking for its existence is
                // still required
                if (exists() && !isFile())
                {
                    throw new FileSystemException("vfs.provider/create-file.error", fileName);
                }

                if (!exists())
                {
                    getOutputStream().close();
                    endOutput();
                }
            }
            catch (final RuntimeException re)
            {
                throw re;
            }
            catch (final Exception e)
            {
                throw new FileSystemException("vfs.provider/create-file.error", fileName, e);
            }
        }
    }

    /**
     * Creates this folder, if it does not exist.  Also creates any ancestor
     * files which do not exist.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public void createFolder() throws FileSystemException
    {
        synchronized (fs)
        {
            // VFS-210: we create a folder only if it does not already exist. So this check should be safe.
            if (getType().hasChildren())
            {
                // Already exists as correct type
                return;
            }
            if (getType() != FileType.IMAGINARY)
            {
                throw new FileSystemException("vfs.provider/create-folder-mismatched-type.error", fileName);
            }
            /* VFS-210: checking for writeable is not always possible as the security constraint might
               be more complex
            if (!isWriteable())
            {
                throw new FileSystemException("vfs.provider/create-folder-read-only.error", name);
            }
            */

            // Traverse up the hierarchy and make sure everything is a folder
            final FileObject parent = getParent();
            if (parent != null)
            {
                parent.createFolder();
            }

            try
            {
                // Create the folder
                doCreateFolder();

                // Update cached info
                handleCreate(FileType.FOLDER);
            }
            catch (final RuntimeException re)
            {
                throw re;
            }
            catch (final Exception exc)
            {
                throw new FileSystemException("vfs.provider/create-folder.error", fileName, exc);
            }
        }
    }

    /**
     * Deletes this file.
     * <p>
     * TODO - This will not fail if this is a non-empty folder.
     *
     * @return true if this object has been deleted
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public boolean delete() throws FileSystemException
    {
        return delete(Selectors.SELECT_SELF) > 0;
    }

    /**
     * Deletes this file, and all children matching the {@code selector}.
     *
     * @param selector The FileSelector.
     * @return the number of deleted files.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public int delete(final FileSelector selector) throws FileSystemException
    {
        int nuofDeleted = 0;

        /* VFS-210
        if (getType() == FileType.IMAGINARY)
        {
            // File does not exist
            return nuofDeleted;
        }
        */

        // Locate all the files to delete
        final ArrayList<FileObject> files = new ArrayList<FileObject>();
        findFiles(selector, true, files);

        // Delete 'em
        final int count = files.size();
        for (int i = 0; i < count; i++)
        {
            final AbstractFileObject file = FileObjectUtils.getAbstractFileObject(files.get(i));
            // file.attach();

            // VFS-210: It seems impossible to me that findFiles will return a list with hidden files/directories
            // in it, else it would not be hidden. Checking for the file-type seems ok in this case
            // If the file is a folder, make sure all its children have been deleted
            if (file.getType().hasChildren() && file.getChildren().length != 0)
            {
                // Skip - as the selector forced us not to delete all files
                continue;
            }

            // Delete the file
            if (file.deleteSelf())
            {
                nuofDeleted++;
            }
        }

        return nuofDeleted;
    }

    /**
     * Deletes this file and all children. Shorthand for {@code delete(Selectors.SELECT_ALL)}
     *
     * @return the number of deleted files.
     * @throws FileSystemException if an error occurs.
     * @see #delete(FileSelector)
     * @see Selectors#SELECT_ALL
     */
    @Override
    public int deleteAll() throws FileSystemException
    {
        return this.delete(Selectors.SELECT_ALL);
    }

    /**
     * Deletes this file, once all its children have been deleted
     *
     * @return true if this file has been deleted
     * @throws FileSystemException if an error occurs.
     */
    private boolean deleteSelf() throws FileSystemException
    {
        synchronized (fs)
        {
            //Its possible to delete a read-only file if you have write-execute access to the directory

            /* VFS-210
            if (getType() == FileType.IMAGINARY)
            {
                // File does not exist
                return false;
            }
            */

            try
            {
                // Delete the file
                doDelete();

                // Update cached info
                handleDelete();
            }
            catch (final RuntimeException re)
            {
                throw re;
            }
            catch (final Exception exc)
            {
                throw new FileSystemException("vfs.provider/delete.error", exc, fileName);
            }

            return true;
        }
    }

    /**
     * Detaches this file, invalidating all cached info.  This will force
     * a call to {@link #doAttach} next time this file is used.
     * @throws Exception if an error occurs.
     */
    private void detach() throws Exception
    {
        synchronized (fs)
        {
            if (attached)
            {
                try
                {
                    doDetach();
                }
                finally
                {
                    attached = false;
                    setFileType(null);
                    parent = null;

                    // fs.fileDetached(this);

                    removeChildrenCache();
                    // children = null;
                }
            }
        }
    }

    /**
     * Attaches this file object to its file resource.
     * <p>
     * This method is called before any of the doBlah() or onBlah() methods.
     * Sub-classes can use this method to perform lazy initialisation.
     * <p>
     * This implementation does nothing.
     *
     * @throws Exception if an error occurs.
     */
    protected void doAttach() throws Exception
    {
    }

    /**
     * Create a FileContent implementation.
     * @return The FileContent.
     * @throws FileSystemException if an error occurs.
     * @since 2.0
     */
    protected FileContent doCreateFileContent() throws FileSystemException
    {
        return new DefaultFileContent(this, getFileContentInfoFactory());
    }

    /**
     * Creates this file as a folder.  Is only called when:
     * <ul>
     * <li>{@link #doGetType} returns {@link FileType#IMAGINARY}.</li>
     * <li>The parent folder exists and is writeable, or this file is the
     * root of the file system.</li>
     * </ul>
     * This implementation throws an exception.
     *
     * @throws Exception if an error occurs.
     */
    protected void doCreateFolder() throws Exception
    {
        throw new FileSystemException("vfs.provider/create-folder-not-supported.error");
    }

    /**
     * Deletes the file.  Is only called when:
     * <ul>
     * <li>{@link #doGetType} does not return {@link FileType#IMAGINARY}.</li>
     * <li>{@link #doIsWriteable} returns true.</li>
     * <li>This file has no children, if a folder.</li>
     * </ul>
     * This implementation throws an exception.

     * @throws Exception if an error occurs.
     */
    protected void doDelete() throws Exception
    {
        throw new FileSystemException("vfs.provider/delete-not-supported.error");
    }

    /**
     * Detaches this file object from its file resource.
     * <p>
     * Called when this file is closed.  Note that the file object may be
     * reused later, so should be able to be reattached.
     * <p>
     * This implementation does nothing.
     *
     * @throws Exception if an error occurs.
     */
    protected void doDetach() throws Exception
    {
    }

    /**
     * Returns the attributes of this file.  Is only called if {@link #doGetType}
     * does not return {@link FileType#IMAGINARY}.
     * <p>
     * This implementation always returns an empty map.
     *
     * @return The attributes of the file.
     * @throws Exception if an error occurs.
     */
    protected Map<String, Object> doGetAttributes() throws Exception
    {
        return Collections.emptyMap();
    }

    /**
     * Returns the certificates used to sign this file.  Is only called if
     * {@link #doGetType} does not return {@link FileType#IMAGINARY}.
     * <p>
     * This implementation always returns null.
     *
     * @return The certificates used to sign the file.
     * @throws Exception if an error occurs.
     */
    protected Certificate[] doGetCertificates() throws Exception
    {
        return null;
    }

    /**
     * Returns the size of the file content (in bytes).  Is only called if
     * {@link #doGetType} returns {@link FileType#FILE}.
     * @return The size of the file in bytes.
     * @throws Exception if an error occurs.
     */
    protected abstract long doGetContentSize() throws Exception;

    /**
     * Creates an input stream to read the file content from.  Is only called
     * if {@link #doGetType} returns {@link FileType#FILE}.
     * <p>
     * It is guaranteed that there are no open output streams for this file
     * when this method is called.
     * <p>
     * The returned stream does not have to be buffered.
     *
     * @return An InputStream to read the file content.
     * @throws Exception if an error occurs.
     */
    protected abstract InputStream doGetInputStream() throws Exception;

    /**
     * Returns the last modified time of this file.  Is only called if
     * {@link #doGetType} does not return {@link FileType#IMAGINARY}.
     * <p>
     * This implementation throws an exception.
     *
     * @return The last modification time.
     * @throws Exception if an error occurs.
     */
    protected long doGetLastModifiedTime() throws Exception
    {
        throw new FileSystemException("vfs.provider/get-last-modified-not-supported.error");
    }

    /**
     * Creates an output stream to write the file content to.  Is only
     * called if:
     * <ul>
     * <li>{@link #doIsWriteable} returns true.
     * <li>{@link #doGetType} returns {@link FileType#FILE}, or
     * {@link #doGetType} returns {@link FileType#IMAGINARY}, and the file's
     * parent exists and is a folder.
     * </ul>
     * It is guaranteed that there are no open stream (input or output) for
     * this file when this method is called.
     * <p>
     * The returned stream does not have to be buffered.
     * <p>
     * This implementation throws an exception.
     *
     * @param bAppend true if the file should be appended to, false if it should be overwritten.
     * @return An OutputStream to write to the file.
     * @throws Exception if an error occurs.
     */
    protected OutputStream doGetOutputStream(final boolean bAppend) throws Exception
    {
        throw new FileSystemException("vfs.provider/write-not-supported.error");
    }

    /**
     * Creates access to the file for random i/o.  Is only called
     * if {@link #doGetType} returns {@link FileType#FILE}.
     * <p>
     * It is guaranteed that there are no open output streams for this file
     * when this method is called.
     *
     * @param mode The mode to access the file.
     * @return The RandomAccessContext.
     * @throws Exception if an error occurs.
     */
    protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception
    {
        throw new FileSystemException("vfs.provider/random-access-not-supported.error");
    }

    /**
     * Determines the type of this file.  Must not return null.  The return
     * value of this method is cached, so the implementation can be expensive.
     * @return the type of the file.
     * @throws Exception if an error occurs.
     */
    protected abstract FileType doGetType() throws Exception;

    /**
     * Determines if this file is executable.  Is only called if {@link #doGetType}
     * does not return {@link FileType#IMAGINARY}.
     * <p>
     * This implementation always returns false.
     *
     * @return true if the file is executable, false otherwise.
     * @throws Exception if an error occurs.
     */
    protected boolean doIsExecutable() throws Exception
    {
        return false;
    }

    /**
     * Determines if this file is hidden.  Is only called if {@link #doGetType}
     * does not return {@link FileType#IMAGINARY}.
     * <p>
     * This implementation always returns false.
     *
     * @return true if the file is hidden, false otherwise.
     * @throws Exception if an error occurs.
     */
    protected boolean doIsHidden() throws Exception
    {
        return false;
    }

    /**
     * Determines if this file can be read.  Is only called if {@link #doGetType}
     * does not return {@link FileType#IMAGINARY}.
     * <p>
     * This implementation always returns true.
     *
     * @return true if the file is readable, false otherwise.
     * @throws Exception if an error occurs.
     */
    protected boolean doIsReadable() throws Exception
    {
        return true;
    }

    /**
     * Checks if this fileObject is the same file as {@code destFile} just with a different
     * name. E.g. for case insensitive filesystems like windows.
     *
     * @param destFile The file to compare to.
     * @return true if the FileObjects are the same.
     * @throws FileSystemException if an error occurs.
     */
    protected boolean doIsSameFile(final FileObject destFile) throws FileSystemException
    {
        return false;
    }

    /**
     * Determines if this file can be written to.  Is only called if
     * {@link #doGetType} does not return {@link FileType#IMAGINARY}.
     * <p>
     * This implementation always returns true.
     *
     * @return true if the file is writable.
     * @throws Exception if an error occurs.
     */
    protected boolean doIsWriteable() throws Exception
    {
        return true;
    }

    /**
     * Lists the children of this file. Is only called if {@link #doGetType}
     * returns {@link FileType#FOLDER}. The return value of this method
     * is cached, so the implementation can be expensive.
     *
     * @return a possible empty String array if the file is a directory or null or an exception if the
     * file is not a directory or can't be read.
     * @throws Exception if an error occurs.
     */
    protected abstract String[] doListChildren() throws Exception;

    /**
     * Lists the children of this file.
     * <p>
     * Is only called if {@link #doGetType} returns {@link FileType#FOLDER}.
     * <p>
     * The return value of this method is cached, so the implementation can be expensive.<br>
     * Other than {@code doListChildren} you could return FileObject's to e.g. reinitialize the
     * type of the file.
     * <p>
     * (Introduced for Webdav: "permission denied on resource" during getType())
     *
     * @return The children of this FileObject.
     * @throws Exception if an error occurs.
     */
    protected FileObject[] doListChildrenResolved() throws Exception
    {
        return null;
    }

    /**
     * Removes an attribute of this file.
     * <p>
     * Is only called if {@link #doGetType} does not return {@link FileType#IMAGINARY}.
     * <p>
     * This implementation throws an exception.
     *
     * @param attrName The name of the attribute to remove.
     * @throws Exception if an error occurs.
     * @since 2.0
     */
    protected void doRemoveAttribute(final String attrName) throws Exception
    {
        throw new FileSystemException("vfs.provider/remove-attribute-not-supported.error");
    }

    /**
     * Renames the file.
     * <p>
     * Is only called when:
     * <ul>
     * <li>{@link #doIsWriteable} returns true.</li>
     * </ul>
     * <p>
     * This implementation throws an exception.
     *
     * @param newFile A FileObject with the new file name.
     * @throws Exception if an error occurs.
     */
    protected void doRename(final FileObject newFile) throws Exception
    {
        throw new FileSystemException("vfs.provider/rename-not-supported.error");
    }

    /**
     * Sets an attribute of this file.
     * <p>
     * Is only called if {@link #doGetType} does not return {@link FileType#IMAGINARY}.
     * <p>
     * This implementation throws an exception.
     *
     * @param attrName The attribute name.
     * @param value The value to be associated with the attribute name.
     * @throws Exception if an error occurs.
     */
    protected void doSetAttribute(final String attrName, final Object value) throws Exception
    {
        throw new FileSystemException("vfs.provider/set-attribute-not-supported.error");
    }

    /**
     * Make the file executable.
     * <p>
     * Only called if {@link #doGetType} does not return {@link FileType#IMAGINARY}.
     * <p>
     * This implementation returns false.
     *
     * @param executable True to allow access, false to disallow.
     * @param ownerOnly If {@code true}, the permission applies only to the owner; otherwise, it applies to everybody.
     * @return true if the operation succeeded.
     * @throws Exception Any Exception thrown is wrapped in FileSystemException.
     * @see #setExecutable(boolean, boolean)
     * @since 2.1
     */
    protected boolean doSetExecutable(final boolean executable, final boolean ownerOnly) throws Exception
    {
        return false;
    }

    /**
     * Sets the last modified time of this file.
     * <p>
     * Is only called if {@link #doGetType} does not return {@link FileType#IMAGINARY}.
     * <p>
     * This implementation throws an exception.
     *
     * @param modtime The last modification time.
     * @return true if the time was set.
     * @throws Exception Any Exception thrown is wrapped in FileSystemException.
     */
    protected boolean doSetLastModifiedTime(final long modtime) throws Exception
    {
        throw new FileSystemException("vfs.provider/set-last-modified-not-supported.error");
    }

    /**
     * Make the file or folder readable.
     * <p>
     * Only called if {@link #doGetType} does not return {@link FileType#IMAGINARY}.
     * <p>
     * This implementation returns false.
     *
     * @param readable
     *            True to allow access, false to disallow
     * @param ownerOnly
     *            If {@code true}, the permission applies only to the owner; otherwise, it applies to everybody.
     * @return true if the operation succeeded
     * @throws Exception Any Exception thrown is wrapped in FileSystemException.
     * @see #setReadable(boolean, boolean)
     * @since 2.1
     */
    protected boolean doSetReadable(final boolean readable, final boolean ownerOnly) throws Exception
    {
        return false;
    }

    /**
     * Make the file or folder writeable.
     * <p>
     * Only called if {@link #doGetType} does not return {@link FileType#IMAGINARY}.
     *
     * @param writable True to allow access, false to disallow
     * @param ownerOnly If {@code true}, the permission applies only to the owner; otherwise, it applies to everybody.
     * @return true if the operation succeeded
     * @throws Exception Any Exception thrown is wrapped in FileSystemException.
     * @see #setWritable(boolean, boolean)
     * @since 2.1
     */
    protected boolean doSetWritable(final boolean writable, final boolean ownerOnly) throws Exception
    {
        return false;
    }

    /**
     * Called when the output stream for this file is closed.
     * @throws Exception if an error occurs.
     */
    protected void endOutput() throws Exception
    {
        if (getType() == FileType.IMAGINARY)
        {
            // File was created
            handleCreate(FileType.FILE);
        }
        else
        {
            // File has changed
            onChange();
        }
    }

    /**
     * Determines if the file exists.
     * @return true if the file exists, false otherwise,
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public boolean exists() throws FileSystemException
    {
        return getType() != FileType.IMAGINARY;
    }

    private FileName[] extractNames(final FileObject[] objects)
    {
        if (objects == null)
        {
            return null;
        }

        final FileName[] names = new FileName[objects.length];
        for (int iterObjects = 0; iterObjects < objects.length; iterObjects++)
        {
            names[iterObjects] = objects[iterObjects].getName();
        }

        return names;
    }

    @Override
    protected void finalize() throws Throwable
    {
        fs.fileObjectDestroyed(this);

        super.finalize();
    }


    /**
     * Finds the set of matching descendants of this file, in depthwise
     * order.
     *
     * @param selector The FileSelector.
     * @return list of files or null if the base file (this object) do not exist
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileObject[] findFiles(final FileSelector selector) throws FileSystemException
    {
        final List<FileObject> list = this.listFiles(selector);
        return list == null ? null : list.toArray(new FileObject[list.size()]);
    }

    /**
     * Traverses the descendants of this file, and builds a list of selected
     * files.
     * @param selector The FileSelector.
     * @param depthwise if true files are added after their descendants, before otherwise.
     * @param selected A List of the located FileObjects.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public void findFiles(final FileSelector selector,
                          final boolean depthwise,
                          final List<FileObject> selected) throws FileSystemException
    {
        try
        {
            if (exists())
            {
                // Traverse starting at this file
                final DefaultFileSelectorInfo info = new DefaultFileSelectorInfo();
                info.setBaseFolder(this);
                info.setDepth(0);
                info.setFile(this);
                traverse(info, selector, depthwise, selected);
            }
        }
        catch (final Exception e)
        {
            throw new FileSystemException("vfs.provider/find-files.error", fileName, e);
        }
    }

    /**
     * Returns the file system this file belongs to.
     * @return The FileSystem this file is associated with.
     */
    protected AFS getAbstractFileSystem()
    {
        return fs;
    }

    /**
     * Returns a child of this file.
     * @param name The name of the child to locate.
     * @return The FileObject for the file or null if the child does not exist.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileObject getChild(final String name) throws FileSystemException
    {
        // TODO - use a hashtable when there are a large number of children
        final FileObject[] children = getChildren();
        for (final FileObject element : children)
        {
            final FileName child = element.getName();
            // TODO - use a comparator to compare names
            if (child.getBaseName().equals(name))
            {
                return resolveFile(child);
            }
        }
        return null;
    }

    /**
     * Returns the children of the file.
     * @return an array of FileObjects, one per child.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileObject[] getChildren() throws FileSystemException
    {
        synchronized (fs)
        {
            // VFS-210
            if (!fs.hasCapability(Capability.LIST_CHILDREN))
            {
                throw new FileNotFolderException(fileName);
            }

            /* VFS-210
            if (!getType().hasChildren())
            {
                throw new FileSystemException("vfs.provider/list-children-not-folder.error", name);
            }
            */
            attach();

            // Use cached info, if present
            if (children != null)
            {
                return resolveFiles(children);
            }

            // allow the filesystem to return resolved children. e.g. prefill type for webdav
            FileObject[] childrenObjects;
            try
            {
                childrenObjects = doListChildrenResolved();
                children = extractNames(childrenObjects);
            }
            catch (final FileSystemException exc)
            {
                // VFS-210
                throw exc;
            }
            catch (final Exception exc)
            {
                throw new FileSystemException("vfs.provider/list-children.error", exc, fileName);
            }

            if (childrenObjects != null)
            {
                return childrenObjects;
            }

            // List the children
            final String[] files;
            try
            {
                files = doListChildren();
            }
            catch (final FileSystemException exc)
            {
                // VFS-210
                throw exc;
            }
            catch (final Exception exc)
            {
                throw new FileSystemException("vfs.provider/list-children.error", exc, fileName);
            }

            if (files == null)
            {
                // VFS-210
                // honor the new doListChildren contract
                // return null;
                throw new FileNotFolderException(fileName);
            }
            else if (files.length == 0)
            {
                // No children
                children = EMPTY_FILE_ARRAY;
            }
            else
            {
                // Create file objects for the children
                final FileName[] cache = new FileName[files.length];
                for (int i = 0; i < files.length; i++)
                {
                    final String file = files[i];
                    cache[i] = fs.getFileSystemManager().resolveName(fileName, file, NameScope.CHILD);
                }
                // VFS-285: only assign the children filenames after all of them have been
                // resolved successfully to prevent an inconsistent internal state
                children = cache;
            }

            return resolveFiles(children);
        }
    }

    /**
     * Returns the file's content.
     * @return the FileContent for this FileObject.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileContent getContent() throws FileSystemException
    {
        synchronized (fs)
        {
            attach();
            if (content == null)
            {
                content = doCreateFileContent();
            }
            return content;
        }
    }

    /**
     * create the filecontentinfo implementation.
     * @return The FileContentInfoFactory.
     */
    protected FileContentInfoFactory getFileContentInfoFactory()
    {
        return fs.getFileSystemManager().getFileContentInfoFactory();
    }

    /**
     * @return FileOperations interface that provides access to the operations
     *         API.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileOperations getFileOperations() throws FileSystemException
    {
        if (operations == null)
        {
            operations = new DefaultFileOperations(this);
        }

        return operations;
    }

    /**
     * Returns the file system this file belongs to.
     * @return The FileSystem this file is associated with.
     */
    @Override
    public FileSystem getFileSystem()
    {
        return fs;
    }

    /**
     * Returns an input stream to use to read the content of the file.
     * @return The InputStream to access this file's content.
     * @throws FileSystemException if an error occurs.
     */
    public InputStream getInputStream() throws FileSystemException
    {
        /* VFS-210
        if (!getType().hasContent())
        {
            throw new FileSystemException("vfs.provider/read-not-file.error", name);
        }
        if (!isReadable())
        {
            throw new FileSystemException("vfs.provider/read-not-readable.error", name);
        }
        */

        // Get the raw input stream
        try
        {
            return doGetInputStream();
        }
        catch (final org.apache.commons.vfs2.FileNotFoundException exc)
        {
            throw new org.apache.commons.vfs2.FileNotFoundException(fileName, exc);
        }
        catch (final FileNotFoundException exc)
        {
            throw new org.apache.commons.vfs2.FileNotFoundException(fileName, exc);
        }
        catch (final FileSystemException exc)
        {
            throw exc;
        }
        catch (final Exception exc)
        {
            throw new FileSystemException("vfs.provider/read.error", fileName, exc);
        }
    }

    /**
     * Returns the name of the file.
     *
     * @return The FileName, never {@code null}.
     */
    @Override
    public FileName getName()
    {
        return fileName;
    }

    /**
     * Returns the receiver as a URI String for public display, like, without a
     * password.
     *
     * @return A URI String without a password, never {@code null}.
     */
    @Override
    public String getPublicURIString()
    {
        return fileName.getFriendlyURI();
    }

    /**
     * Prepares this file for writing.  Makes sure it is either a file,
     * or its parent folder exists.  Returns an output stream to use to
     * write the content of the file to.
     * @return An OutputStream where the new contents of the file can be written.
     * @throws FileSystemException if an error occurs.
     */
    public OutputStream getOutputStream() throws FileSystemException
    {
        return getOutputStream(false);
    }

    /**
     * Prepares this file for writing.  Makes sure it is either a file,
     * or its parent folder exists.  Returns an output stream to use to
     * write the content of the file to.<br>
     *
     * @param bAppend true when append to the file.<br>
     *                Note: If the underlying filesystem does not support appending,
     *                a FileSystemException is thrown.
     * @return An OutputStream where the new contents of the file can be written.
     * @throws FileSystemException if an error occurs; for example:<br>
     *         bAppend is true, and the underlying FileSystem does not support it
     */
    public OutputStream getOutputStream(final boolean bAppend) throws FileSystemException
    {
        /* VFS-210
        if (getType() != FileType.IMAGINARY && !getType().hasContent())
        {
            throw new FileSystemException("vfs.provider/write-not-file.error", name);
        }
        if (!isWriteable())
        {
            throw new FileSystemException("vfs.provider/write-read-only.error", name);
        }
        */

        if (bAppend && !fs.hasCapability(Capability.APPEND_CONTENT))
        {
            throw new FileSystemException("vfs.provider/write-append-not-supported.error", fileName);
        }

        if (getType() == FileType.IMAGINARY)
        {
// Does not exist - make sure parent does
            final FileObject parent = getParent();
            if (parent != null)
            {
                parent.createFolder();
            }
        }

// Get the raw output stream
        try
        {
            return doGetOutputStream(bAppend);
        }
        catch (final RuntimeException re)
        {
            throw re;
        }
        catch (final Exception exc)
        {
            throw new FileSystemException("vfs.provider/write.error", exc, fileName);
        }
    }

    /**
     * Returns the parent of the file.
     * @return the parent FileObject.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileObject getParent() throws FileSystemException
    {
        if (this.compareTo(fs.getRoot()) == 0) // equals is not implemented :-/
        {
            if (fs.getParentLayer() == null)
            {
                // Root file has no parent
                return null;
            }
            else
            {
                // Return the parent of the parent layer
                return fs.getParentLayer().getParent();
            }
        }

        synchronized (fs)
        {
            // Locate the parent of this file
            if (parent == null)
            {
                FileName name = fileName.getParent();
                if (name == null)
                {
                    return null;
                }
                parent = fs.resolveFile(name);
            }
            return parent;
        }
    }

    /**
     * Returns an input/output stream to use to read and write the content of the file in and
     * random manner.
     * @param mode The RandomAccessMode.
     * @return The RandomAccessContent.
     * @throws FileSystemException if an error occurs.
     */
    public RandomAccessContent getRandomAccessContent(final RandomAccessMode mode) throws FileSystemException
    {
        /* VFS-210
        if (!getType().hasContent())
        {
            throw new FileSystemException("vfs.provider/read-not-file.error", name);
        }
        */

        if (mode.requestRead())
        {
            if (!fs.hasCapability(Capability.RANDOM_ACCESS_READ))
            {
                throw new FileSystemException("vfs.provider/random-access-read-not-supported.error");
            }
            if (!isReadable())
            {
                throw new FileSystemException("vfs.provider/read-not-readable.error", fileName);
            }
        }

        if (mode.requestWrite())
        {
            if (!fs.hasCapability(Capability.RANDOM_ACCESS_WRITE))
            {
                throw new FileSystemException("vfs.provider/random-access-write-not-supported.error");
            }
            if (!isWriteable())
            {
                throw new FileSystemException("vfs.provider/write-read-only.error", fileName);
            }
        }

        // Get the raw input stream
        try
        {
            return doGetRandomAccessContent(mode);
        }
        catch (final Exception exc)
        {
            throw new FileSystemException("vfs.provider/random-access.error", fileName, exc);
        }
    }

    /**
     * Returns the file's type.
     * @return The FileType.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileType getType() throws FileSystemException
    {
        synchronized (fs)
        {
            attach();

            // VFS-210: get the type only if requested for
            try
            {
                if (type == null)
                {
                    setFileType(doGetType());
                }
                if (type == null)
                {
                    setFileType(FileType.IMAGINARY);
                }
            }
            catch (final Exception e)
            {
                throw new FileSystemException("vfs.provider/get-type.error", e, fileName);
            }

            return type;
        }
    }

    /**
     * Returns a URL representation of the file.
     * @return The URL representation of the file.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public URL getURL() throws FileSystemException
    {
        try
        {
            return AccessController.doPrivileged(new PrivilegedExceptionAction<URL>()
            {
                @Override
                public URL run() throws MalformedURLException
                {
                    final StringBuilder buf = new StringBuilder();
                    final String scheme = UriParser.extractScheme(fileName.getURI(), buf);
                    return new URL(scheme, "", -1,
                        buf.toString(), new DefaultURLStreamHandler(fs.getContext(), fs.getFileSystemOptions()));
                }
            });
        }
        catch (final PrivilegedActionException e)
        {
            throw new FileSystemException("vfs.provider/get-url.error", fileName, e.getException());
        }
    }

    /**
     * Called when this file is changed.
     * <p>
     * This will only happen if you monitor the file using {@link org.apache.commons.vfs2.FileMonitor}.
     *
     * @throws Exception if an error occurs.
     */
    protected void handleChanged() throws Exception
    {
        // Notify the file system
        fs.fireFileChanged(this);
    }

    /**
     * Called when this file is created. Updates cached info and notifies
     * the parent and file system.
     *
     * @param newType The type of the file.
     * @throws Exception if an error occurs.
     */
    protected void handleCreate(final FileType newType) throws Exception
    {
        synchronized (fs)
        {
            if (attached)
            {
                // Fix up state
                injectType(newType);

                removeChildrenCache();

                // Notify subclass
                onChange();
            }

            // Notify parent that its child list may no longer be valid
            notifyParent(this.getName(), newType);

            // Notify the file system
            fs.fireFileCreated(this);
        }
    }

    /**
     * Called when this file is deleted.  Updates cached info and notifies
     * subclasses, parent and file system.
     * @throws Exception if an error occurs.
     */
    protected void handleDelete() throws Exception
    {
        synchronized (fs)
        {
            if (attached)
            {
                // Fix up state
                injectType(FileType.IMAGINARY);
                removeChildrenCache();

                // Notify subclass
                onChange();
            }

            // Notify parent that its child list may no longer be valid
            notifyParent(this.getName(), FileType.IMAGINARY);

            // Notify the file system
            fs.fireFileDeleted(this);
        }
    }

    /**
     * This method is meant to add an object where this object holds a strong reference then.
     * E.g. a archive-filesystem creates a list of all children and they shouldn't get
     * garbage collected until the container is garbage collected
     *
     * @param strongRef The Object to add.
     */
    // TODO should this be a FileObject?
    public void holdObject(final Object strongRef)
    {
        if (objects == null)
        {
            objects = new ArrayList<Object>(INITIAL_LIST_SIZE);
        }
        objects.add(strongRef);
    }

    protected void injectType(final FileType fileType)
    {
        setFileType(fileType);
    }

    /**
     * Check if the internal state is "attached".
     *
     * @return true if this is the case
     */
    @Override
    public boolean isAttached()
    {
        return attached;
    }

    /**
     * Check if the content stream is open.
     *
     * @return true if this is the case
     */
    @Override
    public boolean isContentOpen()
    {
        if (content == null)
        {
            return false;
        }

        return content.isOpen();
    }

    /**
     * Determines if this file is executable.
     *
     * @return {@code true} if this file is executable, {@code false} if not.
     * @throws FileSystemException On error determining if this file exists.
     */
    @Override
    public boolean isExecutable() throws FileSystemException
    {
        try
        {
            return exists() ? doIsExecutable() : false;
        }
        catch (final Exception exc)
        {
            throw new FileSystemException("vfs.provider/check-is-executable.error", fileName, exc);
        }
    }

    /**
     * Checks if this file is a regular file by using its file type.
     *
     * @return true if this file is a regular file.
     * @throws FileSystemException if an error occurs.
     * @see #getType()
     * @see FileType#FILE
     */
    @Override
    public boolean isFile() throws FileSystemException
    {
        // Use equals instead of == to avoid any class loader worries.
        return FileType.FILE.equals(this.getType());
    }

    /**
     * Checks if this file is a folder by using its file type.
     *
     * @return true if this file is a regular file.
     * @throws FileSystemException if an error occurs.
     * @see #getType()
     * @see FileType#FOLDER
     */
    @Override
    public boolean isFolder() throws FileSystemException
    {
        // Use equals instead of == to avoid any class loader worries.
        return FileType.FOLDER.equals(this.getType());
    }

    /**
     * Determines if this file can be read.
     * @return true if the file is a hidden file, false otherwise.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public boolean isHidden() throws FileSystemException
    {
        try
        {
            return exists() ? doIsHidden() : false;
        }
        catch (final Exception exc)
        {
            throw new FileSystemException("vfs.provider/check-is-hidden.error", fileName, exc);
        }
    }

    /**
     * Determines if this file can be read.
     * @return true if the file can be read, false otherwise.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public boolean isReadable() throws FileSystemException
    {
        try
        {
            return exists() ? doIsReadable() : false;
        }
        catch (final Exception exc)
        {
            throw new FileSystemException("vfs.provider/check-is-readable.error", fileName, exc);
        }
    }

    /**
     * Checks if this fileObject is the same file as {@code destFile} just with a different
     * name. E.g. for case insensitive filesystems like windows.
     *
     * @param destFile The file to compare to.
     * @return true if the FileObjects are the same.
     * @throws FileSystemException if an error occurs.
     */
    protected boolean isSameFile(final FileObject destFile) throws FileSystemException
    {
        attach();
        return doIsSameFile(destFile);
    }

    /**
     * Determines if this file can be written to.
     * @return true if the file can be written to, false otherwise.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public boolean isWriteable() throws FileSystemException
    {
        try
        {
            if (exists())
            {
                return doIsWriteable();
            }
            else
            {
                final FileObject parent = getParent();
                if (parent != null)
                {
                    return parent.isWriteable();
                }
                return true;
            }
        }
        catch (final Exception exc)
        {
            throw new FileSystemException("vfs.provider/check-is-writeable.error", fileName, exc);
        }
    }

    /**
     * Returns an iterator over a set of all FileObject in this file object.
     *
     * @return an Iterator.
     */
    @Override
    public Iterator<FileObject> iterator()
    {
        try
        {
            return listFiles(Selectors.SELECT_ALL).iterator();
        }
        catch (final FileSystemException e)
        {
            throw new IllegalStateException(e);
        }
    }

    /**
     * Lists the set of matching descendants of this file, in depthwise
     * order.
     *
     * @param selector The FileSelector.
     * @return list of files or null if the base file (this object) do not exist or the {@code selector} is null
     * @throws FileSystemException if an error occurs.
     */
    public List<FileObject> listFiles(final FileSelector selector) throws FileSystemException
    {
        if (!exists() || selector == null)
        {
            return null;
        }

        final ArrayList<FileObject> list = new ArrayList<FileObject>();
        this.findFiles(selector, true, list);
        return list;
    }

    /**
     * Moves (rename) the file to another one.
     * @param destFile The target FileObject.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public void moveTo(final FileObject destFile) throws FileSystemException
    {
        if (canRenameTo(destFile))
        {
            if (!getParent().isWriteable())
            {
                throw new FileSystemException("vfs.provider/rename-parent-read-only.error",
                        getName(),
                        getParent().getName());
            }
        }
        else
        {
            if (!isWriteable())
            {
                throw new FileSystemException("vfs.provider/rename-read-only.error", getName());
            }
        }

        if (destFile.exists() && !isSameFile(destFile))
        {
            destFile.deleteAll();
            // throw new FileSystemException("vfs.provider/rename-dest-exists.error", destFile.getName());
        }

        if (canRenameTo(destFile))
        {
            // issue rename on same filesystem
            try
            {
                attach();
                // remember type to avoid attach
                FileType srcType = getType();

                doRename(destFile);

                FileObjectUtils.getAbstractFileObject(destFile).handleCreate(srcType);
                destFile.close(); // now the destFile is no longer imaginary. force reattach.

                handleDelete(); // fire delete-events. This file-object (src) is like deleted.
            }
            catch (final RuntimeException re)
            {
                throw re;
            }
            catch (final Exception exc)
            {
                throw new FileSystemException("vfs.provider/rename.error",  exc,
                        getName(),
                        destFile.getName());
            }
        }
        else
        {
            // different fs - do the copy/delete stuff

            destFile.copyFrom(this, Selectors.SELECT_SELF);

            if ((destFile.getType().hasContent()
                    && destFile.getFileSystem().hasCapability(Capability.SET_LAST_MODIFIED_FILE)
                  || destFile.getType().hasChildren()
                    && destFile.getFileSystem().hasCapability(Capability.SET_LAST_MODIFIED_FOLDER))
                    && fs.hasCapability(Capability.GET_LAST_MODIFIED))
            {
                destFile.getContent().setLastModifiedTime(this.getContent().getLastModifiedTime());
            }

            deleteSelf();
        }

    }

    /**
     * will be called after this file-object closed all its streams.
     */
    protected void notifyAllStreamsClosed()
    {
    }

    /**
     * Notify the parent of a change to its children, when a child is created
     * or deleted.
     * @param childName The name of the child.
     * @param newType The type of the child.
     * @throws Exception if an error occurs.
     */
    private void notifyParent(final FileName childName, final FileType newType) throws Exception
    {
        if (parent == null)
        {
            final FileName parentName = fileName.getParent();
            if (parentName != null)
            {
                // Locate the parent, if it is cached
                parent = fs.getFileFromCache(parentName);
            }
        }

        if (parent != null)
        {
            FileObjectUtils.getAbstractFileObject(parent).childrenChanged(childName, newType);
        }
    }

    /**
     * Called when the type or content of this file changes.
     * <p>
     * This implementation does nothing.
     *
     * @throws Exception if an error occurs.
     */
    protected void onChange() throws Exception
    {
    }

    /**
     * Called when the children of this file change.  Allows subclasses to
     * refresh any cached information about the children of this file.
     * <p>
     * This implementation does nothing.
     *
     * @param child The name of the child that changed.
     * @param newType The type of the file.
     * @throws Exception if an error occurs.
     */
    protected void onChildrenChanged(final FileName child, final FileType newType) throws Exception
    {
    }

    /**
     * This will prepare the fileObject to get resynchronized with the underlying filesystem if required.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public void refresh() throws FileSystemException
    {
        // Detach from the file
        try
        {
            detach();
        }
        catch (final Exception e)
        {
            throw new FileSystemException("vfs.provider/resync.error", fileName, e);
        }
    }

    private void removeChildrenCache()
    {
        children = null;
    }

    private FileObject resolveFile(final FileName child) throws FileSystemException
    {
        return fs.resolveFile(child);
    }

    /**
     * Finds a file, relative to this file.
     *
     * @param path The path of the file to locate.  Can either be a relative
     *             path, which is resolved relative to this file, or an
     *             absolute path, which is resolved relative to the file system
     *             that contains this file.
     * @return The FileObject.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileObject resolveFile(final String path) throws FileSystemException
    {
        final FileName otherName = fs.getFileSystemManager().resolveName(fileName, path);
        return fs.resolveFile(otherName);
    }

    /**
     * Returns a child by name.
     * @param name The name of the child to locate.
     * @param scope the NameScope.
     * @return The FileObject for the file or null if the child does not exist.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileObject resolveFile(final String name, final NameScope scope)
        throws FileSystemException
    {
        // return fs.resolveFile(this.name.resolveName(name, scope));
        return fs.resolveFile(fs.getFileSystemManager().resolveName(this.fileName, name, scope));
    }

    private FileObject[] resolveFiles(final FileName[] children) throws FileSystemException
    {
        if (children == null)
        {
            return null;
        }

        final FileObject[] objects = new FileObject[children.length];
        for (int iterChildren = 0; iterChildren < children.length; iterChildren++)
        {
            objects[iterChildren] = resolveFile(children[iterChildren]);
        }

        return objects;
    }

    @Override
    public boolean setExecutable(final boolean readable, final boolean ownerOnly) throws FileSystemException
    {
        try
        {
            return exists() ? doSetExecutable(readable, ownerOnly) : false;
        }
        catch (final Exception exc)
        {
            throw new FileSystemException("vfs.provider/set-executable.error", fileName, exc);
        }
    }

    private void setFileType(final FileType type)
    {
        if (type != null && type != FileType.IMAGINARY)
        {
            try
            {
                fileName.setType(type);
            }
            catch (final FileSystemException e)
            {
                throw new RuntimeException(e.getMessage());
            }
        }
        this.type = type;
    }

    @Override
    public boolean setReadable(final boolean readable, final boolean ownerOnly) throws FileSystemException
    {
        try
        {
            return exists() ? doSetReadable(readable, ownerOnly) : false;
        }
        catch (final Exception exc)
        {
            throw new FileSystemException("vfs.provider/set-readable.error", fileName, exc);
        }
    }

    // --- OPERATIONS ---

    @Override
    public boolean setWritable(final boolean readable, final boolean ownerOnly) throws FileSystemException
    {
        try
        {
            return exists() ? doSetWritable(readable, ownerOnly) : false;
        }
        catch (final Exception exc)
        {
            throw new FileSystemException("vfs.provider/set-writeable.error", fileName, exc);
        }
    }

    /**
     * Returns the URI as a String.
     *
     * @return Returns the URI as a String.
     */
    @Override
    public String toString()
    {
        return fileName.getURI();
    }
}
