// Path: core/src/main/java/it/nerdammer/spash/shell/common/SpashCollection.java
// public interface SpashCollection<T> extends Serializable {
// 
//     /**
//      * Prints the whole collection to the given writer.
//      *
//      * @param writer the writer on which the collection will be printed on.
//      */
//     void mkString(PrintWriter writer);
// 
//     /**
//      * Tranforms every element of the collection into another element.
//      *
//      * @param f the transformation function
//      * @param <R> the new type
//      * @return the transformed collection
//      */
//     <R> SpashCollection<R> map(SerializableFunction<T, R> f);
// 
//     /**
//      * Merges this collection to the one provided as input.
//      *
//      * @param coll the collection to merge
//      * @return the union of the two collections
//      */
//     SpashCollection<T> union(SpashCollection<T> coll);
// 
//     /**
//      * Filters a collection retaining only elements respecting the given condition.
//      *
//      * @param condition the condition that must evaluate to true for retained elements
//      * @return te resulting collection
//      */
//     SpashCollection<T> filter(SerializableFunction<T, Boolean> condition);
// 
//     /**
//      * Converts this collection to a Spark {@code JavaRDD}.
//      *
//      * @param sc the current Spark context
//      * @return a RDD corresponding to this collection
//      */
//     JavaRDD<T> toRDD(JavaSparkContext sc);
// 
//     /**
//      * Collects the whole collection into a {@code List}.
//      *
//      * @return the elements of the collection
//      */
//     List<T> collect();
// 
// }
// 
// Path: core/src/main/java/it/nerdammer/spash/shell/common/SpashCollectionListAdapter.java
// public class SpashCollectionListAdapter<T> implements SpashCollection<T> {
// 
//     /**
//      * The iterable object.
//      */
//     private List<T> target;
// 
//     public SpashCollectionListAdapter(List<T> target) {
//         this.target = target;
//     }
// 
//     @Override
//     public void mkString(PrintWriter writer) {
//         for(T el : target) {
//             writer.println(el != null ? el.toString() : "");
//         }
//     }
// 
//     @Override
//     public <R> SpashCollection<R> map(final SerializableFunction<T, R> f) {
//         return new SpashCollectionListAdapter<>(Lambda.convert(target, new Converter<T, R>() {
//             @Override
//             public R convert(T t) {
//                 return f.apply(t);
//             }
//         }));
//     }
// 
//     @Override
//     public SpashCollection<T> union(SpashCollection<T> coll) {
//         return new SpashCollectionUnionAdapter<>(this, coll);
//     }
// 
//     @Override
//     public SpashCollection<T> filter(final SerializableFunction<T, Boolean> condition) {
//         return new SpashCollectionListAdapter<>(Lambda.filter(new BaseMatcher<T>() {
//             @Override
//             public boolean matches(Object o) {
//                 return condition.apply((T) o);
//             }
//             @Override
//             public void describeTo(Description description) {
//             }
//         }, target));
//     }
// 
//     @Override
//     public JavaRDD<T> toRDD(JavaSparkContext sc) {
//         return sc.parallelize(this.target);
//     }
// 
//     @Override
//     public List<T> collect() {
//         return this.target;
//     }
// }


import com.google.common.collect.Lists;
import it.nerdammer.spash.shell.common.SpashCollection;
import it.nerdammer.spash.shell.common.SpashCollectionListAdapter;
import java.io.IOException;
import java.net.URI;
import java.nio.file.*;
import java.nio.file.attribute.PosixFileAttributes;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
package it.nerdammer.spash.shell.api.fs;



/**
 * A file system facade to access HDFS.
 *
 * @author Nicola Ferraro
 */
public class FileSystemFacadeImpl implements FileSystemFacade {

    private String host;

    private int port;

    public FileSystemFacadeImpl(String host, int port) {
        this.host = host;
        this.port = port;
    }

    @Override
    public FileSystem getFileSystem() {
        return FileSystems.getFileSystem(getURI("/"));
    }

    @Override
    public SpashCollection<Path> ls(String path) {
        if(path==null || !path.startsWith("/")) {
            throw new IllegalArgumentException("Paths must be absolute. Path=" + path);
        }

        try {
            URI uri = getURI(path);
            Path dir = Paths.get(uri);

            List<Path> children = Lists.newArrayList(Files.newDirectoryStream(dir, new DirectoryStream.Filter<Path>() {
                @Override
                public boolean accept(Path entry) throws IOException {
                    return true;
                }
            }));

// Path: core/src/main/java/it/nerdammer/spash/shell/common/SpashCollection.java
// public interface SpashCollection<T> extends Serializable {
// 
//     /**
//      * Prints the whole collection to the given writer.
//      *
//      * @param writer the writer on which the collection will be printed on.
//      */
//     void mkString(PrintWriter writer);
// 
//     /**
//      * Tranforms every element of the collection into another element.
//      *
//      * @param f the transformation function
//      * @param <R> the new type
//      * @return the transformed collection
//      */
//     <R> SpashCollection<R> map(SerializableFunction<T, R> f);
// 
//     /**
//      * Merges this collection to the one provided as input.
//      *
//      * @param coll the collection to merge
//      * @return the union of the two collections
//      */
//     SpashCollection<T> union(SpashCollection<T> coll);
// 
//     /**
//      * Filters a collection retaining only elements respecting the given condition.
//      *
//      * @param condition the condition that must evaluate to true for retained elements
//      * @return te resulting collection
//      */
//     SpashCollection<T> filter(SerializableFunction<T, Boolean> condition);
// 
//     /**
//      * Converts this collection to a Spark {@code JavaRDD}.
//      *
//      * @param sc the current Spark context
//      * @return a RDD corresponding to this collection
//      */
//     JavaRDD<T> toRDD(JavaSparkContext sc);
// 
//     /**
//      * Collects the whole collection into a {@code List}.
//      *
//      * @return the elements of the collection
//      */
//     List<T> collect();
// 
// }
// 
// Path: core/src/main/java/it/nerdammer/spash/shell/common/SpashCollectionListAdapter.java
// public class SpashCollectionListAdapter<T> implements SpashCollection<T> {
// 
//     /**
//      * The iterable object.
//      */
//     private List<T> target;
// 
//     public SpashCollectionListAdapter(List<T> target) {
//         this.target = target;
//     }
// 
//     @Override
//     public void mkString(PrintWriter writer) {
//         for(T el : target) {
//             writer.println(el != null ? el.toString() : "");
//         }
//     }
// 
//     @Override
//     public <R> SpashCollection<R> map(final SerializableFunction<T, R> f) {
//         return new SpashCollectionListAdapter<>(Lambda.convert(target, new Converter<T, R>() {
//             @Override
//             public R convert(T t) {
//                 return f.apply(t);
//             }
//         }));
//     }
// 
//     @Override
//     public SpashCollection<T> union(SpashCollection<T> coll) {
//         return new SpashCollectionUnionAdapter<>(this, coll);
//     }
// 
//     @Override
//     public SpashCollection<T> filter(final SerializableFunction<T, Boolean> condition) {
//         return new SpashCollectionListAdapter<>(Lambda.filter(new BaseMatcher<T>() {
//             @Override
//             public boolean matches(Object o) {
//                 return condition.apply((T) o);
//             }
//             @Override
//             public void describeTo(Description description) {
//             }
//         }, target));
//     }
// 
//     @Override
//     public JavaRDD<T> toRDD(JavaSparkContext sc) {
//         return sc.parallelize(this.target);
//     }
// 
//     @Override
//     public List<T> collect() {
//         return this.target;
//     }
// }


// Path: core/src/main/java/it/nerdammer/spash/shell/api/fs/FileSystemFacadeImpl.java
import com.google.common.collect.Lists;
import it.nerdammer.spash.shell.common.SpashCollection;
import it.nerdammer.spash.shell.common.SpashCollectionListAdapter;
import java.io.IOException;
import java.net.URI;
import java.nio.file.*;
import java.nio.file.attribute.PosixFileAttributes;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

package it.nerdammer.spash.shell.api.fs;



/**
 * A file system facade to access HDFS.
 *
 * @author Nicola Ferraro
 */
public class FileSystemFacadeImpl implements FileSystemFacade {

    private String host;

    private int port;

    public FileSystemFacadeImpl(String host, int port) {
        this.host = host;
        this.port = port;
    }

    @Override
    public FileSystem getFileSystem() {
        return FileSystems.getFileSystem(getURI("/"));
    }

    @Override
    public SpashCollection<Path> ls(String path) {
        if(path==null || !path.startsWith("/")) {
            throw new IllegalArgumentException("Paths must be absolute. Path=" + path);
        }

        try {
            URI uri = getURI(path);
            Path dir = Paths.get(uri);

            List<Path> children = Lists.newArrayList(Files.newDirectoryStream(dir, new DirectoryStream.Filter<Path>() {
                @Override
                public boolean accept(Path entry) throws IOException {
                    return true;
                }
            }));

            return new SpashCollectionListAdapter<>(children);