// Path: src/main/java/org/grapheco/elfinder/service/FsItem.java
// public interface FsItem
// {
// 	FsVolume getVolume();
// }
// 
// Path: src/main/java/org/grapheco/elfinder/service/FsVolume.java
// public interface FsVolume
// {
// 	void createFile(FsItem fsi) throws IOException;
// 
// 	void createFolder(FsItem fsi) throws IOException;
// 
// 	void deleteFile(FsItem fsi) throws IOException;
// 
// 	void deleteFolder(FsItem fsi) throws IOException;
// 
// 	boolean exists(FsItem newFile);
// 
// 	FsItem fromPath(String relativePath);
// 
// 	String getDimensions(FsItem fsi);
// 
// 	long getLastModified(FsItem fsi);
// 
// 	String getMimeType(FsItem fsi);
// 
// 	String getName();
// 
// 	String getName(FsItem fsi);
// 
// 	FsItem getParent(FsItem fsi);
// 
// 	String getPath(FsItem fsi) throws IOException;
// 
// 	FsItem getRoot();
// 
// 	long getSize(FsItem fsi) throws IOException;
// 
// 	String getThumbnailFileName(FsItem fsi);
// 
// 	boolean hasChildFolder(FsItem fsi);
// 
// 	boolean isFolder(FsItem fsi);
// 
// 	boolean isRoot(FsItem fsi);
// 
// 	FsItem[] listChildren(FsItem fsi);
// 
// 	InputStream openInputStream(FsItem fsi) throws IOException;
// 
// 	void writeStream(FsItem f, InputStream is) throws IOException;
// 
// 	void rename(FsItem src, FsItem dst) throws IOException;
// 
// 	/**
// 	 * Gets the URL for the supplied item.
// 	 * 
// 	 * @param f
// 	 *            The item to get the URL for.
// 	 * @return An absolute URL or <code>null</code> if we should not send back a
// 	 *         URL.
// 	 */
// 	String getURL(FsItem f);
// 
// 	/**
// 	 * This allows volumes to change the options returned to the client for a
// 	 * particular item. Implementations should update the map they are passed.
// 	 * 
// 	 * @param f
// 	 *            The item to filter the options for.
// 	 * @param map
// 	 *            The options that are going to be returned.
// 	 */
// 	void filterOptions(FsItem f, Map<String, Object> map);
// }
// 
// Path: src/main/java/org/grapheco/elfinder/util/MimeTypesUtils.java
// public abstract class MimeTypesUtils
// {
// 	private static Map<String, String> _map;
// 
// 	public static final String UNKNOWN_MIME_TYPE = "application/oct-stream";
// 
// 	static
// 	{
// 		_map = new HashMap<String, String>();
// 		try
// 		{
// 			load();
// 		}
// 		catch (Throwable e)
// 		{
// 			e.printStackTrace();
// 		}
// 	}
// 
// 	public static String getMimeType(String ext)
// 	{
// 		return _map.get(ext.toLowerCase());
// 	}
// 
// 	public static boolean isUnknownType(String mime)
// 	{
// 		return mime == null || UNKNOWN_MIME_TYPE.equals(mime);
// 	}
// 
// 	private static void load() throws IOException
// 	{
// 		InputStream is = new ClassPathResource("/mime.types").getInputStream();
// 		BufferedReader fr = new BufferedReader(new InputStreamReader(is));
// 		String line;
// 		while ((line = fr.readLine()) != null)
// 		{
// 			line = line.trim();
// 			if (line.startsWith("#") || line.isEmpty())
// 			{
// 				continue;
// 			}
// 
// 			String[] tokens = line.split("\\s+");
// 			if (tokens.length < 2)
// 				continue;
// 
// 			for (int i = 1; i < tokens.length; i++)
// 			{
// 				putMimeType(tokens[i], tokens[0]);
// 			}
// 		}
// 
// 		is.close();
// 	}
// 
// 	public static void putMimeType(String ext, String type)
// 	{
// 		if (ext == null || type == null)
// 			return;
// 
// 		_map.put(ext.toLowerCase(), type);
// 	}
// }


import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.grapheco.elfinder.service.FsItem;
import org.grapheco.elfinder.service.FsVolume;
import org.grapheco.elfinder.util.MimeTypesUtils;

	@Override
	public FsItem fromPath(String relativePath)
	{
		return fromFile(new File(_rootDir, relativePath));
	}

	@Override
	public String getDimensions(FsItem fsi)
	{
		return null;
	}

	@Override
	public long getLastModified(FsItem fsi)
	{
		return asFile(fsi).lastModified() / 1000;
	}

	@Override
	public String getMimeType(FsItem fsi)
	{
		File file = asFile(fsi);
		if (file.isDirectory())
			return "directory";

		String ext = FilenameUtils.getExtension(file.getName());
		if (ext != null && !ext.isEmpty())
		{
			String mimeType = MimeTypesUtils.getMimeType(ext);
// Path: src/main/java/org/grapheco/elfinder/service/FsItem.java
// public interface FsItem
// {
// 	FsVolume getVolume();
// }
// 
// Path: src/main/java/org/grapheco/elfinder/service/FsVolume.java
// public interface FsVolume
// {
// 	void createFile(FsItem fsi) throws IOException;
// 
// 	void createFolder(FsItem fsi) throws IOException;
// 
// 	void deleteFile(FsItem fsi) throws IOException;
// 
// 	void deleteFolder(FsItem fsi) throws IOException;
// 
// 	boolean exists(FsItem newFile);
// 
// 	FsItem fromPath(String relativePath);
// 
// 	String getDimensions(FsItem fsi);
// 
// 	long getLastModified(FsItem fsi);
// 
// 	String getMimeType(FsItem fsi);
// 
// 	String getName();
// 
// 	String getName(FsItem fsi);
// 
// 	FsItem getParent(FsItem fsi);
// 
// 	String getPath(FsItem fsi) throws IOException;
// 
// 	FsItem getRoot();
// 
// 	long getSize(FsItem fsi) throws IOException;
// 
// 	String getThumbnailFileName(FsItem fsi);
// 
// 	boolean hasChildFolder(FsItem fsi);
// 
// 	boolean isFolder(FsItem fsi);
// 
// 	boolean isRoot(FsItem fsi);
// 
// 	FsItem[] listChildren(FsItem fsi);
// 
// 	InputStream openInputStream(FsItem fsi) throws IOException;
// 
// 	void writeStream(FsItem f, InputStream is) throws IOException;
// 
// 	void rename(FsItem src, FsItem dst) throws IOException;
// 
// 	/**
// 	 * Gets the URL for the supplied item.
// 	 * 
// 	 * @param f
// 	 *            The item to get the URL for.
// 	 * @return An absolute URL or <code>null</code> if we should not send back a
// 	 *         URL.
// 	 */
// 	String getURL(FsItem f);
// 
// 	/**
// 	 * This allows volumes to change the options returned to the client for a
// 	 * particular item. Implementations should update the map they are passed.
// 	 * 
// 	 * @param f
// 	 *            The item to filter the options for.
// 	 * @param map
// 	 *            The options that are going to be returned.
// 	 */
// 	void filterOptions(FsItem f, Map<String, Object> map);
// }
// 
// Path: src/main/java/org/grapheco/elfinder/util/MimeTypesUtils.java
// public abstract class MimeTypesUtils
// {
// 	private static Map<String, String> _map;
// 
// 	public static final String UNKNOWN_MIME_TYPE = "application/oct-stream";
// 
// 	static
// 	{
// 		_map = new HashMap<String, String>();
// 		try
// 		{
// 			load();
// 		}
// 		catch (Throwable e)
// 		{
// 			e.printStackTrace();
// 		}
// 	}
// 
// 	public static String getMimeType(String ext)
// 	{
// 		return _map.get(ext.toLowerCase());
// 	}
// 
// 	public static boolean isUnknownType(String mime)
// 	{
// 		return mime == null || UNKNOWN_MIME_TYPE.equals(mime);
// 	}
// 
// 	private static void load() throws IOException
// 	{
// 		InputStream is = new ClassPathResource("/mime.types").getInputStream();
// 		BufferedReader fr = new BufferedReader(new InputStreamReader(is));
// 		String line;
// 		while ((line = fr.readLine()) != null)
// 		{
// 			line = line.trim();
// 			if (line.startsWith("#") || line.isEmpty())
// 			{
// 				continue;
// 			}
// 
// 			String[] tokens = line.split("\\s+");
// 			if (tokens.length < 2)
// 				continue;
// 
// 			for (int i = 1; i < tokens.length; i++)
// 			{
// 				putMimeType(tokens[i], tokens[0]);
// 			}
// 		}
// 
// 		is.close();
// 	}
// 
// 	public static void putMimeType(String ext, String type)
// 	{
// 		if (ext == null || type == null)
// 			return;
// 
// 		_map.put(ext.toLowerCase(), type);
// 	}
// }


// Path: src/main/java/org/grapheco/elfinder/localfs/LocalFsVolume.java
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.grapheco.elfinder.service.FsItem;
import org.grapheco.elfinder.service.FsVolume;
import org.grapheco.elfinder.util.MimeTypesUtils;


	@Override
	public FsItem fromPath(String relativePath)
	{
		return fromFile(new File(_rootDir, relativePath));
	}

	@Override
	public String getDimensions(FsItem fsi)
	{
		return null;
	}

	@Override
	public long getLastModified(FsItem fsi)
	{
		return asFile(fsi).lastModified() / 1000;
	}

	@Override
	public String getMimeType(FsItem fsi)
	{
		File file = asFile(fsi);
		if (file.isDirectory())
			return "directory";

		String ext = FilenameUtils.getExtension(file.getName());
		if (ext != null && !ext.isEmpty())
		{
			String mimeType = MimeTypesUtils.getMimeType(ext);
			return mimeType == null ? MimeTypesUtils.UNKNOWN_MIME_TYPE