/*
 * Copyright 2010 Henry Coles
 *
 * Licensed 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.pitest.functional.prelude;

import java.io.PrintStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

import org.pitest.functional.predicate.And;
import org.pitest.functional.predicate.Or;

/**
 * @author henry
 *
 */
public abstract class Prelude {

  @SafeVarargs
  public static final <A> And<A> and(final Predicate<A>... ps) {
    return new And<>(Arrays.asList(ps));
  }

  public static final <A> And<A> and(final Iterable<? extends Predicate<A>> ps) {
    return new And<>(ps);
  }

  public static final <A> Predicate<A> not(final Predicate<A> p) {
    return p.negate();
  }

  @SafeVarargs
  public static final <A> Or<A> or(final Predicate<A>... ps) {
    return new Or<>(Arrays.asList(ps));
  }

  public static final <A> Or<A> or(final Iterable<Predicate<A>> ps) {
    return new Or<>(ps);
  }

  public static final <A> Consumer<A> accumulateTo(
      final Collection<A> collection) {
    return collection::add;

  }

  public static <A, B> Consumer<A> putToMap(final Map<A, B> map,
      final B value) {
    return key -> map.put(key, value);
  }

  public static final <A> Function<A, A> id() {
    return a -> a;
  }

  public static final <A> Function<A, A> id(final Class<A> type) {
    return id();
  }

  public static final <T> Consumer<T> println() {
    return printlnTo(System.out);
  }

  public static final <T> Consumer<T> println(final Class<T> type) {
    return println();
  }

  public static final <T> Consumer<T> printlnTo(final Class<T> type,
      final PrintStream stream) {
    return printlnTo(stream);
  }

  public static final <T> Consumer<T> printlnTo(final PrintStream stream) {
    return stream::println;
  }

  public static <T> Consumer<T> printlnWith(final T t) {
    return a -> System.out.println(t + " : " + a);
  }

  public static <T extends Number> Predicate<T> isGreaterThan(final T value) {
    return o -> o.longValue() > value.longValue();
  }

  public static <T> Function<T, Iterable<T>> asList(final Class<T> type) {
    return Collections::singletonList;
  }

  public static <T> Consumer<T> noSideEffect(final Class<T> clazz) {
    return a -> {
    };
  }
}

@@ -1037,38 +1037,32 @@
   public static 
-final 
 %3CA%3E And%3CA%3E and(f
@@ -1146,30 +1146,24 @@
 blic static 
-final 
 %3CA%3E And%3CA%3E a
@@ -1253,30 +1253,24 @@
 blic static 
-final 
 %3CA%3E Predicat
@@ -1353,38 +1353,32 @@
   public static 
-final 
 %3CA%3E Or%3CA%3E or(fin
@@ -1459,30 +1459,24 @@
 blic static 
-final 
 %3CA%3E Or%3CA%3E or
@@ -1553,30 +1553,24 @@
 blic static 
-final 
 %3CA%3E Consumer
@@ -1801,38 +1801,32 @@
   public static 
-final 
 %3CA%3E Function%3CA, 
@@ -1875,22 +1875,16 @@
  static 
-final 
 %3CA%3E Func
@@ -1950,38 +1950,32 @@
   public static 
-final 
 %3CT%3E Consumer%3CT%3E 
@@ -2033,38 +2033,32 @@
   public static 
-final 
 %3CT%3E Consumer%3CT%3E 
@@ -2123,38 +2123,32 @@
   public static 
-final 
 %3CT%3E Consumer%3CT%3E 
@@ -2178,16 +2178,52 @@
 %3E type,%0A
+                                    
       fi
@@ -2299,22 +2299,16 @@
  static 
-final 
 %3CT%3E Cons

remove redundant final modifiers