static void Introducer_OnMessageReceived(object sender, MessageReceivedEventArgs e)
        {
            switch (e.MessageType)
            {
                case MessageType.RequestIntroducerRegistration:
                    {
                        var message = new RequestIntroducerRegistrationMessage();
                        message.ReadPayload(e.MessageReader);

                        // A client wants to register
                        // Get his internal endpoint
                        var internalEndPoint = message.InternalClientEndPoint;
                        // Get his external endpoint
                        var externalEndPoint = e.From;

                        Introducer.Registrants.Add(new Registrant()
                                                       {
                                                           InternalEndPoint = internalEndPoint,
                                                           ExternalEndPoint = externalEndPoint
                                                       });

                        Introducer.Send(e.From, new ResponseIntroducerRegistrationMessage()
                                                    {
                                                        RegisteredEndPoint = e.From
                                                    });
                    }
                    break;
                case MessageType.RequestIntroducerIntroduction:
                    {
                        var message = new RequestIntroducerIntroductionMessage();
                        message.ReadPayload(e.MessageReader);

                        // A client, A, wants to be introduced to another peer, B
                        var bExternalEndPoint = message.ExternalPeerEndPoint;

                        // Get this peer's registration
                        var b =
                            Introducer.Registrants.First(
                                registrant => registrant.ExternalEndPoint.Equals(message.ExternalPeerEndPoint));

                        var a = new Registrant()
                                    {InternalEndPoint = message.InternalOwnEndPoint, ExternalEndPoint = e.From};

                        Introducer.Send(a.ExternalEndPoint, new ResponseIntroducerIntroductionMessage()
                                                                {
                                                                    InternalPeerEndPoint = b.InternalEndPoint,
                                                                    ExternalPeerEndPoint = b.ExternalEndPoint,
                                                                });

                        Introducer.Send(b.ExternalEndPoint, new ResponseIntroducerIntroductionMessage()
                                                                {
                                                                    InternalPeerEndPoint = a.InternalEndPoint,
                                                                    ExternalPeerEndPoint = a.ExternalEndPoint,
                                                                });
                    }
                    break;
            }
        }
        static void Peer_OnMessageReceived(object sender, MessageReceivedEventArgs e)
        {
            switch (e.MessageType)
            {
                case MessageType.ResponseIntroducerRegistration:
                    {
                        var message = new ResponseIntroducerRegistrationMessage();
                        message.ReadPayload(e.MessageReader);

                        Console.WriteLine(String.Format("Introducer: You have been registered as \"{0}\".", message.RegisteredEndPoint));

                        Console.Write("Endpoint of your peer: ");

                        var peerEndPoint = Console.ReadLine().Parse();

                        Console.WriteLine(String.Format("Requesting an introduction to {0}:{1}...", peerEndPoint.Address, peerEndPoint.Port));
                        IntroducerSocket.Send(new RequestIntroducerIntroductionMessage() { InternalOwnEndPoint = (IPEndPoint) IntroducerSocket.Socket.LocalEndPoint, ExternalPeerEndPoint = peerEndPoint} );
                    }
                    break;
                case MessageType.ResponseIntroducerIntroduction:
                    {
                        var message = new ResponseIntroducerIntroductionMessage();
                        message.ReadPayload(e.MessageReader);

                        Console.WriteLine(String.Format("Introducer: Your peer's internal endpoint is \"{0}\".", message.InternalPeerEndPoint));
                        Console.WriteLine(String.Format("Introducer: Your peer's external endpoint is \"{0}\".", message.ExternalPeerEndPoint));

                        ConnectSocketInternal = new NetworkPeer();
                        ConnectSocketInternal.Bind(new IPEndPoint(IPAddress.Any, PORT));
                        Console.WriteLine(String.Format("Connecting to your peer's internal endpoint..."));
                        ConnectSocketInternal.OnConnectionSuccessful += (s, e1) => Console.WriteLine("ConnectSocketInternal.OnConnectionSuccessful");
                        ConnectSocketInternal.Connect(message.InternalPeerEndPoint.Address, message.InternalPeerEndPoint.Port);

                        ConnectSocketExternal = new NetworkPeer();
                        ConnectSocketExternal.Bind(new IPEndPoint(IPAddress.Any, PORT));
                        Console.WriteLine(String.Format("Connecting to your peer's external endpoint..."));
                        ConnectSocketExternal.OnConnectionSuccessful += (s, e1) => Console.WriteLine("ConnectSocketExternal.OnConnectionSuccessful");
                        ConnectSocketExternal.Connect(message.ExternalPeerEndPoint.Address, message.ExternalPeerEndPoint.Port);
                    }
                    break;
            }
        }
 static void Peer_OnMessageReceived(object sender, MessageReceivedEventArgs e)
 {
 }