// Path: agera/src/main/java/com/google/android/agera/Common.java
// static final NullOperator NULL_OPERATOR = new NullOperator();
// 
// Path: agera/src/main/java/com/google/android/agera/Common.java
// static final StaticCondicate TRUE_CONDICATE = new StaticCondicate(true);
// 
// Path: agera/src/main/java/com/google/android/agera/FunctionCompilerStates.java
// interface FItem<TPrev, TFrom> extends FBase<TPrev, TFrom> {
//   /**
//    * Adds a {@link Function} to the behavior chain to unpack an item into a {@link List}, allowing
//    * list behaviors to be used from this point on.
//    *
//    * @param function the unpack function
//    */
//   @NonNull
//   <TTo> FList<TTo, List<TTo>, TFrom> unpack(@NonNull Function<? super TPrev, List<TTo>> function);
// }
// 
// Path: agera/src/main/java/com/google/android/agera/FunctionCompilerStates.java
// interface FList<TPrev, TPrevList, TFrom> extends FBase<TPrevList, TFrom> {
// 
//   /**
//    * Adds a {@link Function} to the behavior chain to change the entire list to a new list.
//    *
//    * <p>The {@code morph} directive is functionally equivalent to {@code apply}, which treats the
//    * input list as a single item. But {@code morph} is aware of the list-typed output and allows
//    * list behaviors to follow immediately. Since the only difference between {@link #apply} and
//    * {@code morph} is the next state of the compiler, {@code thenMorph} does not exist since
//    * {@link #thenApply} can be used in its place.
//    *
//    * @param function the function to apply to the list
//    */
//   @NonNull
//   <TTo> FList<TTo, List<TTo>, TFrom> morph(@NonNull Function<List<TPrev>, List<TTo>> function);
// 
//   /**
//    * Adds a {@link Function} to the behavior chain to map each item into a new type.
//    *
//    * @param function the function to apply to each item to create a new list
//    */
//   @NonNull
//   <TTo> FList<TTo, List<TTo>, TFrom> map(@NonNull Function<TPrev, TTo> function);
// 
//   /**
//    * Adds a {@link Function} to the end of the behavior chain to map each item into a new type.
//    *
//    * @param function the function to apply to each item to create a new list
//    */
//   @NonNull
//   <TTo> Function<TFrom, List<TTo>> thenMap(@NonNull Function<? super TPrev, TTo> function);
// 
//   /**
//    * Adds a {@link Predicate} to the behavior chain to filter out items.
//    *
//    * @param filter the predicate to filter by
//    */
//   @NonNull
//   FList<TPrev, TPrevList, TFrom> filter(@NonNull Predicate<? super TPrev> filter);
// 
//   /**
//    * Adds a max number of item limit to the behavior chain.
//    *
//    * @param limit the max number of items the list is limited to
//    */
//   @NonNull
//   FList<TPrev, TPrevList, TFrom> limit(int limit);
// 
//   /**
//    * Adds a {@link Comparator} to the behavior chain to sort the items.
//    *
//    * @param comparator the comparator to sort the items
//    */
//   @NonNull
//   FList<TPrev, TPrevList, TFrom> sort(@NonNull Comparator<TPrev> comparator);
// 
//   /**
//    * Adds a {@link Predicate} to the end of the behavior chain to filter out items.
//    *
//    * @param filter the predicate to filter by
//    */
//   @NonNull
//   Function<TFrom, TPrevList> thenFilter(@NonNull Predicate<? super TPrev> filter);
// 
//   /**
//    * Adds a max number of item limit to the end of the behavior chain.
//    *
//    * @param limit the max number of items the list is limited to
//    */
//   @NonNull
//   Function<TFrom, TPrevList> thenLimit(int limit);
// 
//   /**
//    * Adds a {@link Comparator} to the behavior chain to sort the items.
//    *
//    * @param comparator the comparator to sort the items
//    */
//   @NonNull
//   Function<TFrom, TPrevList> thenSort(@NonNull Comparator<TPrev> comparator);
// }


import static com.google.android.agera.Common.NULL_OPERATOR;
import static com.google.android.agera.Common.TRUE_CONDICATE;
import static com.google.android.agera.Preconditions.checkNotNull;
import static java.util.Collections.emptyList;
import android.support.annotation.NonNull;
import com.google.android.agera.FunctionCompilerStates.FItem;
import com.google.android.agera.FunctionCompilerStates.FList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
  public FList unpack(@NonNull final Function function) {
    addFunction(function);
    return this;
  }

  @NonNull
  @Override
  public FItem apply(@NonNull final Function function) {
    addFunction(function);
    return this;
  }

  @NonNull
  @Override
  public FList morph(@NonNull final Function function) {
    addFunction(function);
    return this;
  }

  @NonNull
  @Override
  public FList filter(@NonNull final Predicate filter) {
    if (filter != TRUE_CONDICATE) {
      addFunction(new FilterFunction(filter));
    }
    return this;
  }

  @NonNull
  @Override
// Path: agera/src/main/java/com/google/android/agera/Common.java
// static final NullOperator NULL_OPERATOR = new NullOperator();
// 
// Path: agera/src/main/java/com/google/android/agera/Common.java
// static final StaticCondicate TRUE_CONDICATE = new StaticCondicate(true);
// 
// Path: agera/src/main/java/com/google/android/agera/FunctionCompilerStates.java
// interface FItem<TPrev, TFrom> extends FBase<TPrev, TFrom> {
//   /**
//    * Adds a {@link Function} to the behavior chain to unpack an item into a {@link List}, allowing
//    * list behaviors to be used from this point on.
//    *
//    * @param function the unpack function
//    */
//   @NonNull
//   <TTo> FList<TTo, List<TTo>, TFrom> unpack(@NonNull Function<? super TPrev, List<TTo>> function);
// }
// 
// Path: agera/src/main/java/com/google/android/agera/FunctionCompilerStates.java
// interface FList<TPrev, TPrevList, TFrom> extends FBase<TPrevList, TFrom> {
// 
//   /**
//    * Adds a {@link Function} to the behavior chain to change the entire list to a new list.
//    *
//    * <p>The {@code morph} directive is functionally equivalent to {@code apply}, which treats the
//    * input list as a single item. But {@code morph} is aware of the list-typed output and allows
//    * list behaviors to follow immediately. Since the only difference between {@link #apply} and
//    * {@code morph} is the next state of the compiler, {@code thenMorph} does not exist since
//    * {@link #thenApply} can be used in its place.
//    *
//    * @param function the function to apply to the list
//    */
//   @NonNull
//   <TTo> FList<TTo, List<TTo>, TFrom> morph(@NonNull Function<List<TPrev>, List<TTo>> function);
// 
//   /**
//    * Adds a {@link Function} to the behavior chain to map each item into a new type.
//    *
//    * @param function the function to apply to each item to create a new list
//    */
//   @NonNull
//   <TTo> FList<TTo, List<TTo>, TFrom> map(@NonNull Function<TPrev, TTo> function);
// 
//   /**
//    * Adds a {@link Function} to the end of the behavior chain to map each item into a new type.
//    *
//    * @param function the function to apply to each item to create a new list
//    */
//   @NonNull
//   <TTo> Function<TFrom, List<TTo>> thenMap(@NonNull Function<? super TPrev, TTo> function);
// 
//   /**
//    * Adds a {@link Predicate} to the behavior chain to filter out items.
//    *
//    * @param filter the predicate to filter by
//    */
//   @NonNull
//   FList<TPrev, TPrevList, TFrom> filter(@NonNull Predicate<? super TPrev> filter);
// 
//   /**
//    * Adds a max number of item limit to the behavior chain.
//    *
//    * @param limit the max number of items the list is limited to
//    */
//   @NonNull
//   FList<TPrev, TPrevList, TFrom> limit(int limit);
// 
//   /**
//    * Adds a {@link Comparator} to the behavior chain to sort the items.
//    *
//    * @param comparator the comparator to sort the items
//    */
//   @NonNull
//   FList<TPrev, TPrevList, TFrom> sort(@NonNull Comparator<TPrev> comparator);
// 
//   /**
//    * Adds a {@link Predicate} to the end of the behavior chain to filter out items.
//    *
//    * @param filter the predicate to filter by
//    */
//   @NonNull
//   Function<TFrom, TPrevList> thenFilter(@NonNull Predicate<? super TPrev> filter);
// 
//   /**
//    * Adds a max number of item limit to the end of the behavior chain.
//    *
//    * @param limit the max number of items the list is limited to
//    */
//   @NonNull
//   Function<TFrom, TPrevList> thenLimit(int limit);
// 
//   /**
//    * Adds a {@link Comparator} to the behavior chain to sort the items.
//    *
//    * @param comparator the comparator to sort the items
//    */
//   @NonNull
//   Function<TFrom, TPrevList> thenSort(@NonNull Comparator<TPrev> comparator);
// }


// Path: agera/src/main/java/com/google/android/agera/FunctionCompiler.java
import static com.google.android.agera.Common.NULL_OPERATOR;
import static com.google.android.agera.Common.TRUE_CONDICATE;
import static com.google.android.agera.Preconditions.checkNotNull;
import static java.util.Collections.emptyList;
import android.support.annotation.NonNull;
import com.google.android.agera.FunctionCompilerStates.FItem;
import com.google.android.agera.FunctionCompilerStates.FList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

  public FList unpack(@NonNull final Function function) {
    addFunction(function);
    return this;
  }

  @NonNull
  @Override
  public FItem apply(@NonNull final Function function) {
    addFunction(function);
    return this;
  }

  @NonNull
  @Override
  public FList morph(@NonNull final Function function) {
    addFunction(function);
    return this;
  }

  @NonNull
  @Override
  public FList filter(@NonNull final Predicate filter) {
    if (filter != TRUE_CONDICATE) {
      addFunction(new FilterFunction(filter));
    }
    return this;
  }

  @NonNull
  @Override
  public FList limit(final int limit) {