// Path: mug-protobuf/src/main/java/com/google/mu/protobuf/util/MoreValues.java
// static Value valueOf(double n) {
//   return Value.newBuilder().setNumberValue(n).build();
// }
// 
// Path: mug/src/main/java/com/google/mu/util/stream/BiCollector.java
// @FunctionalInterface
// public interface BiCollector<K, V, R> {
//   /**
//    * Returns a {@code Collector} that will first split the input elements using {@code toKey} and
//    * {@code toValue} and subsequently collect the bisected parts through this {@code BiCollector}.
//    *
//    * @param toKey
//    *        The function to read the key from the input entry.
//    *        May be applied on the same input entry multiple times.
//    *        Because input entries could be ephemeral like {@link java.util.Map.Entry},
//    *        applying the function on a previous input entry has undefined result.
//    * @param toValue
//    *        The function to read the value from the input entry.
//    *        May be applied on the same input entry multiple times.
//    *        Because input entries could be ephemeral like {@link java.util.Map.Entry},
//    *        applying the function on a previous input entry has undefined result.
//    * @param <E> used to abstract away the underlying pair/entry type used by {@link BiStream}.
//    */
//   // Deliberately avoid wildcards for toKey and toValue, because we don't expect
//   // users to call this method. Instead, users will typically provide method references matching
//   // this signature.
//   // Signatures with or without wildcards should both match.
//   // In other words, this signature optimizes flexibility for implementors, not callers.
//   <E> Collector<E, ?, R> splitting(Function<E, K> toKey, Function<E, V> toValue);
// }


import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.mu.protobuf.util.MoreValues.valueOf;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collector;
import com.google.common.collect.Maps;
import com.google.errorprone.annotations.CheckReturnValue;
import com.google.mu.util.stream.BiCollector;
import com.google.protobuf.ListValue;
import com.google.protobuf.Struct;
import com.google.protobuf.StructOrBuilder;
import com.google.protobuf.Value;
   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} or {@code value} is null
   */
  public static Struct struct(String name, ListValue value) {
    return struct(name, valueOf(value));
  }

  /**
   * Returns a {@link Collector} that collects input key-value pairs into {@link Struct}.
   *
   * <p>Duplicate keys (according to {@link CharSequence#toString()}) are not allowed.
   */
  public static <T> Collector<T, ?, Struct> toStruct(
      Function<? super T, ? extends CharSequence> keyFunction,
      Function<? super T, Value> valueFunction) {
    checkNotNull(keyFunction);
    checkNotNull(valueFunction);
    return Collector.of(
        StructBuilder::new,
        (builder, input) -> builder.add(keyFunction.apply(input).toString(), valueFunction.apply(input)),
        StructBuilder::addAllFields,
        StructBuilder::build);
  }

  /**
   * Returns a {@link BiCollector} that collects the input key-value pairs into {@link Struct}.
   *
   * <p>Duplicate keys (according to {@link CharSequence#toString()}) are not allowed.
   */
// Path: mug-protobuf/src/main/java/com/google/mu/protobuf/util/MoreValues.java
// static Value valueOf(double n) {
//   return Value.newBuilder().setNumberValue(n).build();
// }
// 
// Path: mug/src/main/java/com/google/mu/util/stream/BiCollector.java
// @FunctionalInterface
// public interface BiCollector<K, V, R> {
//   /**
//    * Returns a {@code Collector} that will first split the input elements using {@code toKey} and
//    * {@code toValue} and subsequently collect the bisected parts through this {@code BiCollector}.
//    *
//    * @param toKey
//    *        The function to read the key from the input entry.
//    *        May be applied on the same input entry multiple times.
//    *        Because input entries could be ephemeral like {@link java.util.Map.Entry},
//    *        applying the function on a previous input entry has undefined result.
//    * @param toValue
//    *        The function to read the value from the input entry.
//    *        May be applied on the same input entry multiple times.
//    *        Because input entries could be ephemeral like {@link java.util.Map.Entry},
//    *        applying the function on a previous input entry has undefined result.
//    * @param <E> used to abstract away the underlying pair/entry type used by {@link BiStream}.
//    */
//   // Deliberately avoid wildcards for toKey and toValue, because we don't expect
//   // users to call this method. Instead, users will typically provide method references matching
//   // this signature.
//   // Signatures with or without wildcards should both match.
//   // In other words, this signature optimizes flexibility for implementors, not callers.
//   <E> Collector<E, ?, R> splitting(Function<E, K> toKey, Function<E, V> toValue);
// }


// Path: mug-protobuf/src/main/java/com/google/mu/protobuf/util/MoreStructs.java
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.mu.protobuf.util.MoreValues.valueOf;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collector;
import com.google.common.collect.Maps;
import com.google.errorprone.annotations.CheckReturnValue;
import com.google.mu.util.stream.BiCollector;
import com.google.protobuf.ListValue;
import com.google.protobuf.Struct;
import com.google.protobuf.StructOrBuilder;
import com.google.protobuf.Value;

   * Returns a Struct with {@code name} and {@code value}.
   *
   * @throws NullPointerException if {@code name} or {@code value} is null
   */
  public static Struct struct(String name, ListValue value) {
    return struct(name, valueOf(value));
  }

  /**
   * Returns a {@link Collector} that collects input key-value pairs into {@link Struct}.
   *
   * <p>Duplicate keys (according to {@link CharSequence#toString()}) are not allowed.
   */
  public static <T> Collector<T, ?, Struct> toStruct(
      Function<? super T, ? extends CharSequence> keyFunction,
      Function<? super T, Value> valueFunction) {
    checkNotNull(keyFunction);
    checkNotNull(valueFunction);
    return Collector.of(
        StructBuilder::new,
        (builder, input) -> builder.add(keyFunction.apply(input).toString(), valueFunction.apply(input)),
        StructBuilder::addAllFields,
        StructBuilder::build);
  }

  /**
   * Returns a {@link BiCollector} that collects the input key-value pairs into {@link Struct}.
   *
   * <p>Duplicate keys (according to {@link CharSequence#toString()}) are not allowed.
   */
  public static BiCollector<CharSequence, Value, Struct> toStruct() {