OperationChain implements Output<OUT>,
        Operations<Operation> { @JsonIgnore @Override public TypeReference<OUT> getOutputTypeReference() { if (!operations.isEmpty()) { final Operation lastOp = operations.get(operations.size() - 1); if (lastOp instanceof Output) { return ((Output) lastOp).getOutputTypeReference(); } } return (TypeReference<OUT>) new TypeReferenceImpl.Void(); } OperationChain();  OperationChain(final Operation operation);  OperationChain(final Output<OUT> operation);  OperationChain(final Operation... operations);  OperationChain(final List<Operation> operations);  OperationChain(final List<Operation> operations, final boolean flatten); static OperationChain<?> wrap(final Operation operation); static OperationChain<O> wrap(final Output<O> operation); @JsonIgnore @Override TypeReference<OUT> getOutputTypeReference(); @Override @JsonIgnore List<Operation> getOperations(); OperationChain<OUT> shallowClone(); @Override Map<String, String> getOptions(); @Override void setOptions(final Map<String, String> options); @Override String toString(); String toOverviewString(); @Override void close(); @Override boolean equals(final Object obj); @Override int hashCode();  }
@Test public void shouldDetermineOperationChainOutputType() { final Operation operation1 = mock(Operation.class); final GetElements operation2 = mock(GetElements.class); final TypeReference typeRef = mock(TypeReference.class); given(operation2.getOutputTypeReference()).willReturn(typeRef); final OperationChain opChain = new OperationChain.Builder() .first(operation1) .then(operation2) .build(); assertSame(typeRef, opChain.getOutputTypeReference()); }