/*
 * 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.impl;

import java.io.File;
import java.lang.reflect.Constructor;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs2.CacheStrategy;
import org.apache.commons.vfs2.Capability;
import org.apache.commons.vfs2.FileContentInfoFactory;
import org.apache.commons.vfs2.FileName;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystem;
import org.apache.commons.vfs2.FileSystemConfigBuilder;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.FileType;
import org.apache.commons.vfs2.FilesCache;
import org.apache.commons.vfs2.NameScope;
import org.apache.commons.vfs2.VFS;
import org.apache.commons.vfs2.cache.SoftRefFilesCache;
import org.apache.commons.vfs2.operations.FileOperationProvider;
import org.apache.commons.vfs2.provider.AbstractFileName;
import org.apache.commons.vfs2.provider.AbstractFileProvider;
import org.apache.commons.vfs2.provider.DefaultURLStreamHandler;
import org.apache.commons.vfs2.provider.FileProvider;
import org.apache.commons.vfs2.provider.FileReplicator;
import org.apache.commons.vfs2.provider.LocalFileProvider;
import org.apache.commons.vfs2.provider.TemporaryFileStore;
import org.apache.commons.vfs2.provider.UriParser;
import org.apache.commons.vfs2.provider.VfsComponent;

/**
 * The default file system manager implementation.
 */
public class DefaultFileSystemManager implements FileSystemManager {

    /**
     * Mapping from URI scheme to FileProvider.
     */
    private final Map<String, FileProvider> providers = new HashMap<>();

    /**
     * List of the schemes of virtual file systems added.
     */
    private final List<String> virtualFileSystemSchemes = new ArrayList<>();

    /**
     * All components used by this manager.
     */
    private final ArrayList<Object> components = new ArrayList<>();

    /**
     * The context to pass to providers.
     */
    private final DefaultVfsComponentContext context = new DefaultVfsComponentContext(this);

    /**
     * Operations providers added to this manager.
     */
    private final Map<String, List<FileOperationProvider>> operationProviders = new HashMap<>();

    /**
     * Mappings of file types.
     */
    private final FileTypeMap typeMap = new FileTypeMap();

    /**
     * The provider for local files.
     */
    private LocalFileProvider localFileProvider;

    /**
     * The default provider.
     */
    private FileProvider defaultProvider;

    /**
     * The file replicator to use.
     */
    private FileReplicator fileReplicator;

    /**
     * The base file to use for relative URI.
     */
    private FileObject baseFile;

    /**
     * The files cache
     */
    private FilesCache filesCache;

    /**
     * The cache strategy
     */
    private CacheStrategy fileCacheStrategy;

    /**
     * Class which decorates all returned fileObjects
     */
    private Class<?> fileObjectDecorator;
    /**
     * Reflection constructor extracted from {@link #fileObjectDecorator}
     */
    private Constructor<?> fileObjectDecoratorConst;

    /**
     * The class to use to determine the content-type (mime-type)
     */
    private FileContentInfoFactory fileContentInfoFactory;

    /**
     * The logger to use. Default implementation.
     */
    private Log log = LogFactory.getLog(getClass());

    /**
     * The temporary file store to use.
     */
    private TemporaryFileStore tempFileStore;

    /**
     * The virtual file provider.
     */
    private VirtualFileProvider vfsProvider;

    /**
     * Flag, if manager is initialized (after init() and before close()).
     */
    private boolean init;

    /**
     * Returns the logger used by this manager.
     *
     * @return the Logger.
     */
    protected Log getLogger() {
        return log;
    }

    /**
     * Registers a file system provider.
     * <p>
     * The manager takes care of all lifecycle management. A provider may be registered multiple times. The first
     * {@link LocalFileProvider} added will be remembered for {@link #getLocalFileProvider()}.
     *
     * @param urlScheme The scheme the provider will handle.
     * @param provider The provider.
     * @throws FileSystemException if an error occurs adding the provider.
     */
    public void addProvider(final String urlScheme, final FileProvider provider) throws FileSystemException {
        addProvider(new String[] { urlScheme }, provider);
    }

    /**
     * Registers a file system provider.
     * <p>
     * The manager takes care of all lifecycle management. A provider may be registered multiple times. The first
     * {@link LocalFileProvider} added will be remembered for {@link #getLocalFileProvider()}.
     *
     * @param urlSchemes The schemes the provider will handle.
     * @param provider The provider.
     * @throws FileSystemException if an error occurs adding the provider.
     */
    public void addProvider(final String[] urlSchemes, final FileProvider provider) throws FileSystemException {
        // fail duplicate schemes
        for (final String scheme : urlSchemes) {
            if (providers.containsKey(scheme)) {
                throw new FileSystemException("vfs.impl/multiple-providers-for-scheme.error", scheme);
            }
        }

        // Contextualise the component (if not already)
        setupComponent(provider);

        // Add to map
        Arrays.stream(urlSchemes).forEach(scheme -> providers.put(scheme, provider));

        if (provider instanceof LocalFileProvider && localFileProvider == null) {
            localFileProvider = (LocalFileProvider) provider;
        }
    }

    /**
     * Unregisters a file system provider.
     *
     * @param urlScheme The scheme of the provider.
     * @since 2.8.0
     */
    public void removeProvider(final String urlScheme) {
        final FileProvider provider = providers.remove(urlScheme);
        // check whether the same instance is not used somewhere else
        if (provider != null && !providers.containsValue(provider)) {
            closeComponent(provider);
        }
    }

    /**
     * Returns true if this manager has a provider for a particular scheme.
     *
     * @param scheme The scheme to check.
     * @return true if a provider is configured for this scheme, false otherwise.
     */
    @Override
    public boolean hasProvider(final String scheme) {
        return providers.containsKey(scheme);
    }

    /**
     * Adds an file name extension mapping.
     *
     * @param extension The file name extension.
     * @param scheme The scheme to use for files with this extension.
     */
    public void addExtensionMap(final String extension, final String scheme) {
        typeMap.addExtension(extension, scheme);
    }

    /**
     * Adds a mime type mapping.
     *
     * @param mimeType The mime type.
     * @param scheme The scheme to use for files with this mime type.
     */
    public void addMimeTypeMap(final String mimeType, final String scheme) {
        typeMap.addMimeType(mimeType, scheme);
    }

    /**
     * Sets the default provider. This is the provider that will handle URI with unknown schemes. The manager takes care
     * of all lifecycle management.
     *
     * @param provider The FileProvider.
     * @throws FileSystemException if an error occurs setting the provider.
     */
    public void setDefaultProvider(final FileProvider provider) throws FileSystemException {
        setupComponent(provider);
        defaultProvider = provider;
    }

    /**
     * Returns the filesCache implementation used to cache files.
     *
     * @return The FilesCache.
     */
    @Override
    public FilesCache getFilesCache() {
        return filesCache;
    }

    /**
     * Sets the filesCache implementation used to cache files.
     * <p>
     * Can only be set before the FileSystemManager is initialized.
     * <p>
     * The manager takes care of the lifecycle. If none is set, a default is picked in {@link #init()}.
     *
     * @param filesCache The FilesCache.
     * @throws FileSystemException if an error occurs setting the cache..
     */
    public void setFilesCache(final FilesCache filesCache) throws FileSystemException {
        if (init) {
            throw new FileSystemException("vfs.impl/already-inited.error");
        }
        this.filesCache = filesCache;
    }

    /**
     * Set the cache strategy to use when dealing with file object data.
     * <p>
     * Can only be set before the FileSystemManager is initialized.
     * <p>
     * The default is {@link CacheStrategy#ON_RESOLVE}
     *
     * @param fileCacheStrategy The CacheStrategy to use.
     * @throws FileSystemException if this is not possible. e.g. it is already set.
     */
    public void setCacheStrategy(final CacheStrategy fileCacheStrategy) throws FileSystemException {
        if (init) {
            throw new FileSystemException("vfs.impl/already-inited.error");
        }

        this.fileCacheStrategy = fileCacheStrategy;
    }

    /**
     * Get the cache strategy used.
     *
     * @return The CacheStrategy.
     */
    @Override
    public CacheStrategy getCacheStrategy() {
        return fileCacheStrategy;
    }

    /**
     * Get the file object decorator used.
     *
     * @return The decorator.
     */
    @Override
    public Class<?> getFileObjectDecorator() {
        return fileObjectDecorator;
    }

    /**
     * The constructor associated to the fileObjectDecorator. We cache it here for performance reasons.
     *
     * @return The decorator's Constructor.
     */
    @Override
    public Constructor<?> getFileObjectDecoratorConst() {
        return fileObjectDecoratorConst;
    }

    /**
     * Set a fileObject decorator to be used for ALL returned file objects.
     * <p>
     * Can only be set before the FileSystemManager is initialized.
     *
     * @param fileObjectDecorator must be inherted from {@link DecoratedFileObject} a has to provide a constructor with
     *            a single {@link FileObject} as argument
     * @throws FileSystemException if an error occurs setting the decorator.
     */
    public void setFileObjectDecorator(final Class<?> fileObjectDecorator) throws FileSystemException {
        if (init) {
            throw new FileSystemException("vfs.impl/already-inited.error");
        }
        if (!DecoratedFileObject.class.isAssignableFrom(fileObjectDecorator)) {
            throw new FileSystemException("vfs.impl/invalid-decorator.error", fileObjectDecorator.getName());
        }

        try {
            fileObjectDecoratorConst = fileObjectDecorator.getConstructor(FileObject.class);
        } catch (final NoSuchMethodException e) {
            throw new FileSystemException("vfs.impl/invalid-decorator.error", fileObjectDecorator.getName(), e);
        }

        this.fileObjectDecorator = fileObjectDecorator;
    }

    /**
     * get the fileContentInfoFactory used to determine the infos of a file content.
     *
     * @return The FileContentInfoFactory.
     */
    @Override
    public FileContentInfoFactory getFileContentInfoFactory() {
        return fileContentInfoFactory;
    }

    /**
     * set the fileContentInfoFactory used to determine the infos of a file content.
     * <p>
     * Can only be set before the FileSystemManager is initialized.
     *
     * @param fileContentInfoFactory The FileContentInfoFactory.
     * @throws FileSystemException if an error occurs setting the FileContentInfoFactory.
     */
    public void setFileContentInfoFactory(final FileContentInfoFactory fileContentInfoFactory)
            throws FileSystemException {
        if (init) {
            throw new FileSystemException("vfs.impl/already-inited.error");
        }

        this.fileContentInfoFactory = fileContentInfoFactory;
    }

    /**
     * Sets the file replicator to use.
     * <p>
     * The manager takes care of all lifecycle management.
     *
     * @param replicator The FileReplicator.
     * @throws FileSystemException if an error occurs setting the replicator.
     */
    public void setReplicator(final FileReplicator replicator) throws FileSystemException {
        setupComponent(replicator);
        fileReplicator = replicator;
    }

    /**
     * Sets the temporary file store to use.
     * <p>
     * The manager takes care of all lifecycle management.
     *
     * @param tempFileStore The temporary FileStore.
     * @throws FileSystemException if an error occurs adding the file store.
     */
    public void setTemporaryFileStore(final TemporaryFileStore tempFileStore) throws FileSystemException {
        setupComponent(tempFileStore);
        this.tempFileStore = tempFileStore;
    }

    /**
     * Sets the logger to use.
     * <p>
     * This overwrites the default logger for this manager and is not reset in {@link #close()}.
     *
     * @param log The Logger to use.
     */
    @Override
    public void setLogger(final Log log) {
        this.log = log;
    }

    /**
     * Initializes a component, if it has not already been initialized.
     *
     * @param component The component to setup.
     * @throws FileSystemException if an error occurs.
     */
    private void setupComponent(final Object component) throws FileSystemException {
        if (!components.contains(component)) {
            if (component instanceof VfsComponent) {
                final VfsComponent vfsComponent = (VfsComponent) component;
                vfsComponent.setLogger(getLogger());
                vfsComponent.setContext(context);
                vfsComponent.init();
            }
            components.add(component);
        }
    }

    /**
     * Closes a component, if it has not already been closed.
     *
     * @param component The component to close.
     */
    private void closeComponent(final Object component) {
        if (component != null && components.contains(component)) {
            if (component instanceof VfsComponent) {
                ((VfsComponent) component).close();
            }
            components.remove(component);
        }
    }

    /**
     * Returns the file replicator.
     *
     * @return The file replicator. Never returns null.
     * @throws FileSystemException if there is no FileReplicator.
     */
    public FileReplicator getReplicator() throws FileSystemException {
        return FileSystemException.requireNonNull(fileReplicator, "vfs.impl/no-replicator.error");
    }

    /**
     * Returns the temporary file store.
     *
     * @return The file store. Never returns null.
     * @throws FileSystemException if there is no TemporaryFileStore.
     */
    public TemporaryFileStore getTemporaryFileStore() throws FileSystemException {
        return FileSystemException.requireNonNull(tempFileStore, "vfs.impl/no-temp-file-store.error");
    }

    /**
     * Initializes this manager.
     * <p>
     * If no value for the following properties was specified, it will use the following defaults:
     * <ul>
     * <li>fileContentInfoFactory = new FileContentInfoFilenameFactory()</li>
     * <li>filesCache = new SoftRefFilesCache()</li>
     * <li>fileCacheStrategy = CacheStrategy.ON_RESOLVE</li>
     * </ul>
     *
     * @throws FileSystemException if an error occurs during initialization.
     */
    public void init() throws FileSystemException {
        if (fileContentInfoFactory == null) {
            fileContentInfoFactory = new FileContentInfoFilenameFactory();
        }

        if (filesCache == null) {
            filesCache = new SoftRefFilesCache();
        }
        if (fileCacheStrategy == null) {
            fileCacheStrategy = CacheStrategy.ON_RESOLVE;
        }
        setupComponent(filesCache);

        vfsProvider = new VirtualFileProvider();
        setupComponent(vfsProvider);

        init = true;
    }

    /**
     * Closes the manager.
     * <p>
     * This will close all providers (all files), it will also close all managed components including temporary files,
     * replicator, file cache and file operations.
     * <p>
     * The manager is in uninitialized state after this method.
     */
    @Override
    public void close() {
        if (!init) {
            return;
        }

        // make sure all discovered components in
        // org.apache.commons.vfs2.impl.StandardFileSystemManager.configure(Element)
        // are closed here

        // Close the file system providers.
        providers.values().forEach(this::closeComponent);

        // Close the other components
        closeComponent(vfsProvider);
        closeComponent(fileReplicator);
        closeComponent(tempFileStore);
        closeComponent(defaultProvider);

        // unregister all providers here, so if any components have local file references
        // they can still resolve against the supported schemes
        providers.clear();

        // FileOperations are components, too
        operationProviders.values().forEach(opProviders -> opProviders.forEach(this::closeComponent));

        // unregister all
        operationProviders.clear();

        // collections with add()
        typeMap.clear();

        // should not happen, but make debugging easier:
        if (!components.isEmpty()) {
            log.warn("DefaultFilesystemManager.close: not all components are closed: " + components.toString());
        }
        components.clear();

        // managed components
        vfsProvider = null;

        // virtual schemas
        virtualFileSystemSchemes.clear();

        // Close cache last.
        if (filesCache != null) {
            filesCache.close();
        }

        // setters and derived state
        defaultProvider = null;
        baseFile = null;
        fileObjectDecorator = null;
        fileObjectDecoratorConst = null;
        localFileProvider = null;
        fileReplicator = null;
        tempFileStore = null;
        // setters with init() defaults
        filesCache = null;
        fileCacheStrategy = null;
        fileContentInfoFactory = null;

        init = false;
    }

    /**
     * Free all resources used by unused file systems created by this manager.
     */
    public void freeUnusedResources() {
        if (!init) {
            return;
        }

        // Close the providers.
        for (final FileProvider fileProvider : providers.values()) {
            if (fileProvider instanceof AbstractFileProvider) {
                ((AbstractFileProvider) fileProvider).freeUnusedResources();
            }
        }
        // vfsProvider does not need to free resources
    }

    /**
     * Sets the base file to use when resolving relative URI.
     *
     * @param baseFile The new base FileObject.
     * @throws FileSystemException if an error occurs.
     */
    public void setBaseFile(final FileObject baseFile) throws FileSystemException {
        this.baseFile = baseFile;
    }

    /**
     * Sets the base file to use when resolving relative URI.
     *
     * @param baseFile The new base FileObject.
     * @throws FileSystemException if an error occurs.
     */
    public void setBaseFile(final File baseFile) throws FileSystemException {
        this.baseFile = getLocalFileProvider().findLocalFile(baseFile);
    }

    /**
     * Returns the base file used to resolve relative URI.
     *
     * @return The FileObject that represents the base file.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileObject getBaseFile() throws FileSystemException {
        return baseFile;
    }

    /**
     * Locates a file by URI.
     *
     * @param uri The URI of the file to locate.
     * @return The FileObject for the located file.
     * @throws FileSystemException if the file cannot be located or an error occurs.
     */
    @Override
    public FileObject resolveFile(final String uri) throws FileSystemException {
        return resolveFile(getBaseFile(), uri);
    }

    /**
     * Locate a file by URI, use the FileSystemOptions for file-system creation.
     *
     * @param uri The URI of the file to locate.
     * @param fileSystemOptions The options for the FileSystem.
     * @return The FileObject for the located file.
     * @throws FileSystemException if the file cannot be located or an error occurs.
     */

    @Override
    public FileObject resolveFile(final String uri, final FileSystemOptions fileSystemOptions)
            throws FileSystemException {
        // return resolveFile(baseFile, uri, fileSystemOptions);
        return resolveFile(getBaseFile(), uri, fileSystemOptions);
    }

    /**
     * Resolves a URI, relative to base file.
     * <p>
     * Uses the {@linkplain #getLocalFileProvider() local file provider} to locate the system file.
     *
     * @param baseFile The base File to use to locate the file.
     * @param uri The URI of the file to locate.
     * @return The FileObject for the located file.
     * @throws FileSystemException if the file cannot be located or an error occurs.
     */
    @Override
    public FileObject resolveFile(final File baseFile, final String uri) throws FileSystemException {
        return resolveFile(getLocalFileProvider().findLocalFile(baseFile), uri);
    }

    /**
     * Resolves a URI, relative to a base file.
     *
     * @param baseFile The base FileOjbect to use to locate the file.
     * @param uri The URI of the file to locate.
     * @return The FileObject for the located file.
     * @throws FileSystemException if the file cannot be located or an error occurs.
     */
    @Override
    public FileObject resolveFile(final FileObject baseFile, final String uri) throws FileSystemException {
        return resolveFile(baseFile, uri, baseFile == null ? null : baseFile.getFileSystem().getFileSystemOptions());
    }

    /**
     * Resolves a URI, relative to a base file with specified FileSystem configuration.
     *
     * @param baseFile The base file.
     * @param uri The file name. May be a fully qualified or relative path or a url.
     * @param fileSystemOptions Options to pass to the file system.
     * @return A FileObject representing the target file.
     * @throws FileSystemException if an error occurs accessing the file.
     */
    public FileObject resolveFile(final FileObject baseFile, final String uri,
            final FileSystemOptions fileSystemOptions) throws FileSystemException {
        final FileObject realBaseFile;
        if (baseFile != null && VFS.isUriStyle() && baseFile.getName().isFile()) {
            realBaseFile = baseFile.getParent();
        } else {
            realBaseFile = baseFile;
        }
        // TODO: use resolveName and use this name to resolve the fileObject

        UriParser.checkUriEncoding(uri);

        if (uri == null) {
            throw new IllegalArgumentException();
        }

        // Extract the scheme
        final String scheme = UriParser.extractScheme(getSchemes(), uri);
        if (scheme != null) {
            // An absolute URI - locate the provider
            final FileProvider provider = providers.get(scheme);
            if (provider != null) {
                return provider.findFile(realBaseFile, uri, fileSystemOptions);
            }
            // Otherwise, assume a local file
        }

        // Handle absolute file names
        if (localFileProvider != null && localFileProvider.isAbsoluteLocalName(uri)) {
            return localFileProvider.findLocalFile(uri);
        }

        if (scheme != null) {
            // An unknown scheme - hand it to the default provider
            FileSystemException.requireNonNull(defaultProvider, "vfs.impl/unknown-scheme.error", scheme, uri);
            return defaultProvider.findFile(realBaseFile, uri, fileSystemOptions);
        }

        // Assume a relative name - use the supplied base file
        FileSystemException.requireNonNull(realBaseFile, "vfs.impl/find-rel-file.error", uri);

        return realBaseFile.resolveFile(uri);
    }

    /**
     * Resolves a name, relative to the file. If the supplied name is an absolute path, then it is resolved relative to
     * the root of the file system that the file belongs to. If a relative name is supplied, then it is resolved
     * relative to this file name.
     *
     * @param root The base FileName.
     * @param path The path to the file relative to the base FileName or an absolute path.
     * @return The constructed FileName.
     * @throws FileSystemException if an error occurs constructing the FileName.
     */
    @Override
    public FileName resolveName(final FileName root, final String path) throws FileSystemException {
        return resolveName(root, path, NameScope.FILE_SYSTEM);
    }

    /**
     * Resolves a name, relative to the root.
     *
     * @param base the base file name
     * @param name the name
     * @param scope the {@link NameScope}
     * @return The FileName of the file.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileName resolveName(final FileName base, final String name, final NameScope scope)
            throws FileSystemException {
        FileSystemException.requireNonNull(base, "Invalid base FileName.");
        FileSystemException.requireNonNull(name, "Invalid name FileName.");
        final FileName realBase;
        if (VFS.isUriStyle() && base.isFile()) {
            realBase = base.getParent();
        } else {
            realBase = base;
        }

        final StringBuilder buffer = new StringBuilder(name);

        // Adjust separators
        UriParser.fixSeparators(buffer);
        String scheme = UriParser.extractScheme(getSchemes(), buffer.toString());

        // Determine whether to prepend the base path
        if (name.isEmpty() || (scheme == null && buffer.charAt(0) != FileName.SEPARATOR_CHAR)) {
            // Supplied path is not absolute
            if (!VFS.isUriStyle()) {
                // when using URIs the parent already do have the trailing "/"
                buffer.insert(0, FileName.SEPARATOR_CHAR);
            }
            buffer.insert(0, realBase.getPath());
        }

        // Normalise the path
        final FileType fileType = UriParser.normalisePath(buffer);

        // Check the name is ok
        final String resolvedPath = buffer.toString();
        if (!AbstractFileName.checkName(realBase.getPath(), resolvedPath, scope)) {
            throw new FileSystemException("vfs.provider/invalid-descendent-name.error", name);
        }

        final String fullPath;
        if (scheme != null) {
            fullPath = resolvedPath;
        } else {
            scheme = realBase.getScheme();
            fullPath = realBase.getRootURI() + resolvedPath;
        }
        final FileProvider provider = providers.get(scheme);
        if (provider != null) {
            // TODO: extend the file name parser to be able to parse
            // only a pathname and take the missing informations from
            // the base. Then we can get rid of the string operation.
            // // String fullPath = base.getRootURI() +
            // resolvedPath.substring(1);

            return provider.parseUri(realBase, fullPath);
        }

        // An unknown scheme - hand it to the default provider - if possible
        if (scheme != null && defaultProvider != null) {
            return defaultProvider.parseUri(realBase, fullPath);
        }

        // TODO: avoid fallback to this point
        // this happens if we have a virtual filesystem (no provider for scheme)
        return ((AbstractFileName) realBase).createName(resolvedPath, fileType);
    }

    /**
     * Resolve the uri to a file name.
     *
     * @param uri The URI to resolve.
     * @return The FileName of the file.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileName resolveURI(final String uri) throws FileSystemException {
        UriParser.checkUriEncoding(uri);

        if (uri == null) {
            throw new IllegalArgumentException();
        }

        // Extract the scheme
        final String scheme = UriParser.extractScheme(getSchemes(), uri);
        if (scheme != null) {
            // An absolute URI - locate the provider
            final FileProvider provider = providers.get(scheme);
            if (provider != null) {
                return provider.parseUri(null, uri);
            }

            // Otherwise, assume a local file
        }

        // Handle absolute file names
        if (localFileProvider != null && localFileProvider.isAbsoluteLocalName(uri)) {
            return localFileProvider.parseUri(null, uri);
        }

        if (scheme != null) {
            // An unknown scheme - hand it to the default provider
            FileSystemException.requireNonNull(defaultProvider, "vfs.impl/unknown-scheme.error", scheme, uri);
            return defaultProvider.parseUri(null, uri);
        }

        // Assume a relative name - use the supplied base file
        FileSystemException.requireNonNull(baseFile, "vfs.impl/find-rel-file.error", uri);

        return resolveName(baseFile.getName(), uri, NameScope.FILE_SYSTEM);
    }

    /**
     * Converts a local file into a {@link FileObject}.
     *
     * @param file The input File.
     * @return the create FileObject
     * @throws FileSystemException if an error occurs creating the file.
     */
    @Override
    public FileObject toFileObject(final File file) throws FileSystemException {
        return getLocalFileProvider().findLocalFile(file);
    }

    /**
     * Creates a layered file system.
     *
     * @param scheme The scheme to use.
     * @param file The FileObject.
     * @return The layered FileObject.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileObject createFileSystem(final String scheme, final FileObject file) throws FileSystemException {
        final FileProvider provider = providers.get(scheme);
        FileSystemException.requireNonNull(provider, "vfs.impl/unknown-provider.error", scheme, file);
        return provider.createFileSystem(scheme, file, file.getFileSystem().getFileSystemOptions());
    }

    /**
     * Creates a layered file system.
     *
     * @param file The FileObject to use.
     * @return The layered FileObject.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileObject createFileSystem(final FileObject file) throws FileSystemException {
        final String scheme = typeMap.getScheme(file);
        FileSystemException.requireNonNull(scheme, "vfs.impl/no-provider-for-file.error", file);
        return createFileSystem(scheme, file);
    }

    /**
     * Determines if a layered file system can be created for a given file.
     *
     * @param file The file to check for.
     * @return true if the FileSystem can be created.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public boolean canCreateFileSystem(final FileObject file) throws FileSystemException {
        return typeMap.getScheme(file) != null;
    }

    /**
     * Creates a virtual file system.
     *
     * @param rootFile The FileObject to use.
     * @return The FileObject in the VirtualFileSystem.
     * @throws FileSystemException if an error occurs creating the file.
     */
    @Override
    public FileObject createVirtualFileSystem(final FileObject rootFile) throws FileSystemException {
        final FileObject fileObject = vfsProvider.createFileSystem(rootFile);
        addVirtualFileSystemScheme(rootFile.getName().getScheme());
        return fileObject;
    }

    /**
     * Creates an empty virtual file system.
     *
     * @param rootUri The URI to use as the root of the FileSystem.
     * @return A FileObject in the virtual FileSystem.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileObject createVirtualFileSystem(final String rootUri) throws FileSystemException {
        final FileObject fileObject = vfsProvider.createFileSystem(rootUri);
        addVirtualFileSystemScheme(rootUri);
        return fileObject;
    }


    protected void addVirtualFileSystemScheme(String rootUri) {
        if (rootUri.indexOf(':') != -1) {
            rootUri = rootUri.substring(0, rootUri.indexOf(':'));
        }
        virtualFileSystemSchemes.add(rootUri);
    }

    /**
     * Locates the local file provider.
     * <p>
     * The local file provider is the first {@linkplain #addProvider(String[], FileProvider) provider added}
     * implementing {@link LocalFileProvider}.
     *
     * @return The LocalFileProvider.
     * @throws FileSystemException if no local file provider was set.
     */
    private LocalFileProvider getLocalFileProvider() throws FileSystemException {
        return FileSystemException.requireNonNull(localFileProvider, "vfs.impl/no-local-file-provider.error");
    }

    /**
     * Get the URLStreamHandlerFactory.
     *
     * @return The URLStreamHandlerFactory.
     */
    @Override
    public URLStreamHandlerFactory getURLStreamHandlerFactory() {
        return new VfsStreamHandlerFactory();
    }

    /**
     * Closes the given file system.
     * <p>
     * If you use VFS as singleton it is VERY dangerous to call this method.
     *
     * @param fileSystem The FileSystem to close.
     */
    @Override
    public void closeFileSystem(final FileSystem fileSystem) {
        // inform the cache ...
        getFilesCache().clear(fileSystem);

        // just in case the cache didnt call _closeFileSystem
        _closeFileSystem(fileSystem);
    }

    /**
     * Closes the given file system.
     * <p>
     * If you use VFS as singleton it is VERY dangerous to call this method
     * </p>
     *
     * @param fileSystem The FileSystem to close.
     */
    public void _closeFileSystem(final FileSystem fileSystem) {
        final FileProvider provider = providers.get(fileSystem.getRootName().getScheme());
        if (provider != null) {
            ((AbstractFileProvider) provider).closeFileSystem(fileSystem);
        } else if (fileSystem instanceof VirtualFileSystem) {
            // vfsProvider does not implement AbstractFileProvider
            vfsProvider.closeFileSystem(fileSystem);
        }
    }

    /**
     * This is an internal class because it needs access to the private member providers.
     */
    final class VfsStreamHandlerFactory implements URLStreamHandlerFactory {
        @Override
        public URLStreamHandler createURLStreamHandler(final String protocol) {
            final FileProvider provider = providers.get(protocol);
            if (provider != null) {
                return new DefaultURLStreamHandler(context);
            }

            // Route all other calls to the default URLStreamHandlerFactory
            return new URLStreamHandlerProxy();
        }
    }

    /**
     * Get the schemes currently available.
     *
     * @return The array of scheme names.
     */
    @Override
    public String[] getSchemes() {
        final List<String> schemes = new ArrayList<>(providers.size() + virtualFileSystemSchemes.size());
        schemes.addAll(providers.keySet());
        schemes.addAll(virtualFileSystemSchemes);
        return schemes.toArray(new String[]{});
    }

    /**
     * Get the capabilities for a given scheme.
     *
     * @param scheme The scheme to located.
     * @return A Collection of capabilities.
     * @throws FileSystemException if the given scheme is not konwn
     */
    @Override
    public Collection<Capability> getProviderCapabilities(final String scheme) throws FileSystemException {
        final FileProvider provider = providers.get(scheme);
        FileSystemException.requireNonNull(provider, "vfs.impl/unknown-scheme.error", scheme);
        return provider.getCapabilities();
    }

    /**
     * Get the configuration builder for the given scheme.
     *
     * @param scheme The scheme to locate.
     * @return The FileSystemConfigBuilder for the scheme.
     * @throws FileSystemException if the given scheme is not konwn
     */
    @Override
    public FileSystemConfigBuilder getFileSystemConfigBuilder(final String scheme) throws FileSystemException {
        final FileProvider provider = providers.get(scheme);
        FileSystemException.requireNonNull(provider, "vfs.impl/unknown-scheme.error", scheme);
        return provider.getConfigBuilder();
    }

    // -- OPERATIONS --

    /**
     * Adds the specified FileOperationProvider for the specified scheme. Several FileOperationProvider's might be
     * registered for the same scheme. For example, for "file" scheme we can register SvnWsOperationProvider and
     * CvsOperationProvider.
     *
     * @param scheme The scheme the provider should be registered for.
     * @param operationProvider The FileOperationProvider.
     * @throws FileSystemException if an error occurs adding the provider.
     */
    @Override
    public void addOperationProvider(final String scheme, final FileOperationProvider operationProvider)
            throws FileSystemException {
        addOperationProvider(new String[] { scheme }, operationProvider);
    }

    /**
     * @see FileSystemManager#addOperationProvider(String, org.apache.commons.vfs2.operations.FileOperationProvider)
     *
     * @param schemes The array of schemes the provider should apply to.
     * @param operationProvider The FileOperationProvider.
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public void addOperationProvider(final String[] schemes, final FileOperationProvider operationProvider)
            throws FileSystemException {
        for (final String scheme : schemes) {
            if (!operationProviders.containsKey(scheme)) {
                final List<FileOperationProvider> providers = new ArrayList<>();
                operationProviders.put(scheme, providers);
            }

            final List<FileOperationProvider> providers = operationProviders.get(scheme);

            if (providers.contains(operationProvider)) {
                throw new FileSystemException("vfs.operation/operation-provider-already-added.error", scheme);
            }

            setupComponent(operationProvider);

            providers.add(operationProvider);
        }
    }

    /**
     * @param scheme the scheme for wich we want to get the list af registered providers.
     *
     * @return the registered FileOperationProviders for the specified scheme. If there were no providers registered for
     *         the scheme, it returns null.
     *
     * @throws FileSystemException if an error occurs.
     */
    @Override
    public FileOperationProvider[] getOperationProviders(final String scheme) throws FileSystemException {

        final List<?> providers = operationProviders.get(scheme);
        if (providers == null || providers.isEmpty()) {
            return null;
        }
        return providers.toArray(new FileOperationProvider[] {});
    }

    /**
     * Converts a URI into a {@link FileObject}.
     *
     * @param uri The URI to convert.
     * @return The {@link FileObject} that represents the URI. Never returns null.
     * @throws FileSystemException On error converting the URI.
     * @since 2.1
     */
    @Override
    public FileObject resolveFile(final URI uri) throws FileSystemException {
        // TODO Push the URI deeper into VFS
        return resolveFile(baseFile, uri.toString(), null);
    }

    /**
     * Converts a URL into a {@link FileObject}.
     *
     * @param url The URL to convert.
     * @return The {@link FileObject} that represents the URL. Never returns null.
     * @throws FileSystemException On error converting the URL.
     * @since 2.1
     */
    @Override
    public FileObject resolveFile(final URL url) throws FileSystemException {
        try {
            return this.resolveFile(url.toURI());
        } catch (final URISyntaxException e) {
            throw new FileSystemException(e);
        }
    }

}
