### Question:
HashObjectFunnels { public static Funnel<RevCommit> commitFunnel() { return CommitFunnel.INSTANCE; }  static Funnel<RevCommit> commitFunnel(); static Funnel<RevTree> treeFunnel(); static Funnel<Object> valueFunnel(); static Funnel<RevFeature> featureFunnel(); static Funnel<RevTag> tagFunnel(); static Funnel<RevFeatureType> featureTypeFunnel(); static void feature(@NonNull PrimitiveSink into, @NonNull List<Object> values); static void tree(@NonNull PrimitiveSink into, @NonNull List<Node> trees,
            @NonNull List<Node> features, @NonNull Iterable<Bucket> buckets); static ObjectId hashTag(@NonNull String name, @NonNull ObjectId commitId,
            @NonNull String message, @NonNull RevPerson tagger); static ObjectId hashFeature(@NonNull List<Object> values); static ObjectId hashCommit(@NonNull ObjectId treeId, @NonNull List<ObjectId> parentIds,
            @NonNull RevPerson author, @NonNull RevPerson committer,
            @NonNull String commitMessage); static ObjectId hashFeatureType(@NonNull FeatureType featureType); static ObjectId hashTree(@Nullable List<Node> trees, @Nullable List<Node> features,
            @Nullable Iterable<Bucket> buckets); static ObjectId hashValue(@Nullable Object value); static ObjectId hashObject(@NonNull RevObject o); static void tag(@NonNull PrimitiveSink into, @NonNull String name,
            @NonNull ObjectId commitId, @NonNull String message, @NonNull RevPerson tagger); static void featureType(@NonNull PrimitiveSink into, @NonNull FeatureType featureType); static void commit(@NonNull PrimitiveSink into, @NonNull ObjectId treeId,
            @NonNull List<ObjectId> parentIds, @NonNull RevPerson author,
            @NonNull RevPerson committer, @NonNull String commitMessage);  }### Answer:
@Test public void testCommitFunnel() { ImmutableList<ObjectId> parents = ImmutableList.of(oid3, oid4); RevCommit testCommit = new RevCommit() { public @Override TYPE getType() { return RevObject.TYPE.COMMIT; } public @Override ObjectId getId() { return oid1; } public @Override ObjectId getTreeId() { return oid2; } public @Override List<ObjectId> getParentIds() { return parents; } public @Override Optional<ObjectId> parentN(int parentIndex) { if (parentIndex >= parents.size()) { return Optional.empty(); } return Optional.ofNullable(parents.get(parentIndex)); } public @Override RevPerson getAuthor() { return new RevPerson() { public @Override Optional<String> getName() { return Optional.of("Test Author"); } public @Override Optional<String> getEmail() { return Optional.of("test@author.com"); } public @Override long getTimestamp() { return 142L; } public @Override int getTimeZoneOffset() { return 4; } }; } public @Override RevPerson getCommitter() { return new RevPerson() { public @Override Optional<String> getName() { return Optional.of("Test Committer"); } public @Override Optional<String> getEmail() { return Optional.of("test@committer.com"); } public @Override long getTimestamp() { return 143L; } public @Override int getTimeZoneOffset() { return 5; } }; } public @Override String getMessage() { return "Commit Message"; } }; Funnel<RevCommit> commitFunnel = HashObjectFunnels.commitFunnel(); Hasher hasher = ObjectId.HASH_FUNCTION.newHasher(); commitFunnel.funnel(testCommit, hasher); final byte[] rawKey = hasher.hash().asBytes(); assertEquals(ObjectId.NUM_BYTES, rawKey.length); }