@Override
 public PCollection<T> apply(PCollection<T> in) {
   WithKeys<IdT, T> withKeys = WithKeys.of(fn);
   if (representativeType != null) {
     withKeys = withKeys.withKeyType(representativeType);
   }
   return in.apply(withKeys)
       .apply(
           Combine.<IdT, T, T>perKey(
               new Combine.BinaryCombineFn<T>() {
                 @Override
                 public T apply(T left, T right) {
                   return left;
                 }
               }))
       .apply(Values.<T>create());
 }
  @Test
  @Category(RunnableOnService.class)
  public void withLambdaAndTypeDescriptorShouldSucceed() {

    PCollection<String> values = p.apply(Create.of("1234", "3210", "0", "-12"));
    PCollection<KV<Integer, String>> kvs =
        values.apply(
            WithKeys.of((String s) -> Integer.valueOf(s))
                .withKeyType(TypeDescriptor.of(Integer.class)));

    PAssert.that(kvs)
        .containsInAnyOrder(
            KV.of(1234, "1234"), KV.of(0, "0"), KV.of(-12, "-12"), KV.of(3210, "3210"));

    p.run();
  }
  @Test
  public void withLambdaAndNoTypeDescriptorShouldThrow() {

    PCollection<String> values = p.apply(Create.of("1234", "3210", "0", "-12"));

    values.apply("ApplyKeysWithWithKeys", WithKeys.of((String s) -> Integer.valueOf(s)));

    thrown.expect(IllegalStateException.class);
    thrown.expectMessage("Unable to return a default Coder for ApplyKeysWithWithKeys");
    thrown.expectMessage("No Coder has been manually specified");
    thrown.expectMessage(containsString("Building a Coder using a registered CoderFactory failed"));
    thrown.expectMessage(
        containsString("Building a Coder from the @DefaultCoder annotation failed"));
    thrown.expectMessage(containsString("Building a Coder from the fallback CoderProvider failed"));

    p.run();
  }