private Object[] generateMessageLengthArgs(
        final List<Token> groups,
        final List<Token> varData,
        final String indent,
        final boolean withName)
    {
        final StringBuilder sb = new StringBuilder();
        int count = 0;

        for (int i = 0, size = groups.size(); i < size; i++)
        {
            final Token groupToken = groups.get(i);
            if (groupToken.signal() != Signal.BEGIN_GROUP)
            {
                throw new IllegalStateException("tokens must begin with BEGIN_GROUP: token=" + groupToken);
            }

            final int endSignal = findEndSignal(groups, i, Signal.END_GROUP, groupToken.name());
            final String groupName = formatPropertyName(groupToken.name());

            if (count > 0)
            {
                sb.append(",\n").append(indent);
            }

            final List<Token> thisGroup = groups.subList(i, endSignal + 1);

            if (isMessageConstLength(thisGroup))
            {
                sb.append("std::size_t");
                if (withName)
                {
                    sb.append(" ").append(groupName).append("Length = 0");
                }
            }
            else
            {
                sb.append("const std::vector<std::tuple<");
                sb.append(generateMessageLengthArgs(thisGroup, indent + INDENT, false)[0]);
                sb.append(">> &");

                if (withName)
                {
                    sb.append(groupName).append("ItemLengths = {}");
                }
            }

            count += 1;

            i = endSignal;
        }

        for (int i = 0, size = varData.size(); i < size;)
        {
            final Token varDataToken = varData.get(i);
            if (varDataToken.signal() != Signal.BEGIN_VAR_DATA)
            {
                throw new IllegalStateException("tokens must begin with BEGIN_VAR_DATA: token=" + varDataToken);
            }

            if (count > 0)
            {
                sb.append(",\n").append(indent);
            }

            sb.append("std::size_t");
            if (withName)
            {
                sb.append(" ").append(formatPropertyName(varDataToken.name())).append("Length = 0");
            }

            count += 1;

            i += varDataToken.componentTokenCount();
        }

        CharSequence result = sb;
        if (count > 1)
        {
            result = "\n" + indent + result;
        }

        return new Object[]{ result, count };
    }
\n");
        sb.append("     * The states in which a encoder/decoder/codec can live.\n");
        sb.append("     *\n");
        sb.append("     * <p>The state machine diagram below, encoded in the dot language, describes\n");
        sb.append("     * the valid state transitions according to the order in which fields may be\n");
        sb.append("     * accessed safely. Tools such as PlantUML and Graphviz can render it.\n");
        sb.append("     *\n");
        sb.append("     * <pre>{@code\n");
        fieldPrecedenceModel.generateGraph(sb, "     *   ");
        sb.append("     * }</pre>\n");
        sb.append("
sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/cpp/CppGenerator.java