public SnmpPdu decodePDU(BerDecoder raw_packet)
                                        throws SnmpMessageException, BerException {
        SnmpPdu pdu = new SnmpPdu();
        int length;

        pdu.setPduType(raw_packet.decodeTag(-1));
        if (debug) dump(pdu.pduTypeToString());
        switch (pdu.getPduType()) {
        case SnmpPdu.SNMP_MSG_GET:
        case SnmpPdu.SNMP_MSG_GETNEXT:
        case SnmpPdu.SNMP_MSG_RESPONSE:
        case SnmpPdu.SNMP_MSG_SET:
        case SnmpPdu.SNMP_MSG_TRAP:
        case SnmpPdu.SNMP_MSG_INFORM:
        case SnmpPdu.SNMP_MSG_TRAP2:
        case SnmpPdu.SNMP_MSG_REPORT:
            length = raw_packet.decodeLength();
            raw_packet.decodeLengthEquals(length);
            pdu.setRequestId(raw_packet.decodeSnmpInteger());
            pdu.setErrorStatus(raw_packet.decodeSnmpInteger());
            pdu.setErrorValue(raw_packet.decodeSnmpInteger());
            break;
        default: 
            throw new SnmpMessageException("Unknown PDU type");
        }
        pdu.setVarbindList(raw_packet.decodeVarbindList());
        return pdu;
    }