private static BinaryOperator<SymbolDependency> guardedMerge(BinaryOperator<SymbolDependency> original) {
        return (a, b) -> {
            if (a.getVersion().equals(b.getVersion())) {
                return b;
            } else {
                return original.apply(a, b);
            }
        };
    }
Gets a mapping of all dependencies used by the provided symbols.

<p>Given a stream of symbols, the dependencies of the symbol are gathered into
a map of the dependencyType to a map of a package name to package version.
Dependencies are sorted while they are collected, meaning that newer versions
of a conflicting dependency typically take precedence over older versions.
However, this is not always true with a natural sort order
(e.g., 0.9 and 0.10).

<p>{@code versionMergeFunction} is invoked each time a package import version
of a package conflicts with another version of the same package for the
same dependency type. The function accepts the dependency type, the package
name, the previous version that was registered, the new conflicting version,
and is expected to return the version that should be used or can throw in
the case of an incompatible conflict. It is a target-specific concern to
determine if two version are compatible or to find an acceptable compromise
between the two versions.

@param symbolStream Stream of symbols to compute from.
@param versionMergeFunction Function that determines which two conflicting versions wins.
@return Returns a map of dependency types to a map of package to version.
smithy-codegen-core/src/main/java/software/amazon/smithy/codegen/core/SymbolDependency.java