private CharSequence generatePrimitiveArrayPropertyDecode(
        final boolean inComposite,
        final String propertyName,
        final CharSequence accessOrderListenerCall,
        final Token propertyToken,
        final Token encodingToken,
        final String indent)
    {
        final Encoding encoding = encodingToken.encoding();
        final String javaTypeName = javaTypeName(encoding.primitiveType());
        final int offset = encodingToken.offset();
        final String byteOrderStr = byteOrderString(encoding);
        final int fieldLength = encodingToken.arrayLength();
        final int typeSize = sizeOfPrimitive(encoding);

        final StringBuilder sb = new StringBuilder();

        generateArrayLengthMethod(propertyName, indent, fieldLength, sb);

        new Formatter(sb).format("\n" +
            indent + "    public %s %s(final int index)\n" +
            indent + "    {\n" +
            indent + "        if (index < 0 || index >= %d)\n" +
            indent + "        {\n" +
            indent + "            throw new IndexOutOfBoundsException(\"index out of range: index=\" + index);\n" +
            indent + "        }\n\n" +
            "%s" +
            "%s" +
            indent + "        final int pos = offset + %d + (index * %d);\n\n" +
            indent + "        return %s;\n" +
            indent + "    }\n\n",
            javaTypeName,
            propertyName,
            fieldLength,
            generateFieldNotPresentCondition(inComposite, propertyToken.version(), encoding, indent),
            accessOrderListenerCall,
            offset,
            typeSize,
            generateGet(encoding.primitiveType(), "pos", byteOrderStr));

        if (encoding.primitiveType() == PrimitiveType.CHAR)
        {
            generateCharacterEncodingMethod(sb, propertyName, encoding.characterEncoding(), indent);

            new Formatter(sb).format("\n" +
                indent + "    public int get%s(final byte[] dst, final int dstOffset)\n" +
                indent + "    {\n" +
                indent + "        final int length = %d;\n" +
                indent + "        if (dstOffset < 0 || dstOffset > (dst.length - length))\n" +
                indent + "        {\n" +
                indent + "            throw new IndexOutOfBoundsException(" +
                "\"Copy will go out of range: offset=\" + dstOffset);\n" +
                indent + "        }\n\n" +
                "%s" +
                "%s" +
                indent + "        buffer.getBytes(offset + %d, dst, dstOffset, length);\n\n" +
                indent + "        return length;\n" +
                indent + "    }\n",
                Generators.toUpperFirstChar(propertyName),
                fieldLength,
                generateArrayFieldNotPresentCondition(inComposite, propertyToken.version(), indent),
                accessOrderListenerCall,
                offset);

            new Formatter(sb).format("\n" +
                indent + "    public String %s()\n" +
                indent + "    {\n" +
                "%s" +
                "%s" +
                indent + "        final byte[] dst = new byte[%d];\n" +
                indent + "        buffer.getBytes(offset + %d, dst, 0, %d);\n\n" +
                indent + "        int end = 0;\n" +
                indent + "        for (; end < %d && dst[end] != 0; ++end);\n\n" +
                indent + "        return new String(dst, 0, end, %s);\n" +
                indent + "    }\n\n",
                propertyName,
                generateStringNotPresentCondition(inComposite, propertyToken.version(), indent),
                accessOrderListenerCall,
                fieldLength,
                offset,
                fieldLength,
                fieldLength,
                charset(encoding.characterEncoding()));

            if (isAsciiEncoding(encoding.characterEncoding()))
            {
                new Formatter(sb).format("\n" +
                    indent + "    public int get%1$s(final Appendable value)\n" +
                    indent + "    {\n" +
                    "%2$s" +
                    "%5$s" +
                    indent + "        for (int i = 0; i < %3$d; ++i)\n" +
                    indent + "        {\n" +
                    indent + "            final int c = buffer.getByte(offset + %4$d + i) & 0xFF;\n" +
                    indent + "            if (c == 0)\n" +
                    indent + "            {\n" +
                    indent + "                return i;\n" +
                    indent + "            }\n\n" +
                    indent + "            try\n" +
                    indent + "            {\n" +
                    indent + "                value.append(c > 127 ? '?' : (char)c);\n" +
                    indent + "            }\n" +
                    indent + "            catch (final java.io.IOException ex)\n" +
                    indent + "            {\n" +
                    indent + "                throw new java.io.UncheckedIOException(ex);\n" +
                    indent + "            }\n" +
                    indent + "        }\n\n" +
                    indent + "        return %3$d;\n" +
                    indent + "    }\n\n",
                    Generators.toUpperFirstChar(propertyName),
                    generateStringNotPresentConditionForAppendable(inComposite, propertyToken.version(), indent),
                    fieldLength,
                    offset,
                    accessOrderListenerCall);
            }
        }
        else if (encoding.primitiveType() == PrimitiveType.UINT8)
        {
            new Formatter(sb).format("\n" +
                indent + "    public int get%s(final byte[] dst, final int dstOffset, final int length)\n" +
                indent + "    {\n" +
                "%s" +
                "%s" +
                indent + "        final int bytesCopied = Math.min(length, %d);\n" +
                indent + "        buffer.getBytes(offset + %d, dst, dstOffset, bytesCopied);\n\n" +
                indent + "        return bytesCopied;\n" +
                indent + "    }\n",
                Generators.toUpperFirstChar(propertyName),
                generateArrayFieldNotPresentCondition(inComposite, propertyToken.version(), indent),
                accessOrderListenerCall,
                fieldLength,
                offset);

            new Formatter(sb).format("\n" +
                indent + "    public int get%s(final %s dst, final int dstOffset, final int length)\n" +
                indent + "    {\n" +
                "%s" +
                "%s" +
                indent + "        final int bytesCopied = Math.min(length, %d);\n" +
                indent + "        buffer.getBytes(offset + %d, dst, dstOffset, bytesCopied);\n\n" +
                indent + "        return bytesCopied;\n" +
                indent + "    }\n",
                Generators.toUpperFirstChar(propertyName),
                fqMutableBuffer,
                generateArrayFieldNotPresentCondition(inComposite, propertyToken.version(), indent),
                accessOrderListenerCall,
                fieldLength,
                offset);

            new Formatter(sb).format("\n" +
                indent + "    public void wrap%s(final %s wrapBuffer)\n" +
                indent + "    {\n" +
                "%s" +
                "%s" +
                indent + "        wrapBuffer.wrap(buffer, offset + %d, %d);\n" +
                indent + "    }\n",
                Generators.toUpperFirstChar(propertyName),
                readOnlyBuffer,
                generateWrapFieldNotPresentCondition(inComposite, propertyToken.version(), indent),
                accessOrderListenerCall,
                offset,
                fieldLength);
        }

        return sb;
    }
\n" +
                "     * Field presence indication. Can be optional, required, or constant.\n" +
                "
sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/java/JavaGenerator.java