private void findTransitions(
        final Token msgToken,
        final List<Token> fields,
        final List<Token> groups,
        final List<Token> varData,
        final Function<IntStream, IntStream> versionsSelector)
    {
        final IntHashSet versions = new IntHashSet();
        versions.add(msgToken.version());
        walkSchemaLevel(new VersionCollector(versions), fields, groups, varData);
        walkSchemaLevel(new PathCollector(topLevelBlockFields, groupPathsByField), fields, groups, varData);

        final IntStream selectedVersions = versionsSelector.apply(versions.stream().mapToInt((i) -> i));
        selectedVersions.sorted().forEach(
            (version) ->
            {
                final State versionWrappedState = allocateState("V" + version + "_BLOCK");

                versionWrappedStates.put(version, versionWrappedState);

                final CodecInteraction wrapInteraction = interactionFactory.wrap(version);

                allocateTransitions(
                    wrapInteraction,
                    Collections.singletonList(notWrappedState),
                    versionWrappedState);

                final TransitionCollector transitionCollector = new TransitionCollector(
                    "V" + version + "_",
                    Collections.singleton(versionWrappedState),
                    versionWrappedState,
                    (token) -> token.version() <= version);

                walkSchemaLevel(transitionCollector, fields, groups, varData);

                // Last writer (highest version) wins when there are multiple versions
                encoderWrappedState = versionWrappedState;
                terminalEncoderStates = transitionCollector.exitStates();
            });
    }
Encodes the state machine as a graphviz dot diagram.
@param sb the string builder to append to.
@param indent the indentation to use.
sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/common/FieldPrecedenceModel.java