http://git-wip-us.apache.org/repos/asf/beam/blob/7e04924e/sdks/java/core/src/main/java/org/apache/beam/sdk/util/AppliedCombineFn.java
----------------------------------------------------------------------
diff --git 
a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/AppliedCombineFn.java 
b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/AppliedCombineFn.java
index 30b302c..b16aadc 100644
--- 
a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/AppliedCombineFn.java
+++ 
b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/AppliedCombineFn.java
@@ -23,13 +23,12 @@ import 
org.apache.beam.sdk.coders.CannotProvideCoderException;
 import org.apache.beam.sdk.coders.Coder;
 import org.apache.beam.sdk.coders.CoderRegistry;
 import org.apache.beam.sdk.coders.KvCoder;
-import org.apache.beam.sdk.transforms.CombineFnBase.PerKeyCombineFn;
-import 
org.apache.beam.sdk.transforms.CombineWithContext.KeyedCombineFnWithContext;
+import org.apache.beam.sdk.transforms.CombineFnBase.GlobalCombineFn;
 import org.apache.beam.sdk.values.PCollectionView;
 
 /**
- * A {@link KeyedCombineFnWithContext} with a fixed accumulator coder. This is 
created from a
- * specific application of the {@link KeyedCombineFnWithContext}.
+ * A {@link GlobalCombineFn} with a fixed accumulator coder. This is created 
from a
+ * specific application of the {@link GlobalCombineFn}.
  *
  *  <p>Because the {@code AccumT} may reference {@code InputT}, the specific 
{@code Coder<AccumT>}
  *  may depend on the {@code Coder<InputT>}.
@@ -41,14 +40,14 @@ import org.apache.beam.sdk.values.PCollectionView;
  */
 public class AppliedCombineFn<K, InputT, AccumT, OutputT> implements 
Serializable {
 
-  private final PerKeyCombineFn<K, InputT, AccumT, OutputT> fn;
+  private final GlobalCombineFn<InputT, AccumT, OutputT> fn;
   private final Coder<AccumT> accumulatorCoder;
 
   private final Iterable<PCollectionView<?>> sideInputViews;
   private final KvCoder<K, InputT> kvCoder;
   private final WindowingStrategy<?, ?> windowingStrategy;
 
-  private AppliedCombineFn(PerKeyCombineFn<K, InputT, AccumT, OutputT> fn,
+  private AppliedCombineFn(GlobalCombineFn<InputT, AccumT, OutputT> fn,
       Coder<AccumT> accumulatorCoder, Iterable<PCollectionView<?>> 
sideInputViews,
       KvCoder<K, InputT> kvCoder, WindowingStrategy<?, ?> windowingStrategy) {
     this.fn = fn;
@@ -60,41 +59,41 @@ public class AppliedCombineFn<K, InputT, AccumT, OutputT> 
implements Serializabl
 
   public static <K, InputT, AccumT, OutputT> AppliedCombineFn<K, InputT, 
AccumT, OutputT>
       withAccumulatorCoder(
-          PerKeyCombineFn<? super K, ? super InputT, AccumT, OutputT> fn,
+          GlobalCombineFn<? super InputT, AccumT, OutputT> fn,
           Coder<AccumT> accumCoder) {
     return withAccumulatorCoder(fn, accumCoder, null, null, null);
   }
 
   public static <K, InputT, AccumT, OutputT> AppliedCombineFn<K, InputT, 
AccumT, OutputT>
       withAccumulatorCoder(
-          PerKeyCombineFn<? super K, ? super InputT, AccumT, OutputT> fn,
+          GlobalCombineFn<? super InputT, AccumT, OutputT> fn,
           Coder<AccumT> accumCoder, Iterable<PCollectionView<?>> 
sideInputViews,
           KvCoder<K, InputT> kvCoder, WindowingStrategy<?, ?> 
windowingStrategy) {
     // Casting down the K and InputT is safe because they're only used as 
inputs.
     @SuppressWarnings("unchecked")
-    PerKeyCombineFn<K, InputT, AccumT, OutputT> clonedFn =
-        (PerKeyCombineFn<K, InputT, AccumT, OutputT>) 
SerializableUtils.clone(fn);
+    GlobalCombineFn<InputT, AccumT, OutputT> clonedFn =
+        (GlobalCombineFn<InputT, AccumT, OutputT>) SerializableUtils.clone(fn);
     return create(clonedFn, accumCoder, sideInputViews, kvCoder, 
windowingStrategy);
   }
 
   @VisibleForTesting
   public static <K, InputT, AccumT, OutputT> AppliedCombineFn<K, InputT, 
AccumT, OutputT>
-      withInputCoder(PerKeyCombineFn<? super K, ? super InputT, AccumT, 
OutputT> fn,
+      withInputCoder(GlobalCombineFn<? super InputT, AccumT, OutputT> fn,
           CoderRegistry registry, KvCoder<K, InputT> kvCoder) {
     return withInputCoder(fn, registry, kvCoder, null, null);
   }
 
   public static <K, InputT, AccumT, OutputT> AppliedCombineFn<K, InputT, 
AccumT, OutputT>
-      withInputCoder(PerKeyCombineFn<? super K, ? super InputT, AccumT, 
OutputT> fn,
+      withInputCoder(GlobalCombineFn<? super InputT, AccumT, OutputT> fn,
           CoderRegistry registry, KvCoder<K, InputT> kvCoder,
           Iterable<PCollectionView<?>> sideInputViews, WindowingStrategy<?, ?> 
windowingStrategy) {
     // Casting down the K and InputT is safe because they're only used as 
inputs.
     @SuppressWarnings("unchecked")
-    PerKeyCombineFn<K, InputT, AccumT, OutputT> clonedFn =
-        (PerKeyCombineFn<K, InputT, AccumT, OutputT>) 
SerializableUtils.clone(fn);
+    GlobalCombineFn<InputT, AccumT, OutputT> clonedFn =
+        (GlobalCombineFn<InputT, AccumT, OutputT>) SerializableUtils.clone(fn);
     try {
-      Coder<AccumT> accumulatorCoder = clonedFn.getAccumulatorCoder(
-          registry, kvCoder.getKeyCoder(), kvCoder.getValueCoder());
+      Coder<AccumT> accumulatorCoder =
+          clonedFn.getAccumulatorCoder(registry, kvCoder.getValueCoder());
       return create(clonedFn, accumulatorCoder, sideInputViews, kvCoder, 
windowingStrategy);
     } catch (CannotProvideCoderException e) {
       throw new IllegalStateException("Could not determine coder for 
accumulator", e);
@@ -102,14 +101,14 @@ public class AppliedCombineFn<K, InputT, AccumT, OutputT> 
implements Serializabl
   }
 
   private static <K, InputT, AccumT, OutputT> AppliedCombineFn<K, InputT, 
AccumT, OutputT> create(
-      PerKeyCombineFn<K, InputT, AccumT, OutputT> fn,
+      GlobalCombineFn<InputT, AccumT, OutputT> fn,
       Coder<AccumT> accumulatorCoder, Iterable<PCollectionView<?>> 
sideInputViews,
       KvCoder<K, InputT> kvCoder, WindowingStrategy<?, ?> windowingStrategy) {
     return new AppliedCombineFn<>(
         fn, accumulatorCoder, sideInputViews, kvCoder, windowingStrategy);
   }
 
-  public PerKeyCombineFn<K, InputT, AccumT, OutputT> getFn() {
+  public GlobalCombineFn<InputT, AccumT, OutputT> getFn() {
     return fn;
   }
 

http://git-wip-us.apache.org/repos/asf/beam/blob/7e04924e/sdks/java/core/src/main/java/org/apache/beam/sdk/util/CombineFnUtil.java
----------------------------------------------------------------------
diff --git 
a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/CombineFnUtil.java 
b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/CombineFnUtil.java
index a9a0178..a394180 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/CombineFnUtil.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/CombineFnUtil.java
@@ -24,12 +24,9 @@ import 
org.apache.beam.sdk.coders.CannotProvideCoderException;
 import org.apache.beam.sdk.coders.Coder;
 import org.apache.beam.sdk.coders.CoderRegistry;
 import org.apache.beam.sdk.transforms.Combine.CombineFn;
-import org.apache.beam.sdk.transforms.Combine.KeyedCombineFn;
 import org.apache.beam.sdk.transforms.CombineFnBase.GlobalCombineFn;
-import org.apache.beam.sdk.transforms.CombineFnBase.PerKeyCombineFn;
 import org.apache.beam.sdk.transforms.CombineWithContext.CombineFnWithContext;
 import org.apache.beam.sdk.transforms.CombineWithContext.Context;
-import 
org.apache.beam.sdk.transforms.CombineWithContext.KeyedCombineFnWithContext;
 import org.apache.beam.sdk.transforms.display.DisplayData;
 import org.apache.beam.sdk.util.state.StateContext;
 
@@ -37,20 +34,21 @@ import org.apache.beam.sdk.util.state.StateContext;
  * Static utility methods that create combine function instances.
  */
 public class CombineFnUtil {
+
   /**
-   * Returns the partial application of the {@link KeyedCombineFnWithContext} 
to a specific
-   * context to produce a {@link KeyedCombineFn}.
+   * Returns the partial application of the {@link CombineFnWithContext} to a 
specific context
+   * to produce a {@link CombineFn}.
    *
-   * <p>The returned {@link KeyedCombineFn} cannot be serialized.
+   * <p>The returned {@link CombineFn} cannot be serialized.
    */
-  public static <K, InputT, AccumT, OutputT> KeyedCombineFn<K, InputT, AccumT, 
OutputT>
-  bindContext(
-      KeyedCombineFnWithContext<K, InputT, AccumT, OutputT> combineFn,
+  public static <K, InputT, AccumT, OutputT> CombineFn<InputT, AccumT, 
OutputT> bindContext(
+      CombineFnWithContext<InputT, AccumT, OutputT> combineFn,
       StateContext<?> stateContext) {
     Context context = 
CombineContextFactory.createFromStateContext(stateContext);
-    return new NonSerializableBoundedKeyedCombineFn<>(combineFn, context);
+    return new NonSerializableBoundedCombineFn<>(combineFn, context);
   }
 
+
   /**
    * Return a {@link CombineFnWithContext} from the given {@link 
GlobalCombineFn}.
    */
@@ -110,100 +108,55 @@ public class CombineFnUtil {
     }
   }
 
-  /**
-   * Return a {@link KeyedCombineFnWithContext} from the given {@link 
PerKeyCombineFn}.
-   */
-  public static <K, InputT, AccumT, OutputT> KeyedCombineFnWithContext<K, 
InputT, AccumT, OutputT>
-  toFnWithContext(PerKeyCombineFn<K, InputT, AccumT, OutputT> perKeyCombineFn) 
{
-    if (perKeyCombineFn instanceof KeyedCombineFnWithContext) {
-      @SuppressWarnings("unchecked")
-      KeyedCombineFnWithContext<K, InputT, AccumT, OutputT> 
keyedCombineFnWithContext =
-          (KeyedCombineFnWithContext<K, InputT, AccumT, OutputT>) 
perKeyCombineFn;
-      return keyedCombineFnWithContext;
-    } else {
-      @SuppressWarnings("unchecked")
-      final KeyedCombineFn<K, InputT, AccumT, OutputT> keyedCombineFn =
-          (KeyedCombineFn<K, InputT, AccumT, OutputT>) perKeyCombineFn;
-      return new KeyedCombineFnWithContext<K, InputT, AccumT, OutputT>() {
-        @Override
-        public AccumT createAccumulator(K key, Context c) {
-          return keyedCombineFn.createAccumulator(key);
-        }
-        @Override
-        public AccumT addInput(K key, AccumT accumulator, InputT value, 
Context c) {
-          return keyedCombineFn.addInput(key, accumulator, value);
-        }
-        @Override
-        public AccumT mergeAccumulators(K key, Iterable<AccumT> accumulators, 
Context c) {
-          return keyedCombineFn.mergeAccumulators(key, accumulators);
-        }
-        @Override
-        public OutputT extractOutput(K key, AccumT accumulator, Context c) {
-          return keyedCombineFn.extractOutput(key, accumulator);
-        }
-        @Override
-        public AccumT compact(K key, AccumT accumulator, Context c) {
-          return keyedCombineFn.compact(key, accumulator);
-        }
-        @Override
-        public Coder<AccumT> getAccumulatorCoder(CoderRegistry registry, 
Coder<K> keyCoder,
-            Coder<InputT> inputCoder) throws CannotProvideCoderException {
-          return keyedCombineFn.getAccumulatorCoder(registry, keyCoder, 
inputCoder);
-        }
-        @Override
-        public Coder<OutputT> getDefaultOutputCoder(CoderRegistry registry, 
Coder<K> keyCoder,
-            Coder<InputT> inputCoder) throws CannotProvideCoderException {
-          return keyedCombineFn.getDefaultOutputCoder(registry, keyCoder, 
inputCoder);
-        }
-        @Override
-        public void populateDisplayData(DisplayData.Builder builder) {
-          keyedCombineFn.populateDisplayData(builder);
-        }
-      };
-    }
-  }
-
-  private static class NonSerializableBoundedKeyedCombineFn<K, InputT, AccumT, 
OutputT>
-      extends KeyedCombineFn<K, InputT, AccumT, OutputT> {
-    private final KeyedCombineFnWithContext<K, InputT, AccumT, OutputT> 
combineFn;
+  private static class NonSerializableBoundedCombineFn<InputT, AccumT, OutputT>
+      extends CombineFn<InputT, AccumT, OutputT> {
+    private final CombineFnWithContext<InputT, AccumT, OutputT> combineFn;
     private final Context context;
 
-    private NonSerializableBoundedKeyedCombineFn(
-        KeyedCombineFnWithContext<K, InputT, AccumT, OutputT> combineFn,
-        Context context) {
+    private NonSerializableBoundedCombineFn(
+        CombineFnWithContext<InputT, AccumT, OutputT> combineFn, Context 
context) {
       this.combineFn = combineFn;
       this.context = context;
     }
+
     @Override
-    public AccumT createAccumulator(K key) {
-      return combineFn.createAccumulator(key, context);
+    public AccumT createAccumulator() {
+      return combineFn.createAccumulator(context);
     }
+
     @Override
-    public AccumT addInput(K key, AccumT accumulator, InputT value) {
-      return combineFn.addInput(key, accumulator, value, context);
+    public AccumT addInput(AccumT accumulator, InputT value) {
+      return combineFn.addInput(accumulator, value, context);
     }
+
     @Override
-    public AccumT mergeAccumulators(K key, Iterable<AccumT> accumulators) {
-      return combineFn.mergeAccumulators(key, accumulators, context);
+    public AccumT mergeAccumulators(Iterable<AccumT> accumulators) {
+      return combineFn.mergeAccumulators(accumulators, context);
     }
+
     @Override
-    public OutputT extractOutput(K key, AccumT accumulator) {
-      return combineFn.extractOutput(key, accumulator, context);
+    public OutputT extractOutput(AccumT accumulator) {
+      return combineFn.extractOutput(accumulator, context);
     }
+
     @Override
-    public AccumT compact(K key, AccumT accumulator) {
-      return combineFn.compact(key, accumulator, context);
+    public AccumT compact(AccumT accumulator) {
+      return combineFn.compact(accumulator, context);
     }
+
     @Override
-    public Coder<AccumT> getAccumulatorCoder(CoderRegistry registry, Coder<K> 
keyCoder,
-        Coder<InputT> inputCoder) throws CannotProvideCoderException {
-      return combineFn.getAccumulatorCoder(registry, keyCoder, inputCoder);
+    public Coder<AccumT> getAccumulatorCoder(CoderRegistry registry, 
Coder<InputT> inputCoder)
+        throws CannotProvideCoderException {
+      return combineFn.getAccumulatorCoder(registry, inputCoder);
     }
+
     @Override
-    public Coder<OutputT> getDefaultOutputCoder(CoderRegistry registry, 
Coder<K> keyCoder,
-        Coder<InputT> inputCoder) throws CannotProvideCoderException {
-      return combineFn.getDefaultOutputCoder(registry, keyCoder, inputCoder);
+    public Coder<OutputT> getDefaultOutputCoder(
+        CoderRegistry registry, Coder<InputT> inputCoder)
+        throws CannotProvideCoderException {
+      return combineFn.getDefaultOutputCoder(registry, inputCoder);
     }
+
     @Override
     public void populateDisplayData(DisplayData.Builder builder) {
       combineFn.populateDisplayData(builder);

http://git-wip-us.apache.org/repos/asf/beam/blob/7e04924e/sdks/java/core/src/main/java/org/apache/beam/sdk/util/state/StateBinder.java
----------------------------------------------------------------------
diff --git 
a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/state/StateBinder.java 
b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/state/StateBinder.java
index f9ab115..6fe37a1 100644
--- 
a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/state/StateBinder.java
+++ 
b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/state/StateBinder.java
@@ -45,20 +45,11 @@ public interface StateBinder<K> {
       Coder<AccumT> accumCoder,
       Combine.CombineFn<InputT, AccumT, OutputT> combineFn);
 
-  <InputT, AccumT, OutputT>
-  CombiningState<InputT, AccumT, OutputT> bindKeyedCombining(
-          String id,
-          StateSpec<? super K, CombiningState<InputT, AccumT, OutputT>> spec,
-          Coder<AccumT> accumCoder,
-          Combine.KeyedCombineFn<? super K, InputT, AccumT, OutputT> 
combineFn);
-
-  <InputT, AccumT, OutputT>
-  CombiningState<InputT, AccumT, OutputT> bindKeyedCombiningWithContext(
-          String id,
-          StateSpec<? super K, CombiningState<InputT, AccumT, OutputT>> spec,
-          Coder<AccumT> accumCoder,
-          CombineWithContext.KeyedCombineFnWithContext<? super K, InputT, 
AccumT, OutputT>
-              combineFn);
+  <InputT, AccumT, OutputT> CombiningState<InputT, AccumT, OutputT> 
bindCombiningWithContext(
+      String id,
+      StateSpec<? super K, CombiningState<InputT, AccumT, OutputT>> spec,
+      Coder<AccumT> accumCoder,
+      CombineWithContext.CombineFnWithContext<InputT, AccumT, OutputT> 
combineFn);
 
   /**
    * Bind to a watermark {@link StateSpec}.

http://git-wip-us.apache.org/repos/asf/beam/blob/7e04924e/sdks/java/core/src/main/java/org/apache/beam/sdk/util/state/StateSpecs.java
----------------------------------------------------------------------
diff --git 
a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/state/StateSpecs.java 
b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/state/StateSpecs.java
index 8fa5bb0..a057a0b 100644
--- 
a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/state/StateSpecs.java
+++ 
b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/state/StateSpecs.java
@@ -27,8 +27,7 @@ import org.apache.beam.sdk.coders.CannotProvideCoderException;
 import org.apache.beam.sdk.coders.Coder;
 import org.apache.beam.sdk.coders.CoderRegistry;
 import org.apache.beam.sdk.transforms.Combine.CombineFn;
-import org.apache.beam.sdk.transforms.Combine.KeyedCombineFn;
-import 
org.apache.beam.sdk.transforms.CombineWithContext.KeyedCombineFnWithContext;
+import org.apache.beam.sdk.transforms.CombineWithContext.CombineFnWithContext;
 import org.apache.beam.sdk.transforms.windowing.BoundedWindow;
 import org.apache.beam.sdk.transforms.windowing.TimestampCombiner;
 
@@ -77,52 +76,16 @@ public class StateSpecs {
   }
 
   /**
-   * Create a state spec for values that use a {@link KeyedCombineFn} to 
automatically merge
+   * Create a state spec for values that use a {@link CombineFnWithContext} to 
automatically merge
    * multiple {@code InputT}s into a single {@code OutputT}.
    */
-  public static <K, InputT, AccumT, OutputT>
-  StateSpec<K, CombiningState<InputT, AccumT, OutputT>> keyedCombining(
-      KeyedCombineFn<K, InputT, AccumT, OutputT> combineFn) {
-    return new KeyedCombiningStateSpec<K, InputT, AccumT, OutputT>(null, 
combineFn);
-  }
-
-  /**
-   * Create a state spec for values that use a {@link KeyedCombineFn} to 
automatically merge
-   * multiple {@code InputT}s into a single {@code OutputT}.
-   */
-  public static <K, InputT, AccumT, OutputT>
-      StateSpec<K, CombiningState<InputT, AccumT, OutputT>> keyedCombining(
-          Coder<AccumT> accumCoder, KeyedCombineFn<K, InputT, AccumT, OutputT> 
combineFn) {
+  public static <InputT, AccumT, OutputT>
+      StateSpec<Object, CombiningState<InputT, AccumT, OutputT>> combining(
+          Coder<AccumT> accumCoder, CombineFnWithContext<InputT, AccumT, 
OutputT> combineFn) {
     checkArgument(accumCoder != null,
         "accumCoder should not be null. "
-            + "Consider using keyedCombining(KeyedCombineFn<> combineFn) 
instead.");
-    return keyedCombiningInternal(accumCoder, combineFn);
-  }
-
-  /**
-   * Create a state spec for values that use a {@link 
KeyedCombineFnWithContext} to automatically
-   * merge multiple {@code InputT}s into a single {@code OutputT}.
-   */
-  public static <K, InputT, AccumT, OutputT>
-  StateSpec<K, CombiningState<InputT, AccumT, OutputT>>
-  keyedCombiningWithContext(KeyedCombineFnWithContext<K, InputT, AccumT, 
OutputT> combineFn) {
-    return new KeyedCombiningWithContextStateSpec<K, InputT, AccumT, 
OutputT>(null, combineFn);
-  }
-
-  /**
-   * Create a state spec for values that use a {@link 
KeyedCombineFnWithContext} to automatically
-   * merge multiple {@code InputT}s into a single {@code OutputT}.
-   */
-  public static <K, InputT, AccumT, OutputT>
-      StateSpec<K, CombiningState<InputT, AccumT, OutputT>>
-  keyedCombiningWithContext(
-              Coder<AccumT> accumCoder,
-              KeyedCombineFnWithContext<K, InputT, AccumT, OutputT> combineFn) 
{
-    checkArgument(accumCoder != null,
-        "accumCoder should not be null. Consider using "
-            + "keyedCombiningWithContext(KeyedCombineFnWithContext<> 
combineFn) instead.");
-    return new KeyedCombiningWithContextStateSpec<K, InputT, AccumT, OutputT>(
-        accumCoder, combineFn);
+            + "Consider using combining(CombineFn<> combineFn) instead.");
+    return combiningInternal(accumCoder, combineFn);
   }
 
   /**
@@ -155,10 +118,10 @@ public class StateSpecs {
     return new CombiningStateSpec<InputT, AccumT, OutputT>(accumCoder, 
combineFn);
   }
 
-  private static <K, InputT, AccumT, OutputT>
-      StateSpec<K, CombiningState<InputT, AccumT, OutputT>> 
keyedCombiningInternal(
-          Coder<AccumT> accumCoder, KeyedCombineFn<K, InputT, AccumT, OutputT> 
combineFn) {
-    return new KeyedCombiningStateSpec<K, InputT, AccumT, OutputT>(accumCoder, 
combineFn);
+  private static <InputT, AccumT, OutputT>
+  StateSpec<Object, CombiningState<InputT, AccumT, OutputT>> combiningInternal(
+      Coder<AccumT> accumCoder, CombineFnWithContext<InputT, AccumT, OutputT> 
combineFn) {
+    return new CombiningWithContextStateSpec<InputT, AccumT, 
OutputT>(accumCoder, combineFn);
   }
 
   /**
@@ -216,17 +179,17 @@ public class StateSpecs {
   public static <K, InputT, AccumT, OutputT>
       StateSpec<Object, BagState<AccumT>> convertToBagSpecInternal(
           StateSpec<? super K, CombiningState<InputT, AccumT, OutputT>> 
combiningSpec) {
-    if (combiningSpec instanceof KeyedCombiningStateSpec) {
+    if (combiningSpec instanceof CombiningStateSpec) {
       // Checked above; conversion to a bag spec depends on the provided spec 
being one of those
       // created via the factory methods in this class.
       @SuppressWarnings("unchecked")
-      KeyedCombiningStateSpec<K, InputT, AccumT, OutputT> typedSpec =
-          (KeyedCombiningStateSpec<K, InputT, AccumT, OutputT>) combiningSpec;
+      CombiningStateSpec<InputT, AccumT, OutputT> typedSpec =
+          (CombiningStateSpec<InputT, AccumT, OutputT>) combiningSpec;
       return typedSpec.asBagSpec();
-    } else if (combiningSpec instanceof KeyedCombiningWithContextStateSpec) {
+    } else if (combiningSpec instanceof CombiningWithContextStateSpec) {
       @SuppressWarnings("unchecked")
-      KeyedCombiningWithContextStateSpec<K, InputT, AccumT, OutputT> typedSpec 
=
-          (KeyedCombiningWithContextStateSpec<K, InputT, AccumT, OutputT>) 
combiningSpec;
+      CombiningWithContextStateSpec<InputT, AccumT, OutputT> typedSpec =
+          (CombiningWithContextStateSpec<InputT, AccumT, OutputT>) 
combiningSpec;
       return typedSpec.asBagSpec();
     } else {
       throw new IllegalArgumentException("Unexpected StateSpec " + 
combiningSpec);
@@ -297,7 +260,6 @@ public class StateSpecs {
    * <p>Includes the {@link CombineFn} and the coder for the accumulator type.
    */
   private static class CombiningStateSpec<InputT, AccumT, OutputT>
-      extends KeyedCombiningStateSpec<Object, InputT, AccumT, OutputT>
       implements StateSpec<Object, CombiningState<InputT, AccumT, OutputT>> {
 
     @Nullable
@@ -307,14 +269,14 @@ public class StateSpecs {
     private CombiningStateSpec(
         @Nullable Coder<AccumT> accumCoder,
         CombineFn<InputT, AccumT, OutputT> combineFn) {
-      super(accumCoder, combineFn.asKeyedFn());
       this.combineFn = combineFn;
       this.accumCoder = accumCoder;
     }
 
     @Override
-    protected Coder<AccumT> getAccumCoder() {
-      return accumCoder;
+    public CombiningState<InputT, AccumT, OutputT> bind(
+        String id, StateBinder<? extends Object> visitor) {
+      return visitor.bindCombining(id, this, accumCoder, combineFn);
     }
 
     @SuppressWarnings("unchecked")
@@ -326,51 +288,14 @@ public class StateSpecs {
         }
       }
     }
-  }
-
-  /**
-   * A specification for a state cell that is combined according to a
-   * {@link KeyedCombineFnWithContext}.
-   *
-   * <p>Includes the {@link KeyedCombineFnWithContext} and the coder for the 
accumulator type.
-   */
-  private static class KeyedCombiningWithContextStateSpec<K, InputT, AccumT, 
OutputT>
-      implements StateSpec<K, CombiningState<InputT, AccumT, OutputT>> {
-
-    @Nullable
-    private Coder<AccumT> accumCoder;
-    private final KeyedCombineFnWithContext<K, InputT, AccumT, OutputT> 
combineFn;
-
-    protected KeyedCombiningWithContextStateSpec(
-        @Nullable Coder<AccumT> accumCoder,
-        KeyedCombineFnWithContext<K, InputT, AccumT, OutputT> combineFn) {
-      this.combineFn = combineFn;
-      this.accumCoder = accumCoder;
-    }
-
-    @Override
-    public CombiningState<InputT, AccumT, OutputT> bind(
-        String id, StateBinder<? extends K> visitor) {
-      return visitor.bindKeyedCombiningWithContext(id, this, accumCoder, 
combineFn);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void offerCoders(Coder[] coders) {
-      if (this.accumCoder == null) {
-        if (coders[2] != null) {
-          this.accumCoder = (Coder<AccumT>) coders[2];
-        }
-      }
-    }
 
     @Override public void finishSpecifying() {
       if (accumCoder == null) {
         throw new IllegalStateException("Unable to infer a coder for"
-            + " KeyedCombiningWithContextState and no Coder was specified."
+            + " CombiningState and no Coder was specified."
             + " Please set a coder by either invoking"
-            + " StateSpecs.keyedCombining(Coder<AccumT> accumCoder,"
-            + " KeyedCombineFn<K, InputT, AccumT, OutputT> combineFn)"
+            + " StateSpecs.combining(Coder<AccumT> accumCoder,"
+            + " CombineFn<InputT, AccumT, OutputT> combineFn)"
             + " or by registering the coder in the Pipeline's CoderRegistry.");
       }
     }
@@ -381,12 +306,12 @@ public class StateSpecs {
         return true;
       }
 
-      if (!(obj instanceof KeyedCombiningWithContextStateSpec)) {
+      if (!(obj instanceof CombiningStateSpec)) {
         return false;
       }
 
-      KeyedCombiningWithContextStateSpec<?, ?, ?, ?> that =
-          (KeyedCombiningWithContextStateSpec<?, ?, ?, ?>) obj;
+      CombiningStateSpec<?, ?, ?> that =
+          (CombiningStateSpec<?, ?, ?>) obj;
       return Objects.equals(this.accumCoder, that.accumCoder);
     }
 
@@ -401,32 +326,28 @@ public class StateSpecs {
   }
 
   /**
-   * A specification for a state cell that is combined according to a {@link 
KeyedCombineFn}.
+   * A specification for a state cell that is combined according to a {@link
+   * CombineFnWithContext}.
    *
-   * <p>Includes the {@link KeyedCombineFn} and the coder for the accumulator 
type.
+   * <p>Includes the {@link CombineFnWithContext} and the coder for the 
accumulator type.
    */
-  private static class KeyedCombiningStateSpec<K, InputT, AccumT, OutputT>
-      implements StateSpec<K, CombiningState<InputT, AccumT, OutputT>> {
+  private static class CombiningWithContextStateSpec<InputT, AccumT, OutputT>
+      implements StateSpec<Object, CombiningState<InputT, AccumT, OutputT>> {
 
-    @Nullable
-    private Coder<AccumT> accumCoder;
-    private final KeyedCombineFn<K, InputT, AccumT, OutputT> keyedCombineFn;
+    @Nullable private Coder<AccumT> accumCoder;
+    private final CombineFnWithContext<InputT, AccumT, OutputT> combineFn;
 
-    protected KeyedCombiningStateSpec(
+    private CombiningWithContextStateSpec(
         @Nullable Coder<AccumT> accumCoder,
-        KeyedCombineFn<K, InputT, AccumT, OutputT> keyedCombineFn) {
-      this.keyedCombineFn = keyedCombineFn;
+        CombineFnWithContext<InputT, AccumT, OutputT> combineFn) {
+      this.combineFn = combineFn;
       this.accumCoder = accumCoder;
     }
 
-    protected Coder<AccumT> getAccumCoder() {
-      return accumCoder;
-    }
-
     @Override
     public CombiningState<InputT, AccumT, OutputT> bind(
-        String id, StateBinder<? extends K> visitor) {
-      return visitor.bindKeyedCombining(id, this, getAccumCoder(), 
keyedCombineFn);
+        String id, StateBinder<? extends Object> visitor) {
+      return visitor.bindCombiningWithContext(id, this, accumCoder, combineFn);
     }
 
     @SuppressWarnings("unchecked")
@@ -439,13 +360,16 @@ public class StateSpecs {
       }
     }
 
-    @Override public void finishSpecifying() {
-      if (getAccumCoder() == null) {
-        throw new IllegalStateException("Unable to infer a coder for 
GroupingState and no"
-            + " Coder was specified. Please set a coder by either invoking"
-            + " StateSpecs.combining(Coder<AccumT> accumCoder,"
-            + " CombineFn<InputT, AccumT, OutputT> combineFn)"
-            + " or by registering the coder in the Pipeline's CoderRegistry.");
+    @Override
+    public void finishSpecifying() {
+      if (accumCoder == null) {
+        throw new IllegalStateException(
+            "Unable to infer a coder for"
+                + " CombiningWithContextState and no Coder was specified."
+                + " Please set a coder by either invoking"
+                + " StateSpecs.combiningWithcontext(Coder<AccumT> accumCoder,"
+                + " CombineFnWithContext<InputT, AccumT, OutputT> combineFn)"
+                + " or by registering the coder in the Pipeline's 
CoderRegistry.");
       }
     }
 
@@ -455,12 +379,11 @@ public class StateSpecs {
         return true;
       }
 
-      if (!(obj instanceof CombiningStateSpec)) {
+      if (!(obj instanceof CombiningWithContextStateSpec)) {
         return false;
       }
 
-      KeyedCombiningStateSpec<?, ?, ?, ?> that =
-          (KeyedCombiningStateSpec<?, ?, ?, ?>) obj;
+      CombiningWithContextStateSpec<?, ?, ?> that = 
(CombiningWithContextStateSpec<?, ?, ?>) obj;
       return Objects.equals(this.accumCoder, that.accumCoder);
     }
 

http://git-wip-us.apache.org/repos/asf/beam/blob/7e04924e/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineFnsTest.java
----------------------------------------------------------------------
diff --git 
a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineFnsTest.java
 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineFnsTest.java
index 13c5f16..dcb8fdc 100644
--- 
a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineFnsTest.java
+++ 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineFnsTest.java
@@ -40,7 +40,7 @@ import org.apache.beam.sdk.testing.TestPipeline;
 import org.apache.beam.sdk.testing.ValidatesRunner;
 import org.apache.beam.sdk.transforms.Combine.BinaryCombineFn;
 import org.apache.beam.sdk.transforms.CombineFns.CoCombineResult;
-import 
org.apache.beam.sdk.transforms.CombineWithContext.KeyedCombineFnWithContext;
+import org.apache.beam.sdk.transforms.CombineWithContext.CombineFnWithContext;
 import org.apache.beam.sdk.transforms.display.DisplayData;
 import org.apache.beam.sdk.values.KV;
 import org.apache.beam.sdk.values.PCollection;
@@ -79,7 +79,7 @@ public class  CombineFnsTest {
     expectedException.expectMessage("it is already present in the 
composition");
 
     TupleTag<Integer> tag = new TupleTag<Integer>();
-    CombineFns.composeKeyed()
+    CombineFns.compose()
       .with(new GetIntegerFunction(), Max.ofIntegers(), tag)
       .with(new GetIntegerFunction(), Min.ofIntegers(), tag);
   }
@@ -93,23 +93,6 @@ public class  CombineFnsTest {
     CombineFns.compose()
       .with(
           new GetUserStringFunction(),
-          new ConcatStringWithContext(null /* view */).forKey("G", 
StringUtf8Coder.of()),
-          tag)
-      .with(
-          new GetUserStringFunction(),
-          new ConcatStringWithContext(null /* view */).forKey("G", 
StringUtf8Coder.of()),
-          tag);
-  }
-
-  @Test
-  public void testDuplicatedTagsWithContextKeyed() {
-    expectedException.expect(IllegalArgumentException.class);
-    expectedException.expectMessage("it is already present in the 
composition");
-
-    TupleTag<UserString> tag = new TupleTag<UserString>();
-    CombineFns.composeKeyed()
-      .with(
-          new GetUserStringFunction(),
           new ConcatStringWithContext(null /* view */),
           tag)
       .with(
@@ -153,17 +136,15 @@ public class  CombineFnsTest {
         .apply(
             "ExtractGloballyResult", ParDo.of(new ExtractResultDoFn(maxIntTag, 
concatStringTag)));
 
-    PCollection<KV<String, KV<Integer, String>>> combinePerKey = perKeyInput
-        .apply(Combine.perKey(CombineFns.composeKeyed()
-            .with(
-                new GetIntegerFunction(),
-                Max.ofIntegers().<String>asKeyedFn(),
-                maxIntTag)
-            .with(
-                new GetUserStringFunction(),
-                new ConcatString().<String>asKeyedFn(),
-                concatStringTag)))
-        .apply("ExtractPerKeyResult", ParDo.of(new 
ExtractResultDoFn(maxIntTag, concatStringTag)));
+    PCollection<KV<String, KV<Integer, String>>> combinePerKey =
+        perKeyInput
+            .apply(
+                Combine.<String, KV<Integer, UserString>, 
CoCombineResult>perKey(
+                    CombineFns.compose()
+                        .with(new GetIntegerFunction(), Max.ofIntegers(), 
maxIntTag)
+                        .with(new GetUserStringFunction(), new ConcatString(), 
concatStringTag)))
+            .apply(
+                "ExtractPerKeyResult", ParDo.of(new 
ExtractResultDoFn(maxIntTag, concatStringTag)));
     PAssert.that(combineGlobally).containsInAnyOrder(
         KV.of("global", KV.of(13, "111134")));
     PAssert.that(combinePerKey).containsInAnyOrder(
@@ -205,7 +186,7 @@ public class  CombineFnsTest {
                 maxIntTag)
             .with(
                 new GetUserStringFunction(),
-                new ConcatStringWithContext(view).forKey("G", 
StringUtf8Coder.of()),
+                new ConcatStringWithContext(view),
                 concatStringTag))
             .withoutDefaults()
             .withSideInputs(ImmutableList.of(view)))
@@ -213,23 +194,24 @@ public class  CombineFnsTest {
         .apply(
             "ExtractGloballyResult", ParDo.of(new ExtractResultDoFn(maxIntTag, 
concatStringTag)));
 
-    PCollection<KV<String, KV<Integer, String>>> combinePerKey = perKeyInput
-        .apply(Combine.perKey(CombineFns.composeKeyed()
-            .with(
-                new GetIntegerFunction(),
-                Max.ofIntegers().<String>asKeyedFn(),
-                maxIntTag)
-            .with(
-                new GetUserStringFunction(),
-                new ConcatStringWithContext(view),
-                concatStringTag))
-            .withSideInputs(ImmutableList.of(view)))
-        .apply("ExtractPerKeyResult", ParDo.of(new 
ExtractResultDoFn(maxIntTag, concatStringTag)));
+    PCollection<KV<String, KV<Integer, String>>> combinePerKey =
+        perKeyInput
+            .apply(
+                Combine.<String, KV<Integer, UserString>, 
CoCombineResult>perKey(
+                        CombineFns.compose()
+                            .with(new GetIntegerFunction(), Max.ofIntegers(), 
maxIntTag)
+                            .with(
+                                new GetUserStringFunction(),
+                                new ConcatStringWithContext(view),
+                                concatStringTag))
+                    .withSideInputs(ImmutableList.of(view)))
+            .apply(
+                "ExtractPerKeyResult", ParDo.of(new 
ExtractResultDoFn(maxIntTag, concatStringTag)));
     PAssert.that(combineGlobally).containsInAnyOrder(
-        KV.of("global", KV.of(13, "111134GI")));
+        KV.of("global", KV.of(13, "111134I")));
     PAssert.that(combinePerKey).containsInAnyOrder(
-        KV.of("a", KV.of(4, "114Ia")),
-        KV.of("b", KV.of(13, "113Ib")));
+        KV.of("a", KV.of(4, "114I")),
+        KV.of("b", KV.of(13, "113I")));
     p.run();
   }
 
@@ -256,17 +238,16 @@ public class  CombineFnsTest {
     TupleTag<Integer> maxIntTag = new TupleTag<Integer>();
     TupleTag<UserString> concatStringTag = new TupleTag<UserString>();
 
-    PCollection<KV<String, KV<Integer, String>>> combinePerKey = perKeyInput
-        .apply(Combine.perKey(CombineFns.composeKeyed()
-            .with(
-                new GetIntegerFunction(),
-                Max.ofIntegers().<String>asKeyedFn(),
-                maxIntTag)
-            .with(
-                new GetUserStringFunction(),
-                new OutputNullString().<String>asKeyedFn(),
-                concatStringTag)))
-        .apply("ExtractPerKeyResult", ParDo.of(new 
ExtractResultDoFn(maxIntTag, concatStringTag)));
+    PCollection<KV<String, KV<Integer, String>>> combinePerKey =
+        perKeyInput
+            .apply(
+                Combine.<String, KV<Integer, UserString>, 
CoCombineResult>perKey(
+                    CombineFns.compose()
+                        .with(new GetIntegerFunction(), Max.ofIntegers(), 
maxIntTag)
+                        .with(
+                            new GetUserStringFunction(), new 
OutputNullString(), concatStringTag)))
+            .apply(
+                "ExtractPerKeyResult", ParDo.of(new 
ExtractResultDoFn(maxIntTag, concatStringTag)));
     PAssert.that(combinePerKey).containsInAnyOrder(
         KV.of("a", KV.of(4, (String) null)),
         KV.of("b", KV.of(13, (String) null)));
@@ -407,7 +388,7 @@ public class  CombineFnsTest {
   }
 
   private static class ConcatStringWithContext
-      extends KeyedCombineFnWithContext<String, UserString, UserString, 
UserString> {
+      extends CombineFnWithContext<UserString, UserString, UserString> {
     private final PCollectionView<String> view;
 
     private ConcatStringWithContext(PCollectionView<String> view) {
@@ -415,22 +396,22 @@ public class  CombineFnsTest {
     }
 
     @Override
-    public UserString createAccumulator(String key, CombineWithContext.Context 
c) {
-      return UserString.of(key + c.sideInput(view));
+    public UserString createAccumulator(CombineWithContext.Context c) {
+      return UserString.of(c.sideInput(view));
     }
 
     @Override
     public UserString addInput(
-        String key, UserString accumulator, UserString input, 
CombineWithContext.Context c) {
-      assertThat(accumulator.strValue, Matchers.startsWith(key + 
c.sideInput(view)));
+        UserString accumulator, UserString input, CombineWithContext.Context 
c) {
+      assertThat(accumulator.strValue, Matchers.startsWith(c.sideInput(view)));
       accumulator.strValue += input.strValue;
       return accumulator;
     }
 
     @Override
     public UserString mergeAccumulators(
-        String key, Iterable<UserString> accumulators, 
CombineWithContext.Context c) {
-      String keyPrefix = key + c.sideInput(view);
+        Iterable<UserString> accumulators, CombineWithContext.Context c) {
+      String keyPrefix = c.sideInput(view);
       String all = keyPrefix;
       for (UserString accumulator : accumulators) {
         assertThat(accumulator.strValue, Matchers.startsWith(keyPrefix));
@@ -441,9 +422,8 @@ public class  CombineFnsTest {
     }
 
     @Override
-    public UserString extractOutput(
-        String key, UserString accumulator, CombineWithContext.Context c) {
-      assertThat(accumulator.strValue, Matchers.startsWith(key + 
c.sideInput(view)));
+    public UserString extractOutput(UserString accumulator, 
CombineWithContext.Context c) {
+      assertThat(accumulator.strValue, Matchers.startsWith(c.sideInput(view)));
       char[] chars = accumulator.strValue.toCharArray();
       Arrays.sort(chars);
       return UserString.of(new String(chars));

http://git-wip-us.apache.org/repos/asf/beam/blob/7e04924e/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineTest.java
----------------------------------------------------------------------
diff --git 
a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineTest.java 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineTest.java
index a5f3df2..82c2504 100644
--- 
a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineTest.java
+++ 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/CombineTest.java
@@ -18,7 +18,6 @@
 package org.apache.beam.sdk.transforms;
 
 import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 import static org.apache.beam.sdk.TestUtils.checkCombineFn;
 import static 
org.apache.beam.sdk.transforms.display.DisplayDataMatchers.hasDisplayItem;
@@ -58,9 +57,10 @@ import org.apache.beam.sdk.testing.NeedsRunner;
 import org.apache.beam.sdk.testing.PAssert;
 import org.apache.beam.sdk.testing.TestPipeline;
 import org.apache.beam.sdk.testing.ValidatesRunner;
-import org.apache.beam.sdk.transforms.Combine.KeyedCombineFn;
+import org.apache.beam.sdk.transforms.Combine.CombineFn;
+import org.apache.beam.sdk.transforms.CombineTest.TestCombineFn.Accumulator;
+import org.apache.beam.sdk.transforms.CombineWithContext.CombineFnWithContext;
 import org.apache.beam.sdk.transforms.CombineWithContext.Context;
-import 
org.apache.beam.sdk.transforms.CombineWithContext.KeyedCombineFnWithContext;
 import org.apache.beam.sdk.transforms.display.DisplayData;
 import org.apache.beam.sdk.transforms.display.DisplayDataEvaluator;
 import org.apache.beam.sdk.transforms.windowing.AfterPane;
@@ -127,7 +127,7 @@ public class CombineTest implements Serializable {
 
     // Java 8 will infer.
     PCollection<KV<String, String>> sumPerKey = input
-        .apply(Combine.perKey(new TestKeyedCombineFn()));
+        .apply(Combine.<String, Integer, String>perKey(new TestCombineFn()));
 
     PAssert.that(sum).containsInAnyOrder(globalSum);
     PAssert.that(sumPerKey).containsInAnyOrder(perKeyCombines);
@@ -147,13 +147,13 @@ public class CombineTest implements Serializable {
     PCollectionView<Integer> globallySumView = 
sum.apply(View.<Integer>asSingleton());
 
     // Java 8 will infer.
-    PCollection<KV<String, String>> combinePerKey = perKeyInput
-        .apply(Combine.perKey(new 
TestKeyedCombineFnWithContext(globallySumView))
-            .withSideInputs(Arrays.asList(globallySumView)));
+    PCollection<KV<String, String>> combinePerKey =
+        perKeyInput.apply(
+            Combine.<String, Integer, String>perKey(new 
TestCombineFnWithContext(globallySumView))
+                .withSideInputs(Arrays.asList(globallySumView)));
 
     PCollection<String> combineGlobally = globallyInput
-        .apply(Combine.globally(new 
TestKeyedCombineFnWithContext(globallySumView)
-            .forKey("G", StringUtf8Coder.of()))
+        .apply(Combine.globally(new TestCombineFnWithContext(globallySumView))
             .withoutDefaults()
             .withSideInputs(Arrays.asList(globallySumView)));
 
@@ -168,7 +168,7 @@ public class CombineTest implements Serializable {
   @Category(ValidatesRunner.class)
   @SuppressWarnings({"rawtypes", "unchecked"})
   public void testSimpleCombine() {
-    runTestSimpleCombine(TABLE, 20, Arrays.asList(KV.of("a", "114a"), 
KV.of("b", "113b")));
+    runTestSimpleCombine(TABLE, 20, Arrays.asList(KV.of("a", "114"), 
KV.of("b", "113")));
   }
 
   @Test
@@ -176,8 +176,8 @@ public class CombineTest implements Serializable {
   @SuppressWarnings({"rawtypes", "unchecked"})
   public void testSimpleCombineWithContext() {
     runTestSimpleCombineWithContext(TABLE, 20,
-        Arrays.asList(KV.of("a", "01124a"), KV.of("b", "01123b")),
-        new String[] {"01111234G"});
+        Arrays.asList(KV.of("a", "01124"), KV.of("b", "01123")),
+        new String[] {"01111234"});
   }
 
   @Test
@@ -260,14 +260,14 @@ public class CombineTest implements Serializable {
         .apply(Combine.globally(new SumInts()).withoutDefaults());
 
     PCollection<KV<String, String>> sumPerKey = input
-        .apply(Combine.perKey(new TestKeyedCombineFn()));
+        .apply(Combine.<String, Integer, String>perKey(new TestCombineFn()));
 
     PAssert.that(sum).containsInAnyOrder(2, 5, 13);
     PAssert.that(sumPerKey).containsInAnyOrder(
-        KV.of("a", "11a"),
-        KV.of("a", "4a"),
-        KV.of("b", "1b"),
-        KV.of("b", "13b"));
+        KV.of("a", "11"),
+        KV.of("a", "4"),
+        KV.of("b", "1"),
+        KV.of("b", "13"));
     pipeline.run();
   }
 
@@ -286,23 +286,23 @@ public class CombineTest implements Serializable {
 
     PCollectionView<Integer> globallySumView = 
sum.apply(View.<Integer>asSingleton());
 
-    PCollection<KV<String, String>> combinePerKeyWithContext = perKeyInput
-        .apply(Combine.perKey(new 
TestKeyedCombineFnWithContext(globallySumView))
-            .withSideInputs(Arrays.asList(globallySumView)));
+    PCollection<KV<String, String>> combinePerKeyWithContext =
+        perKeyInput.apply(
+            Combine.<String, Integer, String>perKey(new 
TestCombineFnWithContext(globallySumView))
+                .withSideInputs(Arrays.asList(globallySumView)));
 
     PCollection<String> combineGloballyWithContext = globallyInput
-        .apply(Combine.globally(new 
TestKeyedCombineFnWithContext(globallySumView)
-            .forKey("G", StringUtf8Coder.of()))
+        .apply(Combine.globally(new TestCombineFnWithContext(globallySumView))
             .withoutDefaults()
             .withSideInputs(Arrays.asList(globallySumView)));
 
     PAssert.that(sum).containsInAnyOrder(2, 5, 13);
     PAssert.that(combinePerKeyWithContext).containsInAnyOrder(
-        KV.of("a", "112a"),
-        KV.of("a", "45a"),
-        KV.of("b", "15b"),
-        KV.of("b", "1133b"));
-    PAssert.that(combineGloballyWithContext).containsInAnyOrder("112G", 
"145G", "1133G");
+        KV.of("a", "112"),
+        KV.of("a", "45"),
+        KV.of("b", "15"),
+        KV.of("b", "1133"));
+    PAssert.that(combineGloballyWithContext).containsInAnyOrder("112", "145", 
"1133");
     pipeline.run();
   }
 
@@ -321,28 +321,28 @@ public class CombineTest implements Serializable {
 
     PCollectionView<Integer> globallySumView = 
sum.apply(View.<Integer>asSingleton());
 
-    PCollection<KV<String, String>> combinePerKeyWithContext = perKeyInput
-        .apply(Combine.perKey(new 
TestKeyedCombineFnWithContext(globallySumView))
-            .withSideInputs(Arrays.asList(globallySumView)));
+    PCollection<KV<String, String>> combinePerKeyWithContext =
+        perKeyInput.apply(
+            Combine.<String, Integer, String>perKey(new 
TestCombineFnWithContext(globallySumView))
+                .withSideInputs(Arrays.asList(globallySumView)));
 
     PCollection<String> combineGloballyWithContext = globallyInput
-        .apply(Combine.globally(new 
TestKeyedCombineFnWithContext(globallySumView)
-            .forKey("G", StringUtf8Coder.of()))
+        .apply(Combine.globally(new TestCombineFnWithContext(globallySumView))
             .withoutDefaults()
             .withSideInputs(Arrays.asList(globallySumView)));
 
     PAssert.that(sum).containsInAnyOrder(1, 2, 1, 4, 5, 14, 13);
     PAssert.that(combinePerKeyWithContext).containsInAnyOrder(
-        KV.of("a", "11a"),
-        KV.of("a", "112a"),
-        KV.of("a", "11a"),
-        KV.of("a", "44a"),
-        KV.of("a", "45a"),
-        KV.of("b", "15b"),
-        KV.of("b", "11134b"),
-        KV.of("b", "1133b"));
+        KV.of("a", "11"),
+        KV.of("a", "112"),
+        KV.of("a", "11"),
+        KV.of("a", "44"),
+        KV.of("a", "45"),
+        KV.of("b", "15"),
+        KV.of("b", "11134"),
+        KV.of("b", "1133"));
     PAssert.that(combineGloballyWithContext).containsInAnyOrder(
-      "11G", "112G", "11G", "44G", "145G", "11134G", "1133G");
+      "11", "112", "11", "44", "145", "11134", "1133");
     pipeline.run();
   }
 
@@ -392,13 +392,13 @@ public class CombineTest implements Serializable {
         .apply(Combine.globally(new SumInts()).withoutDefaults());
 
     PCollection<KV<String, String>> sumPerKey = input
-        .apply(Combine.perKey(new TestKeyedCombineFn()));
+        .apply(Combine.<String, Integer, String>perKey(new TestCombineFn()));
 
     PAssert.that(sum).containsInAnyOrder(7, 13);
     PAssert.that(sumPerKey).containsInAnyOrder(
-        KV.of("a", "114a"),
-        KV.of("b", "1b"),
-        KV.of("b", "13b"));
+        KV.of("a", "114"),
+        KV.of("b", "1"),
+        KV.of("b", "13"));
     pipeline.run();
   }
 
@@ -419,26 +419,29 @@ public class CombineTest implements Serializable {
     PCollectionView<Integer> globallyFixedWindowsView =
         fixedWindowsSum.apply(View.<Integer>asSingleton().withDefaultValue(0));
 
-    PCollection<KV<String, String>> sessionsCombinePerKey = perKeyInput
-        .apply("PerKey Input Sessions",
-            Window.<KV<String, 
Integer>>into(Sessions.withGapDuration(Duration.millis(5))))
-        .apply(Combine.perKey(new 
TestKeyedCombineFnWithContext(globallyFixedWindowsView))
-            .withSideInputs(Arrays.asList(globallyFixedWindowsView)));
+    PCollection<KV<String, String>> sessionsCombinePerKey =
+        perKeyInput
+            .apply(
+                "PerKey Input Sessions",
+                Window.<KV<String, 
Integer>>into(Sessions.withGapDuration(Duration.millis(5))))
+            .apply(
+                Combine.<String, Integer, String>perKey(
+                        new TestCombineFnWithContext(globallyFixedWindowsView))
+                    .withSideInputs(Arrays.asList(globallyFixedWindowsView)));
 
     PCollection<String> sessionsCombineGlobally = globallyInput
         .apply("Globally Input Sessions",
             Window.<Integer>into(Sessions.withGapDuration(Duration.millis(5))))
-        .apply(Combine.globally(new 
TestKeyedCombineFnWithContext(globallyFixedWindowsView)
-            .forKey("G", StringUtf8Coder.of()))
+        .apply(Combine.globally(new 
TestCombineFnWithContext(globallyFixedWindowsView))
             .withoutDefaults()
             .withSideInputs(Arrays.asList(globallyFixedWindowsView)));
 
     PAssert.that(fixedWindowsSum).containsInAnyOrder(2, 4, 1, 13);
     PAssert.that(sessionsCombinePerKey).containsInAnyOrder(
-        KV.of("a", "1114a"),
-        KV.of("b", "11b"),
-        KV.of("b", "013b"));
-    PAssert.that(sessionsCombineGlobally).containsInAnyOrder("11114G", "013G");
+        KV.of("a", "1114"),
+        KV.of("b", "11"),
+        KV.of("b", "013"));
+    PAssert.that(sessionsCombineGlobally).containsInAnyOrder("11114", "013");
     pipeline.run();
   }
 
@@ -502,16 +505,15 @@ public class CombineTest implements Serializable {
   public void testHotKeyCombining() {
     PCollection<KV<String, Integer>> input = copy(createInput(pipeline, 
TABLE), 10);
 
-    KeyedCombineFn<String, Integer, ?, Double> mean =
-        new MeanInts().<String>asKeyedFn();
+    CombineFn<Integer, ?, Double> mean = new MeanInts();
     PCollection<KV<String, Double>> coldMean = input.apply("ColdMean",
-        Combine.perKey(mean).withHotKeyFanout(0));
+        Combine.<String, Integer, Double>perKey(mean).withHotKeyFanout(0));
     PCollection<KV<String, Double>> warmMean = input.apply("WarmMean",
-        Combine.perKey(mean).withHotKeyFanout(hotKeyFanout));
+        Combine.<String, Integer, 
Double>perKey(mean).withHotKeyFanout(hotKeyFanout));
     PCollection<KV<String, Double>> hotMean = input.apply("HotMean",
-        Combine.perKey(mean).withHotKeyFanout(5));
+        Combine.<String, Integer, Double>perKey(mean).withHotKeyFanout(5));
     PCollection<KV<String, Double>> splitMean = input.apply("SplitMean",
-        Combine.perKey(mean).withHotKeyFanout(splitHotKeyFanout));
+        Combine.<String, Integer, 
Double>perKey(mean).withHotKeyFanout(splitHotKeyFanout));
 
     List<KV<String, Double>> expected = Arrays.asList(KV.of("a", 2.0), 
KV.of("b", 7.0));
     PAssert.that(coldMean).containsInAnyOrder(expected);
@@ -678,10 +680,10 @@ public class CombineTest implements Serializable {
     assertEquals(
         "Combine.GloballyAsSingletonView",
         Combine.globally(new SumInts()).asSingletonView().getName());
-    assertEquals("Combine.perKey(TestKeyed)", Combine.perKey(new 
TestKeyedCombineFn()).getName());
+    assertEquals("Combine.perKey(Test)", Combine.perKey(new 
TestCombineFn()).getName());
     assertEquals(
-        "Combine.perKeyWithFanout(TestKeyed)",
-        Combine.perKey(new 
TestKeyedCombineFn()).withHotKeyFanout(10).getName());
+        "Combine.perKeyWithFanout(Test)",
+        Combine.perKey(new TestCombineFn()).withHotKeyFanout(10).getName());
   }
 
   @Test
@@ -908,14 +910,10 @@ public class CombineTest implements Serializable {
   }
 
   /**
-   * A KeyedCombineFn that exercises the full generality of [Keyed]CombineFn.
-   *
-   * <p>The net result of applying this CombineFn is a sorted list of all
-   * characters occurring in the key and the decimal representations of
-   * each value.
+   * A {@link CombineFn} that results in a sorted list of all characters 
occurring in the key and
+   * the decimal representations of each value.
    */
-  public static class TestKeyedCombineFn
-      extends KeyedCombineFn<String, Integer, TestKeyedCombineFn.Accumulator, 
String> {
+  public static class TestCombineFn extends CombineFn<Integer, 
TestCombineFn.Accumulator, String> {
 
     // Not serializable.
     static class Accumulator {
@@ -943,20 +941,18 @@ public class CombineTest implements Serializable {
 
     @Override
     public Coder<Accumulator> getAccumulatorCoder(
-        CoderRegistry registry, Coder<String> keyCoder, Coder<Integer> 
inputCoder) {
+        CoderRegistry registry, Coder<Integer> inputCoder) {
       return Accumulator.getCoder();
     }
 
     @Override
-    public Accumulator createAccumulator(String key) {
-      return new Accumulator(key);
+    public Accumulator createAccumulator() {
+      return new Accumulator("");
     }
 
     @Override
-    public Accumulator addInput(String key, Accumulator accumulator, Integer 
value) {
-      checkNotNull(key);
+    public Accumulator addInput(Accumulator accumulator, Integer value) {
       try {
-        assertThat(accumulator.value, Matchers.startsWith(key));
         return new Accumulator(accumulator.value + String.valueOf(value));
       } finally {
         accumulator.value = "cleared in addInput";
@@ -964,19 +960,17 @@ public class CombineTest implements Serializable {
     }
 
     @Override
-    public Accumulator mergeAccumulators(String key, Iterable<Accumulator> 
accumulators) {
-      String all = key;
+    public Accumulator mergeAccumulators(Iterable<Accumulator> accumulators) {
+      String all = "";
       for (Accumulator accumulator : accumulators) {
-        assertThat(accumulator.value, Matchers.startsWith(key));
-        all += accumulator.value.substring(key.length());
+        all += accumulator.value;
         accumulator.value = "cleared in mergeAccumulators";
       }
       return new Accumulator(all);
     }
 
     @Override
-    public String extractOutput(String key, Accumulator accumulator) {
-      assertThat(accumulator.value, Matchers.startsWith(key));
+    public String extractOutput(Accumulator accumulator) {
       char[] chars = accumulator.value.toCharArray();
       Arrays.sort(chars);
       return new String(chars);
@@ -984,38 +978,33 @@ public class CombineTest implements Serializable {
   }
 
   /**
-   * A {@link KeyedCombineFnWithContext} that exercises the full generality
-   * of [Keyed]CombineFnWithContext.
-   *
-   * <p>The net result of applying this CombineFn is a sorted list of all
-   * characters occurring in the key and the decimal representations of
-   * main and side inputs values.
+   * A {@link CombineFnWithContext} that produces a sorted list of all 
characters occurring in the
+   * key and the decimal representations of main and side inputs values.
    */
-  public class TestKeyedCombineFnWithContext
-      extends KeyedCombineFnWithContext<String, Integer, 
TestKeyedCombineFn.Accumulator, String> {
+  public class TestCombineFnWithContext extends CombineFnWithContext<Integer, 
Accumulator, String> {
     private final PCollectionView<Integer> view;
 
-    public TestKeyedCombineFnWithContext(PCollectionView<Integer> view) {
+    public TestCombineFnWithContext(PCollectionView<Integer> view) {
       this.view = view;
     }
 
     @Override
-    public Coder<TestKeyedCombineFn.Accumulator> getAccumulatorCoder(
-        CoderRegistry registry, Coder<String> keyCoder, Coder<Integer> 
inputCoder) {
-      return TestKeyedCombineFn.Accumulator.getCoder();
+    public Coder<TestCombineFn.Accumulator> getAccumulatorCoder(
+        CoderRegistry registry, Coder<Integer> inputCoder) {
+      return TestCombineFn.Accumulator.getCoder();
     }
 
     @Override
-    public TestKeyedCombineFn.Accumulator createAccumulator(String key, 
Context c) {
-      return new TestKeyedCombineFn.Accumulator(key + 
c.sideInput(view).toString());
+    public TestCombineFn.Accumulator createAccumulator(Context c) {
+      return new TestCombineFn.Accumulator(c.sideInput(view).toString());
     }
 
     @Override
-    public TestKeyedCombineFn.Accumulator addInput(
-        String key, TestKeyedCombineFn.Accumulator accumulator, Integer value, 
Context c) {
+    public TestCombineFn.Accumulator addInput(
+        TestCombineFn.Accumulator accumulator, Integer value, Context c) {
       try {
-        assertThat(accumulator.value, Matchers.startsWith(key + 
c.sideInput(view).toString()));
-        return new TestKeyedCombineFn.Accumulator(accumulator.value + 
String.valueOf(value));
+        assertThat(accumulator.value, 
Matchers.startsWith(c.sideInput(view).toString()));
+        return new TestCombineFn.Accumulator(accumulator.value + 
String.valueOf(value));
       } finally {
         accumulator.value = "cleared in addInput";
       }
@@ -1023,21 +1012,21 @@ public class CombineTest implements Serializable {
     }
 
     @Override
-    public TestKeyedCombineFn.Accumulator mergeAccumulators(
-        String key, Iterable<TestKeyedCombineFn.Accumulator> accumulators, 
Context c) {
-      String keyPrefix = key + c.sideInput(view).toString();
-      String all = keyPrefix;
-      for (TestKeyedCombineFn.Accumulator accumulator : accumulators) {
-        assertThat(accumulator.value, Matchers.startsWith(keyPrefix));
-        all += accumulator.value.substring(keyPrefix.length());
+    public TestCombineFn.Accumulator mergeAccumulators(
+        Iterable<TestCombineFn.Accumulator> accumulators, Context c) {
+      String prefix = c.sideInput(view).toString();
+      String all = prefix;
+      for (TestCombineFn.Accumulator accumulator : accumulators) {
+        assertThat(accumulator.value, Matchers.startsWith(prefix));
+        all += accumulator.value.substring(prefix.length());
         accumulator.value = "cleared in mergeAccumulators";
       }
-      return new TestKeyedCombineFn.Accumulator(all);
+      return new TestCombineFn.Accumulator(all);
     }
 
     @Override
-    public String extractOutput(String key, TestKeyedCombineFn.Accumulator 
accumulator, Context c) {
-      assertThat(accumulator.value, Matchers.startsWith(key + 
c.sideInput(view).toString()));
+    public String extractOutput(TestCombineFn.Accumulator accumulator, Context 
c) {
+      assertThat(accumulator.value, 
Matchers.startsWith(c.sideInput(view).toString()));
       char[] chars = accumulator.value.toCharArray();
       Arrays.sort(chars);
       return new String(chars);

http://git-wip-us.apache.org/repos/asf/beam/blob/7e04924e/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ParDoTest.java
----------------------------------------------------------------------
diff --git 
a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ParDoTest.java 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ParDoTest.java
index 1a976f2..52b2f5e 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ParDoTest.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ParDoTest.java
@@ -2501,7 +2501,7 @@ public class ParDoTest implements Serializable {
         };
 
     thrown.expect(RuntimeException.class);
-    thrown.expectMessage("Unable to infer a coder for GroupingState and no 
Coder was specified.");
+    thrown.expectMessage("Unable to infer a coder for CombiningState and no 
Coder was specified.");
 
     pipeline
         .apply(Create.of(KV.of("hello", 3), KV.of("hello", 6), KV.of("hello", 
7)))

http://git-wip-us.apache.org/repos/asf/beam/blob/7e04924e/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ViewTest.java
----------------------------------------------------------------------
diff --git 
a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ViewTest.java 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ViewTest.java
index 867fe0a..b3fa2c6 100644
--- a/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ViewTest.java
+++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/transforms/ViewTest.java
@@ -1122,7 +1122,7 @@ public class ViewTest implements Serializable {
 
     final PCollectionView<Map<String, Integer>> view =
         pipeline.apply("CreateSideInput", Create.of(KV.of("a", 1), KV.of("a", 
20), KV.of("b", 3)))
-            .apply("SumIntegers", 
Combine.perKey(Sum.ofIntegers().<String>asKeyedFn()))
+            .apply("SumIntegers", Combine.<String, Integer, 
Integer>perKey(Sum.ofIntegers()))
             .apply(View.<String, Integer>asMap());
 
     PCollection<KV<String, Integer>> output =

http://git-wip-us.apache.org/repos/asf/beam/blob/7e04924e/sdks/java/core/src/test/java/org/apache/beam/sdk/util/CombineFnUtilTest.java
----------------------------------------------------------------------
diff --git 
a/sdks/java/core/src/test/java/org/apache/beam/sdk/util/CombineFnUtilTest.java 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/util/CombineFnUtilTest.java
index 36a90e9..798e8dc 100644
--- 
a/sdks/java/core/src/test/java/org/apache/beam/sdk/util/CombineFnUtilTest.java
+++ 
b/sdks/java/core/src/test/java/org/apache/beam/sdk/util/CombineFnUtilTest.java
@@ -29,7 +29,6 @@ import java.io.ObjectOutputStream;
 import java.util.List;
 import org.apache.beam.sdk.transforms.CombineWithContext.CombineFnWithContext;
 import org.apache.beam.sdk.transforms.CombineWithContext.Context;
-import 
org.apache.beam.sdk.transforms.CombineWithContext.KeyedCombineFnWithContext;
 import org.apache.beam.sdk.transforms.Sum;
 import org.apache.beam.sdk.util.state.StateContexts;
 import org.junit.Before;
@@ -48,12 +47,12 @@ public class CombineFnUtilTest {
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
-  KeyedCombineFnWithContext<Integer, Integer, Integer, Integer> mockCombineFn;
+  CombineFnWithContext<Integer, Integer, Integer> mockCombineFn;
 
   @SuppressWarnings("unchecked")
   @Before
   public void setUp() {
-    mockCombineFn = mock(KeyedCombineFnWithContext.class, 
withSettings().serializable());
+    mockCombineFn = mock(CombineFnWithContext.class, 
withSettings().serializable());
   }
 
   @Test
@@ -72,10 +71,6 @@ public class CombineFnUtilTest {
     CombineFnWithContext<Integer, int[], Integer> fnWithContext =
         CombineFnUtil.toFnWithContext(Sum.ofIntegers());
     assertTrue(fnWithContext == CombineFnUtil.toFnWithContext(fnWithContext));
-
-    KeyedCombineFnWithContext<Object, Integer, int[], Integer> 
keyedFnWithContext =
-        CombineFnUtil.toFnWithContext(Sum.ofIntegers().asKeyedFn());
-    assertTrue(keyedFnWithContext == 
CombineFnUtil.toFnWithContext(keyedFnWithContext));
   }
 
   @Test
@@ -89,14 +84,5 @@ public class CombineFnUtilTest {
       accum = fnWithContext.addInput(accum, i, nullContext);
     }
     assertEquals(10, fnWithContext.extractOutput(accum, 
nullContext).intValue());
-
-    KeyedCombineFnWithContext<String, Integer, int[], Integer> 
keyedFnWithContext =
-        CombineFnUtil.toFnWithContext(Sum.ofIntegers().<String>asKeyedFn());
-    String key = "key";
-    accum = keyedFnWithContext.createAccumulator(key, nullContext);
-    for (Integer i : inputs) {
-      accum = keyedFnWithContext.addInput(key, accum, i, nullContext);
-    }
-    assertEquals(10, keyedFnWithContext.extractOutput(key, accum, 
nullContext).intValue());
   }
 }

Reply via email to