public void decodeDisplayable(final boolean quoted, final StringBuilder sb, final CoderContext context) {
        checkSize(1);

        int start = _next;
        int level = _level;

        int classHandle = nextType();
        int currentItemCount = _serializedItemCount;
        boolean isVariableLength = (_next - start) > 1;
        switch (classHandle) {
        case TYPE_NULL: {
            _next = start;
            sb.append(getNull());
            break;
        }

        case TYPE_BYTE: {
            _next = start;
            appendParenthesizedFriendlyClassName(sb, byte.class);
            sb.append(getByte());
            break;
        }

        case TYPE_CHAR: {
            _next = start;
            appendParenthesizedFriendlyClassName(sb, char.class);
            if (quoted)
                Util.appendQuotedChar(sb, getChar());
            else
                sb.append((int) getChar());
            break;
        }

        case TYPE_INT: {
            _next = start;
            sb.append(getInt());
            break;
        }

        case TYPE_LONG: {
            _next = start;
            appendParenthesizedFriendlyClassName(sb, long.class);
            sb.append(getLong());
            break;
        }

        case TYPE_FLOAT: {
            _next = start;
            appendParenthesizedFriendlyClassName(sb, float.class);
            sb.append(getFloat());
            break;
        }

        case TYPE_DOUBLE: {
            _next = start;
            sb.append(getDouble());
            break;
        }

        case TYPE_BOOLEAN: {
            _next = start;
            sb.append(getBoolean());
            break;
        }

        case CLASS_STRING:
        case CLASS_BOOLEAN:
        case CLASS_BYTE:
        case CLASS_SHORT:
        case CLASS_CHAR:
        case CLASS_INT:
        case CLASS_LONG:
        case CLASS_FLOAT:
        case CLASS_DOUBLE: {
            // For these built-in types we don't display the back
            // reference.
            _next = start;
            if (_level != level)
                _end = popEnd();
            Object value = get(null, context);
            appendDisplayable(sb, value, quoted, false);
            break;
        }

        case CLASS_REREF: {
            _next = start;
            Object value = get(null, context);
            appendDisplayable(sb, value, quoted, true);
            break;
        }

        case CLASS_ARRAY: {
            try {
                _depth++;
                _serializedItemCount++;
                registerEncodedObject(sb.length());
                int componentClassHandle = nextType();
                switch (componentClassHandle) {
                case TYPE_BOOLEAN: {
                    sb.append("boolean[]{");
                    int length = _end - _next;
                    for (int index = 0; index < length; index++) {
                        if (index > 0)
                            sb.append(',');
                        sb.append(toBoolean(_next) ? "true" : "false");
                        _next++;
                    }
                    break;
                }

                case TYPE_BYTE: {
                    sb.append("byte[]{");
                    int length = _end - _next;
                    for (int index = 0; index < length; index++) {
                        if (index > 0)
                            sb.append(',');
                        sb.append(Util.getByte(_bytes, _next));
                        _next++;
                    }
                    break;
                }

                case TYPE_SHORT: {
                    sb.append("short[]{");
                    int length = arraySize(_end, _next, 2);
                    for (int index = 0; index < length; index++) {
                        if (index > 0)
                            sb.append(',');
                        sb.append(Util.getShort(_bytes, _next));
                        _next += 2;
                    }
                    break;
                }

                case TYPE_CHAR: {
                    sb.append("char[]{");
                    int length = arraySize(_end, _next, 2);
                    for (int index = 0; index < length; index++) {
                        if (index > 0)
                            sb.append(',');
                        int c = Util.getChar(_bytes, _next);
                        if (quoted)
                            Util.appendQuotedChar(sb, c);
                        else
                            sb.append((int) c);
                        _next += 2;
                    }
                    break;
                }

                case TYPE_INT: {
                    sb.append("int[]{");
                    int length = arraySize(_end, _next, 4);
                    for (int index = 0; index < length; index++) {
                        if (index > 0)
                            sb.append(',');
                        sb.append(Util.getInt(_bytes, _next));
                        _next += 4;
                    }
                    break;
                }

                case TYPE_LONG: {
                    sb.append("long[]{");
                    int length = arraySize(_end, _next, 8);
                    for (int index = 0; index < length; index++) {
                        if (index > 0)
                            sb.append(',');
                        sb.append(Util.getLong(_bytes, _next));
                        _next += 8;
                    }
                    break;
                }

                case TYPE_FLOAT: {
                    sb.append("float[]{");
                    int length = arraySize(_end, _next, 4);
                    for (int index = 0; index < length; index++) {
                        if (index > 0)
                            sb.append(',');
                        float f = Float.intBitsToFloat(Util.getInt(_bytes, _next));
                        sb.append(f);
                        _next += 4;
                    }
                    break;
                }

                case TYPE_DOUBLE: {
                    sb.append("double[]{");
                    int length = arraySize(_end, _next, 8);
                    for (int index = 0; index < length; index++) {
                        if (index > 0)
                            sb.append(',');
                        double d = Double.longBitsToDouble(Util.getLong(_bytes, _next));
                        sb.append(d);
                        _next += 8;
                    }
                    break;
                }

                default: {
                    Class<?> cl = classForHandle(componentClassHandle);
                    if (cl != null)
                        appendFriendlyClassName(sb, cl);
                    sb.append("[]{");
                    int length = decodeElementCount();
                    for (int index = 0; index < length; index++) {
                        if (index > 0)
                            sb.append(',');
                        decodeDisplayable(quoted, sb, context);
                    }
                    break;
                }
                }
                sb.append('}');
            } finally {
                _depth--;
            }
            if (isVariableLength)
                closeVariableLengthItem();
            break;
        }
        case CLASS_MULTI_ARRAY: {
            _next = start;
            decodeDisplayableMultiArray(quoted, sb, context, null);
            break;
        }
        case CLASS_SERIALIZED: {
            _next = start;
            int length = sb.length();
            _depth++;
            try {
                Object object = get(null, context);
                getValueCache().store(currentItemCount, new DisplayMarker(sb.length()));
                appendDisplayable(sb, object, quoted, false);
            } catch (Exception e) {
                sb.setLength(length);
                sb.append("(Serialized-Object)");
                Util.bytesToHex(sb, _bytes, start, _end - start);
            } finally {
                _depth--;
                if (isVariableLength)
                    closeVariableLengthItem();
            }
            break;
        }

        case TYPE_MVV: {
            final int savedSize = _size;
            sb.append('[');

            try {
                MVV.visitAllVersions(new MVV.VersionVisitor() {
                    boolean first = true;

                    @Override
                    public void init() {
                    }

                    @Override
                    public void sawVersion(long version, int offset, int valueLength) {
                        if (!first) {
                            sb.append(',');
                        }
                        sb.append(TransactionStatus.versionString(version));
                        try {
                            long tc = _persistit.getTransactionIndex().commitStatus(version, Long.MAX_VALUE, 0);
                            sb.append("<" + TransactionStatus.tcString(tc) + ">");
                        } catch (Exception e) {
                            sb.append("<" + e + ">");
                        }

                        sb.append(':');
                        if (valueLength == 0) {
                            sb.append(UNDEFINED);
                        } else {
                            _next = offset;
                            _end = _size = _next + valueLength;
                            decodeDisplayable(quoted, sb, context);
                        }
                        first = false;
                    }

                }, getEncodedBytes(), 0, getEncodedSize());
            } catch (Throwable t) {
                sb.append("<<").append(t).append(">>");
            } finally {
                _next = _end = _size = savedSize;
            }

            sb.append(']');
        }
            break;

        default: {
            if (classHandle >= CLASS1) {
                try {
                    Class<?> clazz = _persistit.classForHandle(classHandle);
                    ValueCoder coder = null;
                    _depth++;
                    getValueCache().store(currentItemCount, new DisplayMarker(sb.length()));

                    _serializedItemCount++;

                    if (clazz != null) {
                        coder = getValueCoder(clazz);
                    }
                    if (coder instanceof ValueDisplayer) {
                        appendParenthesizedFriendlyClassName(sb, clazz);
                        ((ValueDisplayer) coder).display(this, sb, clazz, context);
                    } else if (coder instanceof SerialValueCoder) {
                        int length = sb.length();
                        try {
                            _next = start;
                            Object object = get(null, context);
                            getValueCache().store(currentItemCount, new DisplayMarker(sb.length()));
                            appendDisplayable(sb, object, quoted, false);
                        } catch (Exception e) {
                            sb.setLength(length);
                            sb.append("(Serialized-Object)");
                            Util.bytesToHex(sb, _bytes, start, _end - start);
                        }
                    } else {
                        appendParenthesizedFriendlyClassName(sb, clazz);
                        sb.append('{');
                        boolean first = true;
                        while (hasMoreItems()) {
                            if (!first)
                                sb.append(',');
                            first = false;
                            decodeDisplayable(true, sb, null);
                        }
                        sb.append('}');
                    }
                    break;
                } catch (Throwable t) {
                    sb.append("<<" + t + ">>");
                } finally {
                    _depth--;
                    if (isVariableLength)
                        closeVariableLengthItem();
                }