private void registerTimer(int ack, TaskTimer timer)
 {
     if (!dictionaryTimer.ContainsKey(ack))
     {
         dictionaryTimer.Add(ack, timer);
     }
 }
        private void registerPacket(TCPCopycatPacket packet, TCPCopycatReceiveMessageCallback lambda, int waitTime)
        {
            if (waitTime < 0)
            {
                throw new Exception("waitTime must be positive");
            }

            //Console.WriteLine("registering packet: " + packet.header.sequenceNumber);
            if (dictionaryRegisteredPacket.ContainsKey(packet.header.sequenceNumber + 1))
            {
                dictionaryRegisteredPacket[packet.header.sequenceNumber + 1] = lambda;
            }
            else
            {
                dictionaryRegisteredPacket.Add(packet.header.sequenceNumber + 1, lambda);
            }
            //Console.WriteLine(dictionaryRegisteredPacket.Count.ToString() + " packets registered");


            setPacketResponse(packet.header.sequenceNumber + 1, TCPCopyCatController.responseCode.NONE);

            ElapsedEventHandler timerCallbackLambda = delegate(object state, System.Timers.ElapsedEventArgs e)
            {
                TaskTimer        t                 = (TaskTimer)state;
                TCPCopycatPacket packetToSend      = t.packetToSend;
                TCPCopycatReceiveMessageCallback l = t.lambda;
                int w = t.waitTime;
                t.Dispose();
                if (dictionaryRegisteredPacketResponse[packetToSend.header.sequenceNumber + 1] == TCPCopyCatController.responseCode.OK) //unregister timer is called before the timer is even initialized
                {
                    return;
                }
                Console.WriteLine("packet: " + packetToSend.header.sequenceNumber.ToString() + " lost");
                unregisterPacket(packetToSend.header.sequenceNumber + 1);
                setPacketResponse(packetToSend.header.sequenceNumber + 1, TCPCopyCatController.responseCode.NONE);
                TCPCopyCatController.sendMessageToEndPoint(socket, serverEndpoint, packetToSend);
                registerPacket(packetToSend, l, w);
            };


            TaskTimer timer = new TaskTimer();

            timer.Interval  = waitTime;                                                   // set the interval as 10000 ms
            timer.Elapsed  += new System.Timers.ElapsedEventHandler(timerCallbackLambda); // set the event to execute
            timer.AutoReset = false;                                                      // false: only execute once
            timer.Enabled   = true;                                                       // to decide if execute the event of timer specified

            timer.packetToSend = packet;
            timer.lambda       = lambda;
            timer.waitTime     = waitTime;


            registerTimer(packet.header.sequenceNumber + 1, timer);
        }