### Question:
HashObjectFunnels { public static Funnel<RevTag> tagFunnel() { return TagFunnel.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 testTagFunnel() { RevTag testTag = new RevTag() { public @Override TYPE getType() { return RevObject.TYPE.TAG; } public @Override ObjectId getId() { return oid1; } public @Override String getName() { return "TagName"; } public @Override String getMessage() { return "Tag Message"; } public @Override RevPerson getTagger() { return new RevPerson() { public @Override Optional<String> getName() { return Optional.of("Test Tagger"); } public @Override Optional<String> getEmail() { return Optional.of("test@tagger.com"); } public @Override long getTimestamp() { return 142L; } public @Override int getTimeZoneOffset() { return 4; } }; } public @Override ObjectId getCommitId() { return oid2; } }; Funnel<RevTag> tagFunnel = HashObjectFunnels.tagFunnel(); Hasher hasher = ObjectId.HASH_FUNCTION.newHasher(); tagFunnel.funnel(testTag, hasher); byte[] rawKey = hasher.hash().asBytes(); assertEquals(ObjectId.NUM_BYTES, rawKey.length); }