/*****************************************************************************
 * ------------------------------------------------------------------------- *
 * 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 com.google.mu.function;

import static java.util.Objects.requireNonNull;

import java.util.function.BiFunction;
import java.util.function.Function;

/**
 * A function with two result values.
 *
 * <p>Methods wishing to return two values should typically follow this pattern to take as parameter
 * a custom {@link BiFunction} so that the caller can choose the appropriate result type without
 * being forced to use {@code Pair} or {@code Map.Entry}.
 *
 * <p>See {@link java.util.stream.Collectors#teeing} in JDK 12 as an example.
 *
 * @param <F> the input type
 * @param <T1> the first output type
 * @param <T2> the second output type
 */
@FunctionalInterface
public interface DualValuedFunction<F, T1, T2> {
  /**
   * With {@code input}, calls this function and passes the two result values to the {@code output}
   * function (because Java has no built-in tuples).
   *
   * <p>An example is the {@link com.google.mu.util.Substring.Pattern#split(String, BiFunction)}
   * method. Its callers can typically split a string like this:
   *
   * <pre>{@code
   * first('=').split(string, (name, val) -> ...);
   * }</pre>
   *
   * The {@code split()} method (and its friend {@code splitThenTrim}) can then be
   * method-referenced as a {@code DualValuedFunction} and be used in a {@link
   * com.google.mu.util.stream.BiStream} chain, like:
   *
   * <pre>{@code
   * ImmutableSetMultimap<String, String> keyValues = lines.stream()
   *     .map(String::trim)
   *     .filter(l -> l.length() > 0)                     // not empty
   *     .filter(l -> !l.startsWith("//"))                // not comment
   *     .collect(toBiStream(first('=')::splitThenTrim))  // split each line to a key-value pair
   *     .collect(ImmutableSetMultimap::toImmutableSetMultimap);
   * }</pre>
   *
   * @throws NullPointerException if the {@code output} function is null.
   */
  // No wildcard on T1/T2 so that methods following or not following PECS can both be referenced.
  // Users should rarely need to call apply() directly.
  <R> R apply(F input, BiFunction<T1, T2, R> output);

  /**
   * Returns a composed function that first applies this function to its input,
   * and then applies the {@code after} function to the pair of results. If evaluation of either
   * function throws an exception, it is propagated to the caller of the composed function.
   *
   * @throws NullPointerException if the {@code after} function is null.
   */
  default <R> Function<F, R> andThen(BiFunction<? super T1, ? super T2, ? extends R> after) {
    @SuppressWarnings("unchecked")  // function is PECS, safe to cast.
    BiFunction<T1, T2, R> output = (BiFunction<T1, T2, R>) requireNonNull(after);
    return input -> apply(input, output);
  }
}

@@ -1349,47 +1349,11 @@
 ues 
-should typically follow this pattern to
+may
  tak
@@ -1370,20 +1370,10 @@
 eter
-%0A * a custom
+ a
  %7B@l
@@ -1395,24 +1395,27 @@
  so that the
+%0A *
  caller can 
@@ -1456,19 +1456,16 @@
  without
-%0A *
  being f
@@ -1492,16 +1492,19 @@
 Pair%7D or
+%0A *
  %7B@code 
@@ -1953,24 +1953,23 @@
  %3Cp%3E
-An e
+E
 xample
+s
  i
-s th
+nclud
 e %7B@
@@ -1977,364 +1977,100 @@
 ink 
-com.google.mu.util.Substring.Pattern#split(String, BiFunction)%7D%0A   * method. Its callers can typically split a string like this:%0A   *%0A   * %3Cpre%3E%7B@code%0A   * first('=').split(string, (name, val) -%3E ...);%0A   * %7D%3C/pre%3E%0A   *%0A   * The %7B@code split()%7D method (and its friend %7B@code splitThenTrim%7D) can then be%0A   * method-referenced as a %7B@code DualValued
+java.util.stream.Collectors#teeing%7D, %7B@link%0A   * com.google.mu.util.Both#mapToObj(Bi
 Function
 %7D an
@@ -2069,27 +2069,15 @@
 tion
+)
 %7D and 
-be used in a 
 %7B@li
@@ -2107,475 +2107,36 @@
 til.
-stream.BiStream%7D chain, like:%0A   *%0A   * %3Cpre%3E%7B@code%0A   * ImmutableSetMultimap%3CString, String%3E keyValues = lines.stream()%0A   *     .map(String::trim)%0A   *     .filter(l -%3E l.length() %3E 0)                     // not empty%0A   *     .filter(l -%3E !l.startsWith(%22//%22))                // not comment%0A   *     .collect(toBiStream(first('=')::splitThenTrim))  // split each line to a key-value pair%0A   *     .collect(ImmutableSetMultimap::toImmutableSetMultimap);%0A   * %7D%3C/pre%3E
+BiOptional#map(BiFunction)%7D.
 %0A   

fix DualValuedFunction javadoc