class MBeanHelper {

    public String describe(ObjectName bean) throws Exception {
        MBeanInfo mbinfo = mserver.getMBeanInfo(bean);
        StringBuilder sb = new StringBuilder();
        sb.append(bean);
        sb.append('\n');
        sb.append(mbinfo.getClassName());
        sb.append('\n');
        sb.append(" - " + mbinfo.getDescription());
        sb.append('\n');
        for(MBeanAttributeInfo ai: mbinfo.getAttributes()) {
            sb.append(" (A) ");
            sb.append(ai.getName()).append(" : ").append(toPrintableType(ai.getType())).append("");
            if (!ai.isReadable()) {
                sb.append(" - WRITEONLY");
            }
            else if (ai.isWritable()) {
                sb.append(" - WRITEABLE");
            }
            sb.append('\n');
            if (!ai.getName().equals(ai.getDescription())) {
                sb.append("  - " + ai.getDescription());
                sb.append('\n');
            }
        }
        for (MBeanOperationInfo oi: mbinfo.getOperations()) {
            sb.append(" (O) ");
            sb.append(oi.getName()).append("(");
            for(MBeanParameterInfo pi: oi.getSignature()) {
                String name = pi.getName();
                String type = toPrintableType(pi.getType());
                sb.append(type).append(' ').append(name).append(", ");
            }
            if (oi.getSignature().length > 0) {
                sb.setLength(sb.length() - 2);
            }
            sb.append(") : ").append(toPrintableType(oi.getReturnType()));
            sb.append('\n');
            if (!oi.getName().equals(oi.getDescription())) {
                sb.append("  - " + oi.getDescription());
                sb.append('\n');
            }
        }
        return sb.toString();
    }

    public  MBeanHelper(MBeanServerConnection connection);

}