/// <summary>
        /// Decode BER encoded <see cref="ScopedPdu"/> values. This method does not perform SNMP v3 privacy operations
        /// and is not aware of privacy requirements.
        ///
        /// To decode a privacy protected SNMP v3 packet, you will need to a) extract <see cref="OctetString"/> value
        /// holding encrypted <see cref="ScopedPdu"/> data, b) decrypt the encrypted ScopedPdu data into an unecrypted
        /// byte array, c) pass unencrypted <see cref="ScopedPdu"/> and BER encoded byte array to this method for
        /// final data conversion from BER into individual sequences and variables.
        /// </summary>
        /// <param name="buffer">Buffer holding BER encoded <see cref="ScopedPdu"/> data</param>
        /// <param name="offset">Offset within the buffer BER encoded <see cref="ScopedPdu"/> data begins.</param>
        /// <returns>Offset position after parsed ScopedPdu</returns>
        /// <exception cref="SnmpDecodingException">Error was encountered when decoding the PDU</exception>
        /// <exception cref="OverflowException">Thrown when buffer is too short to contain the PDU</exception>
        public override int decode(byte[] buffer, int offset)
        {
            int  length;
            byte sequenceType = ParseHeader(buffer, ref offset, out length);

            if (sequenceType != SnmpConstants.SMI_SEQUENCE)
            {
                throw new SnmpDecodingException("Invalid ScopedPdu sequence detected. Invalid ScopedPdu encoding.");
            }
            // verify packet can match parsed length
            if (length > (buffer.Length - offset))
            {
                throw new OverflowException("SNMP packet too short.");
            }

            // Reset scoped pdu specific variables
            _contextEngineId.Reset();
            _contextName.Reset();
            // parse scoped pdu specific variables
            offset = _contextEngineId.decode(buffer, offset);
            offset = _contextName.decode(buffer, offset);
            // decode base pdu
            offset = base.decode(buffer, offset);

            return(offset);
        }
        /// <summary>BER encode security model field.</summary>
        /// <remarks>
        /// USM security model is a SEQUENCE encoded inside a OCTETSTRING. To encode it, first encode the sequence
        /// of class values then "wrap" it inside a OCTETSTRING field
        /// </remarks>
        /// <param name="buffer">Buffer to store encoded USM security model header</param>
        public override void encode(MutableByte buffer)
        {
            MutableByte tmp = new MutableByte();

            // First encode all the values that will form the sequence
            _engineId.encode(tmp);
            // Encode engine boots
            _engineBoots.encode(tmp);
            // encode engine time
            _engineTime.encode(tmp);
            _securityName.encode(tmp);
            if (_authentication != AuthenticationDigests.None)
            {
                if (_authenticationParameters.Length <= 0)
                {
                    // If authentication is used, set authentication parameters field to 12 bytes set to 0x00
                    _authenticationParameters.Set(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
                }
            }
            else
            {
                _authenticationParameters.Reset();
            }
            _authenticationParameters.encode(tmp);
            if (_privacy != PrivacyProtocols.None)
            {
                if (_privacyParameters.Length <= 0)
                {
                    IPrivacyProtocol privProto = PrivacyProtocol.GetInstance(_privacy);
                    if (privProto != null)
                    {
                        byte[] parameter = new byte[privProto.PrivacyParametersLength];
                        for (int i = 0; i < privProto.PrivacyParametersLength; i++)
                        {
                            parameter[i] = 0x00; // This is not necessary since all array members are, by default, initialized to 0
                        }
                        _privacyParameters.Set(parameter);
                    }
                    else
                    {
                        throw new SnmpException(SnmpException.UnsupportedPrivacyProtocol, "Unrecognized privacy protocol specified.");
                    }
                }
            }
            else
            {
                _privacyParameters.Reset();
            }
            _privacyParameters.encode(tmp);
            MutableByte tmp1 = new MutableByte();

            BuildHeader(tmp1, SnmpConstants.SMI_SEQUENCE, tmp.Length);
            tmp1.Append(tmp);

            BuildHeader(buffer, OCTETSTRING, tmp1.Length);

            buffer.Append(tmp1);
        }