private void generateGroupDecoderClassDeclaration(
        final StringBuilder sb,
        final String groupName,
        final String parentMessageClassName,
        final List<String> subGroupNames,
        final String indent,
        final int dimensionHeaderSize)
    {
        final String className = formatClassName(groupName);

        new Formatter(sb).format("\n" +
            indent + "public static final class %1$s\n" +
            indent + "    implements Iterable<%1$s>, java.util.Iterator<%1$s>\n" +
            indent + "{\n" +
            indent + "    public static final int HEADER_SIZE = %2$d;\n" +
            indent + "    private final %3$s parentMessage;\n" +
            indent + "    private %4$s buffer;\n" +
            indent + "    private int count;\n" +
            indent + "    private int index;\n" +
            indent + "    private int offset;\n" +
            indent + "    private int blockLength;\n",
            className,
            dimensionHeaderSize,
            parentMessageClassName,
            readOnlyBuffer);

        for (final String subGroupName : subGroupNames)
        {
            final String type = formatClassName(decoderName(subGroupName));
            final String field = formatPropertyName(subGroupName);
            sb.append(indent).append("    private final ").append(type).append(" ").append(field).append(";\n");
        }

        sb
            .append("\n")
            .append(indent).append("    ")
            .append(className).append("(final ").append(parentMessageClassName).append(" parentMessage)\n")
            .append(indent).append("    {\n")
            .append(indent).append("        this.parentMessage = parentMessage;\n");

        for (final String subGroupName : subGroupNames)
        {
            final String type = formatClassName(decoderName(subGroupName));
            final String field = formatPropertyName(subGroupName);
            sb
                .append(indent).append("        ")
                .append(field).append(" = new ").append(type).append("(parentMessage);\n");
        }

        sb.append(indent).append("    }\n");
    }
\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/java/JavaGenerator.java