public Response ParseResponse(byte[] recvBytes)
        {
            var memoryStream = new MemoryStream(recvBytes);
            var flagBytesBuffer = new byte[2];
            var transactionIdBuffer = new byte[2];
            var questionsBuffer = new byte[2];
            var answerRRsBuffer = new byte[2];
            var authorityRRsBuffer = new byte[2];
            var additionalRRCountBytesBuffer = new byte[2];
            var nsTypeBuffer = new byte[2];
            var nsClassBuffer = new byte[2];

            var bytesReceived = recvBytes.Length;

            // Parse DNS Response
            memoryStream.Read(transactionIdBuffer, 0, 2);
            memoryStream.Read(flagBytesBuffer, 0, 2);
            memoryStream.Read(questionsBuffer, 0, 2);
            memoryStream.Read(answerRRsBuffer, 0, 2);
            memoryStream.Read(authorityRRsBuffer, 0, 2);
            memoryStream.Read(additionalRRCountBytesBuffer, 0, 2);

            // Parse Header
            var transactionId = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(transactionIdBuffer, 0));
            var flags = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(flagBytesBuffer, 0));
            var queryResponse = (QueryResponse)(flags & (ushort)FlagMasks.QueryResponseMask);
            var opCode = (OpCode)(flags & (ushort)FlagMasks.OpCodeMask);
            var nsFlags = (NsFlags)(flags & (ushort)FlagMasks.NsFlagMask);
            var rCode = (RCode)(flags & (ushort)FlagMasks.RCodeMask);

            // Parse Questions Section
            var questions = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(questionsBuffer, 0));
            var answerRRs = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(answerRRsBuffer, 0));
            var authorityRRs = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(authorityRRsBuffer, 0));
            var additionalRRCount = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(additionalRRCountBytesBuffer, 0));
            var additionalRecords = new List<Record>();
            var answers = new Record[answerRRs];
            var authoritiveNameServers = new Record[authorityRRs];

            var name = _recordNameParser.ParseName(ref memoryStream);

            // Read dnsType
            memoryStream.Read(nsTypeBuffer, 0, 2);

            // Read dnsClass
            memoryStream.Read(nsClassBuffer, 0, 2);

            var nsType = (NsType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsTypeBuffer, 0));
            var nsClass = (NsClass)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsClassBuffer, 0));

            var headerParser = new RecordHeaderParser(_recordNameParser);
            
            // Read in Answer Blocks
            for (var i = 0; i < answerRRs; i++)
            {
                var header = headerParser.Parse(ref memoryStream);
                var parser = _parserFactory.Get(header.NsType);
                answers[i] = parser.ParseRecord(header, ref memoryStream);
            }

            // Parse Authority Records
            for (var i = 0; i < authorityRRs; i++)
            {
                var header = headerParser.Parse(ref memoryStream);
                var parser = _parserFactory.Get(header.NsType);
                authoritiveNameServers[i] = parser.ParseRecord(header, ref memoryStream);
            }

            // Parse Additional Records
            for (var i = 0; i < additionalRRCount; i++)
            {
                var header = headerParser.Parse(ref memoryStream);
                var parser = _parserFactory.Get(header.NsType);
                additionalRecords.Add(parser.ParseRecord(header, ref memoryStream));
            }

            return new Response(transactionId, flags, queryResponse, opCode, nsFlags, rCode, questions, answerRRs, authorityRRs, name, nsType, nsClass, additionalRecords, bytesReceived, answers, authoritiveNameServers);
        }
 public Response(
     ushort transactionId, 
     ushort flags, 
     QueryResponse queryResponse, 
     OpCode opCode, 
     NsFlags nsFlags, 
     RCode rCode, 
     ushort questions, 
     ushort answerRRs, 
     ushort authorityRRs, 
     string name, 
     NsType nsType, 
     NsClass nsClass,
     List<Record> additionalRecords,
     int bytesReceived,
     Record[] answers,
     Record[] authoritiveNameServers
     )
 {
     _bytesReceived = bytesReceived;
     _answers = answers;
     _authoritiveNameServers = authoritiveNameServers;
     _transactionId = transactionId;
     _flags = flags;
     _queryResponse = queryResponse;
     _opCode = opCode;
     _nsFlags = nsFlags;
     _rCode = rCode;
     _questions = questions;
     _answerRRs = answerRRs;
     _authorityRRs = authorityRRs;
     _name = name;
     _nsType = nsType;
     _nsClass = nsClass;
     _additionalRecords = additionalRecords;
 }