// Path: core/src/main/java/it/nerdammer/spash/shell/common/SerializableFunction.java
// public abstract class SerializableFunction<T, R> implements Function<T, R>, Converter<T, R>, Serializable {
// 
//     @Override
//     public R call(T t) throws Exception {
//         return apply(t);
//     }
// 
//     @Override
//     public R convert(T t) {
//         return apply(t);
//     }
// 
//     public abstract R apply(T v1);
// 
// }
// 
// 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/SpashCollectionEmptyAdapter.java
// public class SpashCollectionEmptyAdapter<T> implements SpashCollection<T> {
// 
//     public SpashCollectionEmptyAdapter() {
//     }
// 
//     @Override
//     public void mkString(PrintWriter writer) {
//     }
// 
//     @Override
//     public <R> SpashCollection<R> map(SerializableFunction<T, R> f) {
//         return new SpashCollectionEmptyAdapter<>();
//     }
// 
//     @Override
//     public SpashCollection<T> union(SpashCollection<T> coll) {
//         return coll;
//     }
// 
//     @Override
//     public SpashCollection<T> filter(SerializableFunction<T, Boolean> condition) {
//         return this;
//     }
// 
//     @Override
//     public JavaRDD<T> toRDD(JavaSparkContext sc) {
//         return sc.emptyRDD();
//     }
// 
//     @Override
//     public List<T> collect() {
//         return Collections.emptyList();
//     }
// }


import ch.lambdaj.Lambda;
import com.google.common.collect.ImmutableMap;
import it.nerdammer.spash.shell.command.*;
import it.nerdammer.spash.shell.common.SerializableFunction;
import it.nerdammer.spash.shell.common.SpashCollection;
import it.nerdammer.spash.shell.common.SpashCollectionEmptyAdapter;
import java.util.List;
package it.nerdammer.spash.shell.command.spi;



/**
 * Command to filter collections of data.
 *
 * @author Nicola Ferraro
 */
public class GrepCommand extends AbstractCommand {

    public GrepCommand(String commandString) {
        super(commandString, ImmutableMap.<String, Boolean>builder()
                .put("v", false)
                .put("i", false)
                .build());
    }

    @Override
    public CommandResult execute(ExecutionContext ctx) {

        List<String> args = this.getArguments();
        if(args.size()==0) {
            return CommandResult.error(this, "Missing argument");
        } else if(args.size()==1) {
            // pipe mode
// Path: core/src/main/java/it/nerdammer/spash/shell/common/SerializableFunction.java
// public abstract class SerializableFunction<T, R> implements Function<T, R>, Converter<T, R>, Serializable {
// 
//     @Override
//     public R call(T t) throws Exception {
//         return apply(t);
//     }
// 
//     @Override
//     public R convert(T t) {
//         return apply(t);
//     }
// 
//     public abstract R apply(T v1);
// 
// }
// 
// 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/SpashCollectionEmptyAdapter.java
// public class SpashCollectionEmptyAdapter<T> implements SpashCollection<T> {
// 
//     public SpashCollectionEmptyAdapter() {
//     }
// 
//     @Override
//     public void mkString(PrintWriter writer) {
//     }
// 
//     @Override
//     public <R> SpashCollection<R> map(SerializableFunction<T, R> f) {
//         return new SpashCollectionEmptyAdapter<>();
//     }
// 
//     @Override
//     public SpashCollection<T> union(SpashCollection<T> coll) {
//         return coll;
//     }
// 
//     @Override
//     public SpashCollection<T> filter(SerializableFunction<T, Boolean> condition) {
//         return this;
//     }
// 
//     @Override
//     public JavaRDD<T> toRDD(JavaSparkContext sc) {
//         return sc.emptyRDD();
//     }
// 
//     @Override
//     public List<T> collect() {
//         return Collections.emptyList();
//     }
// }


// Path: core/src/main/java/it/nerdammer/spash/shell/command/spi/GrepCommand.java
import ch.lambdaj.Lambda;
import com.google.common.collect.ImmutableMap;
import it.nerdammer.spash.shell.command.*;
import it.nerdammer.spash.shell.common.SerializableFunction;
import it.nerdammer.spash.shell.common.SpashCollection;
import it.nerdammer.spash.shell.common.SpashCollectionEmptyAdapter;
import java.util.List;

package it.nerdammer.spash.shell.command.spi;



/**
 * Command to filter collections of data.
 *
 * @author Nicola Ferraro
 */
public class GrepCommand extends AbstractCommand {

    public GrepCommand(String commandString) {
        super(commandString, ImmutableMap.<String, Boolean>builder()
                .put("v", false)
                .put("i", false)
                .build());
    }

    @Override
    public CommandResult execute(ExecutionContext ctx) {

        List<String> args = this.getArguments();
        if(args.size()==0) {
            return CommandResult.error(this, "Missing argument");
        } else if(args.size()==1) {
            // pipe mode
            SpashCollection<String> prev = ctx.getPreviousCommandResult() != null ? ctx.getPreviousCommandResult().getContent() : null;