[Freeswitch-svn] [commit] r8236 - in freeswitch/trunk/scripts/contrib/verifier/EventSocket: . trunk trunk/EventWatcher trunk/EventWatcher/Properties trunk/FreeSwitch.EventSocket.Test trunk/FreeSwitch.EventSocket.Test/Properties trunk/FreeSwitchEventSocket trunk/FreeSwitchEventSocket/ChannelEvents trunk/FreeSwitchEventSocket/Commands trunk/FreeSwitchEventSocket/Events trunk/FreeSwitchEventSocket/General trunk/FreeSwitchEventSocket/Ivr trunk/FreeSwitchEventSocket/Properties trunk/FreeSwitchEventSocket/SipEvents trunk/IvrSocket trunk/IvrSocket/Properties

Freeswitch SVN verifier at freeswitch.org
Thu May 1 14:27:39 EDT 2008


Author: verifier
Date: Thu May  1 14:27:39 2008
New Revision: 8236

Added:
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Call.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/CallManager.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/CallStateEvent.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/EventWatcher.csproj
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Extension.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.Designer.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.resx
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/LabelTextBox.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Program.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/AssemblyInfo.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Resources.Designer.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Resources.resx
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Settings.Designer.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Settings.settings
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/ReadMePlease.txt
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/EventSocket.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/FreeSwitch.EventSocket.Test.csproj
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/ParserTest.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Program.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Properties/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Properties/AssemblyInfo.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.sln
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/ChannelEvent.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelAnswer.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelApplication.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelBridge.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelCreate.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelDestroy.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelExecute.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelExecuteComplete.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelHangup.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelOriginate.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelOutgoing.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelProgress.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelState.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelUnbridge.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelUnpark.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventCodec.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventDtmf.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventDtmfStatus.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelInfo.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/AnyCommand.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Api.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/AuthCommand.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/CmdBase.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/CommandReply.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ExecuteJavascript.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/GetVariable.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/HoldCmd.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Originate.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ParkCmd.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Playback.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/RecordCmd.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SendMsg.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SetVariable.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SleepCmd.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/TransferCmd.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventManager.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventParser.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.pfx   (contents, props changed)
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventApiCommand.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventBase.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventHeartbeat.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventMessageQuery.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventMessageWaiting.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventReSchedule.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/FreeSwitch.EventSocket.csproj
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/Address.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/ChannelVariable.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/SipAddress.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/SofiaSipAddress.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Ivr/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Ivr/IvrInterface.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/PartyInfo.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/PlainEventMsg.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Program.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Properties/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Properties/AssemblyInfo.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresence.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceIn.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceOut.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceProbe.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventRoster.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventSofiaExpire.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventSofiaRegister.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/SipEvent.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringHelper.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringParser.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/IvrSocket.csproj
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Program.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Properties/
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Properties/AssemblyInfo.cs
   freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Voicemail.cs

Log:
Initial version

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Call.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Call.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace EventWatcher
+{
+    public class Call
+    {
+        private CallState _currentState = CallState.Disconnected;
+        private CallState _previousState = CallState.Disconnected;
+        private string _id;
+        private string _destination;
+
+        public Call(string id)
+        {
+            _id = id;
+        }
+
+        public string Id
+        {
+            get { return _id; }
+            set { _id = value; }
+        }
+
+        public string Destination
+        {
+            get { return _destination; }
+        }
+
+        public CallState State
+        {
+            get { return _currentState; }
+        }
+
+        public CallState PreviousState
+        {
+            get { return _previousState; }
+        }
+
+        internal void SetCallState(CallState state)
+        {
+            _previousState = _currentState;
+            _currentState = state;
+        }
+
+        internal void SetDestination(string dest)
+        {
+            _destination = dest;
+        }
+
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/CallManager.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/CallManager.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,251 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using FreeSwitch.EventSocket;
+using FreeSwitch.EventSocket.Commands;
+
+namespace EventWatcher
+{
+    internal class CallManager
+    {
+        #region Delegates
+
+        public delegate void CallStateHandler(CallManager mgr, CallStateEvent callEvent);
+
+        #endregion
+
+        private EventManager _eventMgr;
+        private IDictionary<string, CallStateEvent> _events = new Dictionary<string, CallStateEvent>();
+
+        private IDictionary<string, ExtensionMapper> _extensions = new Dictionary<string, ExtensionMapper>();
+        private int _lastCallId = 0;
+
+        public CallManager(EventManager eventSocket)
+        {
+            _eventMgr = eventSocket;
+        }
+
+        public event ExtensionHandler ExtensionAdded;
+        public event CallHandler ExtensionChanged;
+        public event ExtensionHandler ExtensionDisconnected;
+        public event CallStateHandler OnCallState;
+
+        private ExtensionMapper GetMapper(string address)
+        {
+            if (_extensions.ContainsKey(address))
+                return _extensions[address];
+            else
+            {
+                ExtensionMapper em = new ExtensionMapper();
+                em.setter = new ExtensionSetters();
+                em.extension = new Extension(address, em.setter);
+                _extensions.Add(address, em);
+                if (ExtensionAdded != null)
+                    ExtensionAdded(em.extension);
+
+                return em;
+            }
+        }
+
+        private string ChannelDestination(string channelName)
+        {
+            //Check.Require(channelName, "Channel name must be set.");
+            string[] parts = channelName.Split('/');
+            //Check.Require(parts.Length == 3, "Channel must be sofia/<domain>/<user>");
+            return parts[2];
+        }
+
+        public void OnSwitchEvents(EventBase theEvent)
+        {
+            if (theEvent is EventPresenceIn)
+            {
+                EventPresenceIn ep = (EventPresenceIn) theEvent;
+                //Channel-State: CS_RING
+                //Channel-Name: sofia/default/jonas%40192.168.1.102%3A5070
+                //Unique-ID: 2f87ba27-2f71-d64d-8c64-9966ee894eac
+                //Call-Direction: inbound
+                //Answer-State: ringing
+                //Event-Name: PRESENCE_IN
+                CallState state = CallState.Unknown;
+                string destination = string.Empty;
+                if (ep.ChannelState.ChannelInfo.State == ChannelState.Ring)
+                {
+                    if (IsInbound(ep))
+                    {
+                        state = CallState.Alerting;
+                        destination = ep.Caller.DestinationNumber;
+                    }
+                    else
+                    {
+                        state = CallState.Offering;
+                        destination = ep.Caller.UserName;
+                    }
+                }
+                else if (ep.ChannelState.ChannelInfo.State == ChannelState.Hangup)
+                {
+                    state = CallState.Disconnected;
+                    if (IsInbound(ep))
+                        destination = ep.Caller.DestinationNumber;
+                    else
+                        destination = ep.Caller.UserName;
+                }
+                if (state != CallState.Unknown)
+                    TriggerCallState(ep.ChannelState.ChannelInfo.Address, ep.ChannelState.UniqueId, state, destination);
+            }
+            else if (theEvent is EventChannelAnswer)
+            {
+                EventChannelAnswer ea = (EventChannelAnswer) theEvent;
+                string destination;
+                if (IsInbound(ea))
+                    destination = ea.Caller.DestinationNumber;
+                else
+                    destination = ea.Caller.UserName;
+
+                TriggerCallState(ea.ChannelInfo.Address, ea.UniqueId, CallState.Connected, destination);
+            }
+
+            else if (theEvent is EventChannelDestroy)
+            {
+                EventChannelDestroy e = (EventChannelDestroy) theEvent;
+                Debug.WriteLine("triggering CallState.Disconnected");
+                TriggerCallState(e.ChannelInfo.Address, e.UniqueId, CallState.Disconnected,
+                                 e.Originator.DestinationNumber);
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="evt"></param>
+        /// <returns>true if it's inbound to pbx (not to user)</returns>
+        private bool IsInbound(EventBase evt)
+        {
+            return evt.Parameters["Call-Direction"] == "inbound";
+        }
+
+
+        public void OnSwitchEvents2(EventBase theEvent)
+        {
+            ChannelEvent evt = theEvent as ChannelEvent;
+            EventChannelState channelState = theEvent as EventChannelState;
+            if (channelState != null)
+                Debug.WriteLine("ChannelState: " + channelState.ChannelInfo.State + " " + channelState.Caller.UserName +
+                                " " + channelState.Caller.DestinationNumber);
+            else if (evt != null && evt.ChannelInfo != null)
+                Debug.WriteLine("ChannelEvent: " + evt.Name + " " + evt.ChannelInfo.Address);
+            if (evt != null)
+            {
+                // CHANNEL_ANSWER, No originator = new outgoing call. 
+                // ChannelName = the one who makes the call
+                if (evt is EventChannelAnswer)
+                {
+                    EventChannelAnswer e = (EventChannelAnswer) evt;
+                    if (e.Originator.CallerIdName != string.Empty)
+                    {
+                        Debug.WriteLine("Skipping emoty ChannelAnswer");
+                        return; // We do only want empty ones.
+                    }
+
+                    if (!IsExternalNumber(evt.ChannelInfo.Address))
+                    {
+                        Debug.WriteLine("triggering CallState.Alerting");
+                        TriggerCallState(evt.ChannelInfo.Address, e.UniqueId, CallState.Alerting,
+                                         e.Caller.DestinationNumber);
+                    }
+                }
+
+                    // CHANNEL_OUTGOING, Event for Alerting/Offering
+                    // Originator = the one calling
+                    // ChannelName = the one getting called.
+                else if (evt is EventChannelOutgoing)
+                {
+                    EventChannelOutgoing e = (EventChannelOutgoing) evt;
+                    if (!IsExternalNumber(evt.ChannelInfo.Address))
+                    {
+                        Debug.WriteLine("triggering CallState.Offering");
+                        TriggerCallState(evt.ChannelInfo.Address, e.UniqueId, CallState.Offering, e.Originator.UserName);
+                    }
+                    if (!IsExternalNumber(e.Originator.UserName))
+                    {
+                        Debug.WriteLine("triggering CallState.Alerting");
+                        TriggerCallState(e.Originator.UserName, e.Originator.UniqueId, CallState.Alerting,
+                                         e.ChannelInfo.Address);
+                    }
+                }
+
+                else if (evt is EventChannelBridge)
+                {
+                    EventChannelBridge e = (EventChannelBridge) evt;
+                    if (!IsExternalNumber(evt.ChannelInfo.Address))
+                    {
+                        Debug.WriteLine("triggering CallState.Connected");
+                        TriggerCallState(evt.ChannelInfo.Address, e.UniqueId, CallState.Connected,
+                                         e.Caller.DestinationNumber);
+                    }
+
+                    // Trigger destination
+                    if (!IsExternalNumber(e.Caller.DestinationNumber) && e.Originator.ChannelName != string.Empty)
+                    {
+                        Debug.WriteLine("triggering CallState.Connected");
+                        TriggerCallState(ChannelDestination(e.Originator.ChannelName), e.UniqueId, CallState.Connected,
+                                         e.ChannelInfo.Address);
+                    }
+                }
+
+                else if (evt is EventChannelDestroy)
+                {
+                    EventChannelDestroy e = (EventChannelDestroy) evt;
+                    Debug.WriteLine("triggering CallState.Disconnected");
+                    TriggerCallState(evt.ChannelInfo.Address, e.UniqueId, CallState.Disconnected,
+                                     e.Originator.DestinationNumber);
+                }
+            }
+        }
+
+        private bool IsExternalNumber(string number)
+        {
+            if (number == null || number == string.Empty)
+                return false;
+            return number[0] == '+';
+        }
+
+        private void TriggerCallState(string extensionOrUserName, string id, CallState state, string destination)
+        {
+            ExtensionMapper em = GetMapper(extensionOrUserName);
+            Debug.WriteLine(String.Format("{0} -> {1}, {2} id: {3}", extensionOrUserName, destination, state, id));
+            Call call = em.setter.callState(id, state, destination);
+            if (ExtensionChanged != null)
+                ExtensionChanged(em.extension, call);
+        }
+
+        private void OnBridgeCallId(CmdBase command, CommandReply reply)
+        {
+            GetVariableReply gvr = (GetVariableReply) reply;
+            if (!gvr.Success)
+                Debug.WriteLine("OnBridgeCallId " + reply.ErrCode);
+
+            string otherChannelId = (string) command.ContextData;
+            SetVariable sv = new SetVariable(otherChannelId, "gate_callid", gvr.Value);
+            sv.OnReply += OnCallIdReply;
+            _eventMgr.Send(sv);
+            command.OnReply -= OnBridgeCallId;
+        }
+
+        private void OnCallIdReply(CmdBase command, CommandReply reply)
+        {
+            if (!reply.Success)
+                Debug.WriteLine("OnCallIdReply " + reply.ErrCode);
+            command.OnReply -= OnCallIdReply;
+        }
+
+        #region Nested type: ExtensionMapper
+
+        private class ExtensionMapper
+        {
+            public Extension extension;
+            public ExtensionSetters setter;
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/CallStateEvent.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/CallStateEvent.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,158 @@
+using System;
+
+namespace EventWatcher
+{
+    public enum CallState
+    {
+        Unknown,
+
+        /// <summary>
+        /// The call has been created, but Connect has not been called yet. 
+        /// A call can never transition into the idle state. 
+        /// This is the initial state for both incoming and outgoing calls.
+        /// </summary>
+        Idle,
+        /// <summary>
+        /// Connect has been called, and the service provider is working on 
+        /// making a connection. This state is valid only on outgoing calls. 
+        /// This message is optional, because a service provider may have a 
+        /// call transition directly to the connected state.
+        /// </summary>
+        InProgress,
+        /// <summary>
+        /// Call has been connected to the remote end and communication can take place.
+        /// </summary>
+        Connected,
+        /// <summary>
+        /// Call has been disconnected. There are several causes for disconnection. 
+        /// See the table of valid call state transitions below.
+        /// </summary>
+        Disconnected,
+        /// <summary>
+        /// A new call has appeared, and is being offered to an application. 
+        /// If the application has owner privileges on the call, it can either 
+        /// call Answer or Disconnect while the call is in the offering state. 
+        /// </summary>
+        Offering,
+        Alerting,
+        /// <summary>
+        /// The call is in the hold state.
+        /// </summary>
+        Held,
+    }
+
+    public enum HangupCause
+    {
+        Success,
+        NormalClearing,
+        NoRouteTransitNet,
+        NoRouteDestination,
+        Busy,
+        Noanswer,
+        Rejected,
+        NumberChanged,
+        Congestion,
+    }
+    /// <summary>
+    /// Subclass for all call events.
+    /// The events are sent as commands through the
+    /// Command Dispatcher.
+    /// </summary>
+    [Serializable]
+    public class CallStateEvent
+    {
+        private string _callId;
+        private string _pbxId;
+        private string _destination;
+        private string _from;
+        private CallState _state = CallState.Idle;
+        private bool _isIncoming = true;
+        private bool _isInternal;
+        private HangupCause _hangupCause;
+
+        public CallStateEvent()
+        {
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="callId">Call identification string</param>
+        /// <param name="pbxId">Id used internally in the pbx to identify the call.</param>
+        /// <param name="from">Sip-Address to the one that made the call</param>
+        /// <param name="destination">Sip-address to where the call was made.</param>
+        public CallStateEvent(string callId, string pbxId, string from, string destination)
+        {
+            _callId = callId;
+            _from = from;
+            PbxId = pbxId;
+            _destination = destination;
+        }
+
+        /// <summary>
+        /// Call identification string.
+        /// </summary>
+        public string CallId
+        {
+            get { return _callId; }
+            set { _callId = value; }
+        }
+
+        /// <summary>
+        /// User that made the call.
+        /// </summary>
+        public string From
+        {
+            get { return _from; }
+            set { _from = value; }
+        }
+
+        /// <summary>
+        /// To whom the call was made.
+        /// </summary>
+        public string Destination
+        {
+            get { return _destination; }
+            set { _destination = value; }
+        }
+
+        /// <summary>
+        /// Current CallState.
+        /// </summary>
+        public CallState State
+        {
+            get { return _state; }
+            set { _state = value; }
+        }
+
+        /// <summary>
+        /// This is an incoming call.
+        /// </summary>
+        public bool Incoming
+        {
+            get { return _isIncoming; }
+            set { _isIncoming = value; }
+        }
+
+        /// <summary>
+        /// This is an internal call in the pbx.
+        /// </summary>
+        public bool Internal
+        {
+            get { return _isInternal; }
+            set { _isInternal = value; }
+        }
+
+        public HangupCause HangupCause
+        {
+            get { return _hangupCause; }
+            set { _hangupCause = value; }
+        }
+
+        internal string PbxId
+        {
+            get { return _pbxId; }
+            set { _pbxId = value; }
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/EventWatcher.csproj
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/EventWatcher.csproj	Thu May  1 14:27:39 2008
@@ -0,0 +1,96 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{E65ABA5F-A578-4E3C-989D-0FE4E459C03D}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>EventWatcher</RootNamespace>
+    <AssemblyName>EventWatcher</AssemblyName>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Design" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Call.cs" />
+    <Compile Include="CallManager.cs" />
+    <Compile Include="CallStateEvent.cs" />
+    <Compile Include="Extension.cs" />
+    <Compile Include="Form1.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Form1.Designer.cs">
+      <DependentUpon>Form1.cs</DependentUpon>
+    </Compile>
+    <Compile Include="LabelTextBox.cs">
+      <SubType>Component</SubType>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="Form1.resx">
+      <SubType>Designer</SubType>
+      <DependentUpon>Form1.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+      <DesignTime>True</DesignTime>
+    </Compile>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\FreeSwitchEventSocket\FreeSwitch.EventSocket.csproj">
+      <Project>{3F8895F6-F710-4323-B96A-4EFB6BC97E08}</Project>
+      <Name>FreeSwitch.EventSocket</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="ReadMePlease.txt" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Extension.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Extension.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,162 @@
+using System;
+using System.Collections.Generic;
+
+namespace EventWatcher
+{
+    public delegate void ExtensionHandler(Extension extension);
+    public delegate void CallHandler(Extension extension, Call call);
+    public delegate Call CallStateSetter(string id, CallState state, string destination);
+
+    /// <summary>
+    /// Used to set states for the extension.
+    /// We are using this method since we do not want anything else
+    /// but the CallMgr to be able to set stuff.
+    /// </summary>
+    /// <param name="forwardAll">null if it has changed, else the new forward destination</param>
+    /// <param name="forwardBusy">null if it has changed, else the new forward destination</param>
+    /// <param name="forwardNoAnswer">null if it has changed, else the new forward destination</param>
+    public delegate void ForwardSetter(string forwardAll, string forwardBusy, string forwardNoAnswer);
+
+    public class ExtensionSetters
+    {
+        public CallStateSetter callState;
+        public ForwardSetter forwardSetter;
+    }
+
+    /// <summary>
+    /// Class representing an extension.
+    /// </summary>
+    [Serializable]
+    public class Extension
+    {
+        private readonly string _address = string.Empty;
+        private readonly IDictionary<string, Call> _calls = new Dictionary<string, Call>();
+        private readonly string _destination = string.Empty;
+        private string _forwardAll = string.Empty;
+        private string _forwardBusy = string.Empty;
+        private string _forwardNoAnswer = string.Empty;
+        private ExtensionSetters _handler;
+
+        public Extension(string address)
+        {
+            _address = address;
+        }
+
+        public Extension(string address, ExtensionSetters setters)
+        {
+            _address = address;
+            Handler = setters;
+        }
+
+        public bool IsBusy
+        {
+            get
+            {
+                foreach (KeyValuePair<string, Call> pair in _calls)
+                {
+                    if (pair.Value.State != CallState.Disconnected
+                        && pair.Value.State != CallState.Held)
+                        return false;
+                }
+                return true;
+            }
+        }
+
+        /// <summary>
+        /// Determines if this extension is forwarded in any way
+        /// </summary>
+        public bool IsForwarded
+        {
+            get
+            {
+                return _forwardNoAnswer != string.Empty
+                       || _forwardBusy != string.Empty
+                       || _forwardAll != string.Empty;
+            }
+        }
+
+        public string ForwardAll
+        {
+            get { return _forwardAll; }
+        }
+
+        public string ForwardBusy
+        {
+            get { return _forwardBusy; }
+        }
+
+        public string ForwardNoAnswer
+        {
+            get { return _forwardNoAnswer; }
+        }
+
+        public string Destination
+        {
+            get { return _destination; }
+        }
+
+        public string Address
+        {
+            get { return _address; }
+        }
+
+        public ExtensionSetters Handler
+        {
+            get { return _handler; }
+            set
+            {
+                if (value != null)
+                    //Check.Require(_handler == null, "Handler can only be assigned one time.");
+
+                    _handler = value;
+                if (value != null)
+                {
+                    value.callState = SetCallState;
+                    value.forwardSetter = SetForward;
+                }
+            }
+        }
+
+        private Call SetCallState(string id, CallState state, string destination)
+        {
+            bool wasBusy = IsBusy;
+
+            Call call;
+            if (!_calls.ContainsKey(id))
+                call = new Call(id);
+            else
+                call = _calls[id];
+
+            call.SetCallState(state);
+            call.SetDestination(destination);
+
+            if (CallChanged != null)
+                CallChanged(this, call);
+
+            if (state == CallState.Disconnected)
+                _calls.Remove(id);
+
+
+            if (wasBusy != IsBusy && BusyStateChanged != null)
+                BusyStateChanged(this);
+
+            return call;
+        }
+
+        private void SetForward(string forwardAll, string forwardBusy, string forwardNoAnswer)
+        {
+            if (forwardAll != null)
+                _forwardAll = forwardAll;
+            if (forwardBusy != null)
+                _forwardBusy = forwardBusy;
+            if (forwardNoAnswer != null)
+                _forwardNoAnswer = forwardNoAnswer;
+            if (ForwardChanged != null)
+                ForwardChanged(this);
+        }
+
+        public event ExtensionHandler BusyStateChanged;
+        public event CallHandler CallChanged;
+        public event ExtensionHandler ForwardChanged;
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.Designer.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.Designer.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,212 @@
+namespace EventWatcher
+{
+    partial class Form1
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.panel1 = new System.Windows.Forms.Panel();
+            this.log = new System.Windows.Forms.TextBox();
+            this.info = new System.Windows.Forms.RichTextBox();
+            this.lv = new System.Windows.Forms.ListView();
+            this.colAddress = new System.Windows.Forms.ColumnHeader();
+            this.colId = new System.Windows.Forms.ColumnHeader();
+            this.colPbxId = new System.Windows.Forms.ColumnHeader();
+            this.colState = new System.Windows.Forms.ColumnHeader();
+            this.colCaller = new System.Windows.Forms.ColumnHeader();
+            this.colOriginator = new System.Windows.Forms.ColumnHeader();
+            this.colOrginatee = new System.Windows.Forms.ColumnHeader();
+            this.lvAll = new System.Windows.Forms.ListView();
+            this.from = new System.Windows.Forms.ColumnHeader();
+            this.To = new System.Windows.Forms.ColumnHeader();
+            this.ChannelId = new System.Windows.Forms.ColumnHeader();
+            this.SessionId = new System.Windows.Forms.ColumnHeader();
+            this.State = new System.Windows.Forms.ColumnHeader();
+            this.panel1.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // panel1
+            // 
+            this.panel1.Controls.Add(this.log);
+            this.panel1.Controls.Add(this.info);
+            this.panel1.Dock = System.Windows.Forms.DockStyle.Right;
+            this.panel1.Location = new System.Drawing.Point(627, 0);
+            this.panel1.Name = "panel1";
+            this.panel1.Size = new System.Drawing.Size(293, 546);
+            this.panel1.TabIndex = 11;
+            // 
+            // log
+            // 
+            this.log.Dock = System.Windows.Forms.DockStyle.Bottom;
+            this.log.Location = new System.Drawing.Point(0, 526);
+            this.log.Name = "log";
+            this.log.Size = new System.Drawing.Size(293, 20);
+            this.log.TabIndex = 11;
+            // 
+            // info
+            // 
+            this.info.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.info.Location = new System.Drawing.Point(0, 0);
+            this.info.Name = "info";
+            this.info.Size = new System.Drawing.Size(293, 546);
+            this.info.TabIndex = 10;
+            this.info.Text = "";
+            // 
+            // lv
+            // 
+            this.lv.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.colAddress,
+            this.colId,
+            this.colPbxId,
+            this.colState,
+            this.colCaller,
+            this.colOriginator,
+            this.colOrginatee});
+            this.lv.Dock = System.Windows.Forms.DockStyle.Top;
+            this.lv.Location = new System.Drawing.Point(0, 0);
+            this.lv.Name = "lv";
+            this.lv.Size = new System.Drawing.Size(627, 152);
+            this.lv.TabIndex = 12;
+            this.lv.UseCompatibleStateImageBehavior = false;
+            this.lv.View = System.Windows.Forms.View.Details;
+            // 
+            // colAddress
+            // 
+            this.colAddress.Text = "Anknytning";
+            this.colAddress.Width = 65;
+            // 
+            // colId
+            // 
+            this.colId.Text = "Id";
+            this.colId.Width = 26;
+            // 
+            // colPbxId
+            // 
+            this.colPbxId.Text = "PbxId";
+            this.colPbxId.Width = 230;
+            // 
+            // colState
+            // 
+            this.colState.Text = "Status";
+            this.colState.Width = 50;
+            // 
+            // colCaller
+            // 
+            this.colCaller.Text = "Caller";
+            this.colCaller.Width = 62;
+            // 
+            // colOriginator
+            // 
+            this.colOriginator.Text = "Originator";
+            this.colOriginator.Width = 72;
+            // 
+            // colOrginatee
+            // 
+            this.colOrginatee.Text = "Orginatee";
+            this.colOrginatee.Width = 116;
+            // 
+            // lvAll
+            // 
+            this.lvAll.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.from,
+            this.To,
+            this.ChannelId,
+            this.SessionId,
+            this.State});
+            this.lvAll.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.lvAll.Location = new System.Drawing.Point(0, 152);
+            this.lvAll.Name = "lvAll";
+            this.lvAll.Size = new System.Drawing.Size(627, 394);
+            this.lvAll.TabIndex = 13;
+            this.lvAll.UseCompatibleStateImageBehavior = false;
+            this.lvAll.View = System.Windows.Forms.View.Details;
+            this.lvAll.SelectedIndexChanged += new System.EventHandler(this.lvAll_SelectedIndexChanged);
+            this.lvAll.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.lvAll_ItemSelectionChanged);
+            // 
+            // from
+            // 
+            this.from.Text = "Från";
+            // 
+            // To
+            // 
+            this.To.Text = "Till";
+            this.To.Width = 84;
+            // 
+            // ChannelId
+            // 
+            this.ChannelId.Text = "ChannelId";
+            this.ChannelId.Width = 282;
+            // 
+            // SessionId
+            // 
+            this.SessionId.Text = "SessionId";
+            this.SessionId.Width = 318;
+            // 
+            // State
+            // 
+            this.State.Text = "State";
+            this.State.Width = 99;
+            // 
+            // Form1
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(920, 546);
+            this.Controls.Add(this.lvAll);
+            this.Controls.Add(this.lv);
+            this.Controls.Add(this.panel1);
+            this.Name = "Form1";
+            this.Text = "Form1";
+            this.Load += new System.EventHandler(this.Form1_Load);
+            this.panel1.ResumeLayout(false);
+            this.panel1.PerformLayout();
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Panel panel1;
+        private System.Windows.Forms.TextBox log;
+        private System.Windows.Forms.RichTextBox info;
+        private System.Windows.Forms.ListView lv;
+        private System.Windows.Forms.ColumnHeader colAddress;
+        private System.Windows.Forms.ColumnHeader colId;
+        private System.Windows.Forms.ColumnHeader colPbxId;
+        private System.Windows.Forms.ColumnHeader colState;
+        private System.Windows.Forms.ColumnHeader colCaller;
+        private System.Windows.Forms.ColumnHeader colOriginator;
+        private System.Windows.Forms.ColumnHeader colOrginatee;
+        private System.Windows.Forms.ListView lvAll;
+        private System.Windows.Forms.ColumnHeader from;
+        private System.Windows.Forms.ColumnHeader To;
+        private System.Windows.Forms.ColumnHeader ChannelId;
+        private System.Windows.Forms.ColumnHeader SessionId;
+        private System.Windows.Forms.ColumnHeader State;
+
+    }
+}
+

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,235 @@
+using System;
+using System.Diagnostics;
+using System.Drawing;
+using System.Reflection;
+using System.Windows.Forms;
+using FreeSwitch.EventSocket;
+using FreeSwitch.EventSocket.Commands;
+using FreeSwitch.EventSocket.General;
+
+namespace EventWatcher
+{
+    public partial class Form1 : Form
+    {
+        private EventManager _eventMgr;
+        private CallManager _callMgr;
+
+        public Form1()
+        {
+            InitializeComponent();
+            _eventMgr = new EventManager();
+            _callMgr = new CallManager(_eventMgr);
+            _callMgr.OnCallState += OnCallState;
+            _callMgr.ExtensionAdded += OnExtensionAdded;
+            _callMgr.ExtensionChanged += OnExtensionChanged;
+
+
+        }
+
+        private void OnExtensionAdded(Extension extension)
+        {
+            //throw new NotImplementedException();
+        }
+
+        private void OnExtensionChanged(Extension extension, Call call)
+        {
+            if (lv.InvokeRequired)
+                BeginInvoke((MethodInvoker)delegate { OnExtensionChangedX(extension, call); });
+            else
+                OnExtensionChangedX(extension, call);
+        }
+
+        private void OnExtensionChangedX(Extension extension, Call call)
+        {
+            ListViewItem item = null;
+            foreach (ListViewItem item2 in lv.Items)
+            {
+                if (String.Compare(item2.Name, extension.Address, true) == 0)
+                {
+                    item = item2;
+                    break;
+                }
+            }
+            if (item == null)//(!lv.Items.ContainsKey(extension.Address))
+            {
+                item = lv.Items.Add(extension.Address, extension.Address, 0);
+                item.Tag = extension;
+                item.SubItems.Add(call.Id);
+                item.SubItems.Add(call.State.ToString());
+                item.SubItems.Add(call.PreviousState.ToString());
+                item.SubItems.Add("");
+                item.SubItems.Add(extension.Destination);                
+            }
+            else
+            {
+                item.SubItems[2].Text = call.State.ToString();
+                item.SubItems[3].Text = call.PreviousState.ToString();
+            }
+        }
+
+        private void OnExtensionCallState(Extension e)
+        {
+            
+        }
+        private void OnCallState(CallManager mgr, CallStateEvent cs)
+        {
+            if (lv.InvokeRequired)
+                BeginInvoke((MethodInvoker)delegate { OnCallStateX(mgr, cs); });
+            else
+                OnCallStateX(mgr, cs);
+        }
+
+        private void OnCallStateX(CallManager mgr, CallStateEvent cs)
+        {
+            ListViewItem item;
+            if (!lv.Items.ContainsKey(cs.PbxId))
+            {
+                item = lv.Items.Add(cs.PbxId, cs.From, 0);
+                item.Tag = cs;
+                item.SubItems.Add(cs.CallId);
+                item.SubItems.Add(cs.PbxId);
+                item.SubItems.Add(cs.State.ToString());
+                item.SubItems.Add(cs.From);
+                item.SubItems.Add(cs.Destination);
+            }
+            else
+                item = lv.Items[cs.PbxId];
+
+            item.SubItems[1].Text = cs.CallId;
+            item.SubItems[3].Text = cs.State.ToString();
+            item.SubItems[4].Text = cs.Destination;
+
+            if (cs.State == CallState.Disconnected)
+                lv.Items.RemoveByKey(cs.PbxId);
+        }
+
+        private void Form1_Load(object sender, EventArgs e)
+        {
+            _eventMgr.Password = "ClueCon";
+            _eventMgr.Start("localhost");
+            _eventMgr.Subscribe(new Events(Event.All));
+            _eventMgr.EventReceived += OnPreSwitchEvent;
+        }
+
+        private void OnPreSwitchEvent(EventBase theEvent)
+        {
+            _callMgr.OnSwitchEvents(theEvent);
+            if (lvAll.InvokeRequired)
+                BeginInvoke((MethodInvoker)delegate { OnSwitchEvent(theEvent); });
+            else
+                OnSwitchEvent(theEvent);
+        }
+
+
+        private string DisplayProperties(object o)
+        {
+            return DisplayProperties(o, 0);
+        }
+
+        private string DisplayProperties(object o, int spaces)
+        {
+            PropertyInfo[] pis = o.GetType().GetProperties();
+            string info = string.Empty;
+            foreach (PropertyInfo pi in pis)
+            {
+                if (pi.PropertyType == typeof (ChannelInfo) || pi.PropertyType == typeof (PartyInfo))
+                {
+                    info += pi.Name.PadLeft(spaces + pi.Name.Length) + "\r\n";
+                    info += DisplayProperties(pi.GetValue(o, null), spaces + 2);
+                }
+                else
+                    info += pi.Name.PadLeft(spaces + pi.Name.Length) + ": " + pi.GetValue(o, null) + "\r\n";
+            }
+            return info;
+        }
+
+        private void OnSwitchEvent(EventBase theEvent)
+        {
+            EventChannelState e = theEvent as EventChannelState;
+            if (e != null)
+            {
+
+                EventChannelState channelEvent = theEvent as EventChannelState;
+                if (channelEvent == null)
+                    return;
+
+                //OnSwitchEvents(theEvent);
+
+                ListViewItem item;
+                item = lvAll.Items.Add(channelEvent.ChannelInfo.Address);
+                item.Tag = channelEvent;
+                item.SubItems.Add(channelEvent.Originator.UserName);
+                item.SubItems.Add(channelEvent.UniqueId);
+                item.SubItems.Add(channelEvent.Caller.UniqueId);
+                if (channelEvent.Name == "CHANNEL_STATE")
+                    item.SubItems.Add(e.ChannelInfo.State.ToString());
+                else
+                    item.SubItems.Add(e.Name);
+
+                if (e.GetType() == typeof(EventCodec) || theEvent.GetType() == typeof(EventChannelExecute)
+                    || e.Originator.DestinationNumber == string.Empty)
+                {
+                    item.ForeColor = Color.Gray;
+                }
+
+            }
+            log.Text = theEvent.Name;
+        }
+
+        private void AddEvent(ListBox box, ChannelEvent e)
+        {
+            box.Items.Insert(0, new Wrapper(e));
+        }
+
+        private void lvAll_SelectedIndexChanged(object sender, EventArgs e)
+        {
+            /*
+            if (lvAll.SelectedItems.Count == 0)
+                return;
+            ListViewItem itm = lvAll.SelectedItems[0];
+            MessageBox.Show(DisplayProperties(itm.Tag));
+             * */
+        }
+
+        private void lvAll_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
+        {
+            if (lvAll.SelectedItems.Count == 0)
+                return;
+            ListViewItem itm = lvAll.SelectedItems[0];
+            info.Text = DisplayProperties(itm.Tag);
+        }
+
+        #region Nested type: SwitchEventHandler
+
+        private delegate void SwitchEventHandler(EventBase theEvent);
+
+        #endregion
+
+        #region Nested type: Wrapper
+
+        private class Wrapper
+        {
+            public ChannelEvent e;
+
+            public Wrapper(ChannelEvent e)
+            {
+                this.e = e;
+            }
+
+            public override string ToString()
+            {
+                return "[" + e.Name + "] " + e.ChannelInfo.State;
+            }
+        }
+
+        #endregion
+
+        private void btnOriginate_Click(object sender, EventArgs e)
+        {
+            //Originate org = new Originate();
+            //org.Caller = new SofiaSipAddress("gauffin.com");
+            //from_id.Text
+        }
+
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.resx
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Form1.resx	Thu May  1 14:27:39 2008
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/LabelTextBox.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/LabelTextBox.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+
+namespace EventWatcher
+{
+    class LabelTextBox : TextBox
+    {
+        private string _label;
+
+        public string Label
+        {
+            get { return _label; }
+            set 
+            { 
+                _label = value; 
+                if (Text == string.Empty)
+                    SetLabel();
+            }
+        }
+
+        public void test()
+        {
+            TextBox x = new TextBox();
+            x.KeyDown += tb_KeyDown;
+            x.TextChanged += tb_TextChanged;
+        }
+
+        private void tb_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
+        {
+            if (ForeColor == Color.FromKnownColor(KnownColor.InactiveCaptionText))
+                RemoveLabel();
+        }
+
+        private void tb_TextChanged(object sender, EventArgs e)
+        {
+            if (Text == string.Empty)
+              SetLabel();
+            else if (Text != _label && Text != string.Empty)
+             RemoveLabel();   
+        }
+
+        private void RemoveLabel()
+        {
+            ForeColor = Color.FromKnownColor(KnownColor.WindowText);
+            Text = string.Empty;
+
+        }
+        private void SetLabel()
+        {
+            ForeColor = Color.FromKnownColor(KnownColor.InactiveCaptionText);
+            Text = _label;
+
+        }
+
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Program.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Program.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+
+namespace EventWatcher
+{
+    static class Program
+    {
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            Application.Run(new Form1());
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/AssemblyInfo.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/AssemblyInfo.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("EventWatcher")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("EventWatcher")]
+[assembly: AssemblyCopyright("Copyright ©  2007")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("e6a71f21-6833-455f-a398-a0d6a54c1359")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Resources.Designer.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Resources.Designer.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.312
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace EventWatcher.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EventWatcher.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Resources.resx
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Resources.resx	Thu May  1 14:27:39 2008
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Settings.Designer.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Settings.Designer.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:2.0.50727.312
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace EventWatcher.Properties
+{
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Settings.settings
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/Properties/Settings.settings	Thu May  1 14:27:39 2008
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/ReadMePlease.txt
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/EventWatcher/ReadMePlease.txt	Thu May  1 14:27:39 2008
@@ -0,0 +1,3 @@
+This is just a test project that I used to develop the event socket lib.
+
+It could in the future be an application that keep track on all channels and their current state.
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/EventSocket.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/EventSocket.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using FreeSwitch.EventSocket;
+using FreeSwitch.EventSocket.Commands;
+using FreeSwitch.EventSocket.General;
+
+namespace FreeSwitch.EventSocket.Test
+{
+    class EventSocket
+    {
+        private FreeSwitch.EventSocket.EventSocket m_es = new FreeSwitch.EventSocket.EventSocket();
+
+        public void Setup()
+        {
+            m_es.Connect("192.168.1.102");
+            m_es.Subscribe(new Events(Event.All));
+            //m_es.SendApi(new Originate(new SofiaSipAddress("gauffin.com", "arne"), new Address("8888")));
+            System.Threading.Thread.Sleep(500000);
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/FreeSwitch.EventSocket.Test.csproj
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/FreeSwitch.EventSocket.Test.csproj	Thu May  1 14:27:39 2008
@@ -0,0 +1,55 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{3679225D-79A3-4B6C-BCA1-E2DC265E423A}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>FreeSwitch.EventSocket.Test</RootNamespace>
+    <AssemblyName>FreeSwitch.EventSocket.Test</AssemblyName>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="EventSocket.cs" />
+    <Compile Include="ParserTest.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\FreeSwitchEventSocket\FreeSwitch.EventSocket.csproj">
+      <Project>{3F8895F6-F710-4323-B96A-4EFB6BC97E08}</Project>
+      <Name>FreeSwitch.EventSocket</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/ParserTest.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/ParserTest.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket.Test
+{
+    class ParserTest
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Program.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Program.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Text;
+
+namespace FreeSwitch.EventSocket.Test
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            EventManager mgr = new EventManager();
+            mgr.Subscribe(Events.GetChannelEvents());
+            mgr.Start("localhost");
+            Console.ReadLine();
+
+            string buffer = File.ReadAllText("..\\..\\..\\watcherRaw.log");
+            int bufLen = buffer.Length;
+
+            EventParser ep = new EventParser(buffer);
+            //int cnt = 0;
+            EventSocket es = new EventSocket();
+            es.Setup();
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Properties/AssemblyInfo.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.Test/Properties/AssemblyInfo.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("FreeSwitch.EventSocket.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("FreeSwitch.EventSocket.Test")]
+[assembly: AssemblyCopyright("Copyright ©  2007")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b496f9be-f1be-457d-b8c8-fae97c43df8e")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.sln
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitch.EventSocket.sln	Thu May  1 14:27:39 2008
@@ -0,0 +1,38 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSwitch.EventSocket", "FreeSwitchEventSocket\FreeSwitch.EventSocket.csproj", "{3F8895F6-F710-4323-B96A-4EFB6BC97E08}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSwitch.EventSocket.Test", "FreeSwitch.EventSocket.Test\FreeSwitch.EventSocket.Test.csproj", "{3679225D-79A3-4B6C-BCA1-E2DC265E423A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventWatcher", "EventWatcher\EventWatcher.csproj", "{E65ABA5F-A578-4E3C-989D-0FE4E459C03D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IvrSocket", "IvrSocket\IvrSocket.csproj", "{22F26D13-0A0E-4345-9FEC-CE13FC8F37FD}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{3F8895F6-F710-4323-B96A-4EFB6BC97E08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3F8895F6-F710-4323-B96A-4EFB6BC97E08}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3F8895F6-F710-4323-B96A-4EFB6BC97E08}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3F8895F6-F710-4323-B96A-4EFB6BC97E08}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3679225D-79A3-4B6C-BCA1-E2DC265E423A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3679225D-79A3-4B6C-BCA1-E2DC265E423A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3679225D-79A3-4B6C-BCA1-E2DC265E423A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3679225D-79A3-4B6C-BCA1-E2DC265E423A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E65ABA5F-A578-4E3C-989D-0FE4E459C03D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E65ABA5F-A578-4E3C-989D-0FE4E459C03D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E65ABA5F-A578-4E3C-989D-0FE4E459C03D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E65ABA5F-A578-4E3C-989D-0FE4E459C03D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{22F26D13-0A0E-4345-9FEC-CE13FC8F37FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{22F26D13-0A0E-4345-9FEC-CE13FC8F37FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{22F26D13-0A0E-4345-9FEC-CE13FC8F37FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{22F26D13-0A0E-4345-9FEC-CE13FC8F37FD}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/ChannelEvent.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/ChannelEvent.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class ChannelEvent : EventBase
+    {
+        private ChannelInfo _channelInfo;
+        private string _uniqueId = string.Empty;
+        private string _answerState;
+        private string _callDirection;
+
+        public override bool IsChannelEvent
+        {
+            get { return true; }
+        }
+
+        /// <summary>
+        /// Information about the used channel and it's state.
+        /// </summary>
+        public ChannelInfo ChannelInfo
+        {
+            get { return _channelInfo; }
+            set { _channelInfo = value; }
+        }
+
+        public string UniqueId
+        {
+            get { return _uniqueId; }
+            set { _uniqueId = value; }
+        }
+
+        public string AnswerState
+        {
+            get { return _answerState; }
+            set { _answerState = value; }
+        }
+
+        public string CallDirection
+        {
+            get { return _callDirection; }
+            set { _callDirection = value; }
+        }
+
+        public override bool ParseCommand(string name, string value)
+        {
+            if (name == "unique-id")
+                _uniqueId = value;
+            else if (name == "answer-state")
+                _answerState = value;
+            else if (name == "call-direction")
+                _callDirection = value;
+            else if (name.Length > 8 && name.Substring(0, 8) ==  "channel-")
+            {
+                if (_channelInfo == null)
+                    _channelInfo = new ChannelInfo();
+                return _channelInfo.Parse(name, value);
+            }
+            else
+                return base.ParseCommand(name, value);
+
+            return true;
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelAnswer.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelAnswer.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,6 @@
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelAnswer : EventChannelState
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelApplication.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelApplication.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelApplication : EventChannelState
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelBridge.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelBridge.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelBridge : EventChannelState
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelCreate.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelCreate.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,6 @@
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelCreate : ChannelEvent
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelDestroy.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelDestroy.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelDestroy : EventChannelState
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelExecute.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelExecute.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelExecute : EventChannelState
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelExecuteComplete.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelExecuteComplete.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,7 @@
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelExecuteComplete : EventChannelState
+    {
+    }
+}
+

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelHangup.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelHangup.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelHangup : EventChannelState
+    {
+        private Causes m_hangupCause;
+
+        public enum Causes
+        {
+            Success,
+            NoRouteTransitNet,
+            NoRouteDestination,
+            ChannelUnacceptable,
+            CallAwardedDelivered,
+            NormalClearing,
+            UserBusy,
+            NoUserResponse,
+            NoAnswer,
+            SubscriberAbsent,
+            CallRejected,
+            NumberChanged,
+            RedirectionToNewDestination,
+            ExchangeRoutingError,
+            DestinationOutOfOrder,
+            InvalidNumberFormat,
+            FacilityRejected,
+            ResponseToStatusEnquiry,
+            NormalUnspecified,
+            NormalCircuitCongestion,
+            NetworkOutOfOrder,
+            NormalTemporaryFailure,
+            SwitchCongestion,
+            AccessInfoDiscarded,
+            RequestedChanUnavail,
+            PreEmpted,
+            FacilityNotSubscribed,
+            OutgoingCallBarred,
+            IncomingCallBarred,
+            BearercapabilityNotauth,
+            BearercapabilityNotavail,
+            ServiceUnavailable,
+            ChanNotImplemented,
+            FacilityNotImplemented,
+            ServiceNotImplemented,
+            InvalidCallReference,
+            IncompatibleDestination,
+            InvalidMsgUnspecified,
+            MandatoryIeMissing,
+            MessageTypeNonexist,
+            WrongMessage,
+            IeNonexist,
+            InvalidIeContents,
+            WrongCallState,
+            RecoveryOnTimerExpire,
+            MandatoryIeLengthError,
+            ProtocolError,
+            Interworking,
+            OriginatorCancel,
+            Crash,
+            SystemShutdown,
+            LoseRace,
+            ManagerRequest,
+            BlindTransfer,
+            AttendedTransfer,
+            AllottedTimeout            
+        }
+
+        public Causes Cause
+        {
+            get { return m_hangupCause; }
+            set { m_hangupCause = value; }
+        }
+
+        public override bool ParseCommand(string name, string value)
+        {
+            if (name == "hangupcause" || name == "hangup-cause")
+            {
+                string cause = StringHelper.UpperCaseToCamelCase(value);
+                m_hangupCause = (Causes)Enum.Parse(typeof(Causes), cause);
+            }
+            else 
+                return base.ParseCommand(name, value);
+
+            return true;
+        }
+
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelOriginate.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelOriginate.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelOriginate : ChannelEvent
+    {
+
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelOutgoing.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelOutgoing.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelOutgoing : EventChannelState
+    {
+
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelProgress.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelProgress.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelProgress : EventChannelState
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelState.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelState.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,63 @@
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelState : ChannelEvent
+    {
+        private PartyInfo _caller = new PartyInfo();
+        private PartyInfo _originator = new PartyInfo();
+        private bool _screenBit = false;
+
+        /// <summary>
+        /// Information about the called party.
+        /// This property is null for certain channel states,
+        /// depending on if freeswitch sends it or not.
+        /// </summary>
+        public PartyInfo Caller
+        {
+            get { return _caller; }
+            set { _caller = value; }
+        }
+
+        /// <summary>
+        /// Information about the destination (place that the caller want to reach).
+        /// This property is null for certain channel states,
+        /// depending on if freeswitch sends it or not.
+        /// </summary>
+        public PartyInfo Originator
+        {
+            get { return _originator; }
+            set { _originator = value; }
+        }
+
+        public bool ScreenBit
+        {
+            get { return _screenBit; }
+            set { _screenBit = value; }
+        }
+
+        public override bool ParseCommand(string name, string value)
+        {
+            if (name == "screen-bit")
+            {
+                ScreenBit = value == "yes";
+                return true;
+            }
+            else if (name.Length > 11 && name.Substring(0, 11) == "originator-"
+                     || name.Length > 11 && name.Substring(0, 11) == "originatee-")
+            {
+                if (_originator == null)
+                    _originator = new PartyInfo();
+
+                return _originator.Parse(name.Substring(11), value);
+            }
+            else if (name.Length > 7 && name.Substring(0, 7) == "caller-")
+            {
+                if (_caller == null)
+                    _caller = new PartyInfo();
+
+                return _caller.Parse(name.Substring(7), value);
+            }
+            else
+                return base.ParseCommand(name, value);
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelUnbridge.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelUnbridge.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelUnbridge : EventChannelState
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelUnpark.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventChannelUnpark.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventChannelUnpark : EventChannelState
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventCodec.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventCodec.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,6 @@
+namespace FreeSwitch.EventSocket
+{
+    public class EventCodec : EventChannelState
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventDtmf.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventDtmf.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,35 @@
+namespace FreeSwitch.EventSocket
+{
+    public class EventDtmf : ChannelEvent
+    {
+        private char _digit;
+        private int _duration;
+
+        public char Digit
+        {
+            get { return _digit; }
+            set { _digit = value; }
+        }
+
+        public int Duration
+        {
+            get { return _duration; }
+            set { _duration = value; }
+        }
+
+        public override bool ParseCommand(string name, string value)
+        {
+            switch(name)
+            {
+                case "dtmf-digit":
+                    _digit = value[0];
+                    break;
+                case "dtmf-duration":
+                    int.TryParse(value, out _duration);
+                    break;
+            }
+
+            return base.ParseCommand(name, value);
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventDtmfStatus.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelEvents/EventDtmfStatus.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,31 @@
+namespace FreeSwitch.EventSocket
+{
+    /// <summary>
+    /// Reports when DTMF digits have been pressed
+    /// </summary>
+    public class EventDtmfStatus : ChannelEvent
+    {
+        private int _count;
+
+        /// <summary>
+        /// Number of digits in the buffer.
+        /// </summary>
+        public int Count
+        {
+            get { return _count; }
+        }
+
+
+        public override bool ParseCommand(string name, string value)
+        {
+            switch (name)
+            {
+                case "dtmf-count":
+                    int.TryParse(value, out _count);
+                    break;
+            }
+
+            return base.ParseCommand(name, value);
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelInfo.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/ChannelInfo.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,225 @@
+namespace FreeSwitch.EventSocket
+{
+    #region enum ChannelState
+    public enum ChannelState
+    {
+        New,       // Channel is newly created 
+        Init,      // Channel has been initilized
+        Ring,      // Channel is looking for a dialplan
+        Transmit,  // Channel is in a passive transmit state
+        Execute,   // Channel is executing it's dialplan 
+        Loopback,  // Channel is in loopback
+        Hold,	  // Channel is on hold
+        Hibernate, // Channel is in a sleep state
+        Hangup,    // Channel is flagged for hangup and ready to end
+        Done,      // Channel is ready to be destroyed and out of the state machine
+        Unknown
+    }
+    #endregion
+
+    public class ChannelInfo
+    {
+        private ChannelState m_state;
+        private int m_stateNumber;
+        private string _profile;
+        private string m_address;
+        private string _hostName;
+        private string m_protocol = string.Empty;
+        private string m_readCodecName;
+        private int m_readCodecRate;
+        private string m_writeCodecName;
+        private int m_writeCodecRate;
+
+        /// <summary>
+        /// Coded used to read information from the channel.
+        /// Example: L16
+        /// </summary>
+        public string ReadCodecName
+        {
+            get { return m_readCodecName; }
+            set { m_readCodecName = value; }
+        }
+
+        /// <summary>
+        /// Bitrate of the read coded that is used.
+        /// Example: 8000
+        /// </summary>
+        public int ReadCodecRate
+        {
+            get { return m_readCodecRate; }
+            set { m_readCodecRate = value; }
+        }
+
+        /// <summary>
+        /// Codec used for writing to the channel.
+        /// Example: L16
+        /// </summary>
+        public string WriteCodecName
+        {
+            get { return m_writeCodecName; }
+            set { m_writeCodecName = value; }
+        }
+
+        /// <summary>
+        /// Bitrate of the codec.
+        /// Example: 8000
+        /// </summary>
+        public int WriteCodecRate
+        {
+            get { return m_writeCodecRate; }
+            set { m_writeCodecRate = value; }
+        }
+
+        /// <summary>
+        /// State that the channel is in. Check ChannelState enum for more information.
+        /// </summary>
+        public ChannelState State
+        {
+            get { return m_state; }
+            set { m_state = value; }
+        }
+
+        /// <summary>
+        /// Number of the state (from the enum in FreeSwitch)
+        /// </summary>
+        public int StateNumber
+        {
+            get { return m_stateNumber; }
+            set { m_stateNumber = value; }
+        }
+
+        /// <summary>
+        /// Name of the channel.
+        /// </summary>
+        /// <example>sofia/mydomain.com/1234 at conference.freeswitch.org</example>
+        /// <seealso cref="ChannelInfo.Protocol"/>
+        /// <seealso cref="ProfileName"/>
+        /// <seealso cref="Address"/>
+        /// <seealso cref="HostName"/>
+        public string Name
+        {
+            get { return m_protocol + "/" + _profile + "/" + m_address + "@" + _hostName; }
+            set 
+            { 
+                string[] bits = value.Split('/');
+                if (bits.Length == 3)
+                {
+                    m_protocol = bits[0];
+                    _profile = bits[1];
+                    string[] userParts = bits[2].Split('@');
+                    if (userParts.Length == 2)
+                    {
+                        m_address = userParts[0];
+                        HostName = userParts[1];
+                    }
+                    else
+                        m_address = bits[2];
+                }
+                
+            }
+        }
+
+        /// <summary>
+        /// ProfileName for the diaplan/sip.
+        /// </summary>
+        public string ProfileName
+        {
+            get { return _profile; }
+            set { _profile = value; }
+        }
+
+        /// <summary>
+        /// Extension/Username for the channel
+        /// </summary>
+        public string Address
+        {
+            get { return m_address; }
+            set { m_address = value; }
+        }
+
+        /// <summary>
+        /// Where the extension/user is calling from.
+        /// </summary>
+        public string HostName
+        {
+            get { return _hostName; }
+            set
+            {
+                if (value == null)
+                {
+                    _hostName = string.Empty;
+                    return;
+                }
+
+                int pos = value.IndexOf(':');
+                if (pos == -1)
+                    _hostName = value;
+                else
+                    _hostName = value.Substring(0, pos);
+            }
+        }
+
+        /// <summary>
+        /// Protocol used for communication.
+        /// "sofia" = sip.
+        /// </summary>
+        public string Protocol
+        {
+            get { return m_protocol;  }
+        }
+
+        public bool Parse(string name, string value)
+        {
+            switch (name)
+            {
+                case "channel-state":
+                    m_state = StateFromString(value);
+                    break;
+                case "channel-state-number":
+                    int.TryParse(value, out m_stateNumber);
+                    break;
+                case "channel-name":
+                    Name = value;
+                    break;
+                case "channel-read-codec-name":
+                    m_readCodecName = value;
+                    break;
+                case "channel-read-codec-rate":
+                    int.TryParse(value, out m_readCodecRate);
+                    break;
+                case "channel-write-codec-name":
+                    m_writeCodecName = value;
+                    break;
+                case "channel-write-codec-rate":
+                    int.TryParse(value, out m_writeCodecRate);
+                    break;
+                default:
+                    return false;
+            }
+            return true;
+        }
+
+        public ChannelState StateFromString(string state)
+        {
+            switch (state)
+            {
+                case "CS_NEW": return ChannelState.New;
+                case "CS_INIT": return ChannelState.Init;
+                case "CS_RING": return ChannelState.Ring;
+                case "CS_TRANSMIT": return ChannelState.Transmit;
+                case "CS_EXECUTE": return ChannelState.Execute;
+                case "CS_LOOPBACK": return ChannelState.Loopback;
+                case "CS_HOLD": return ChannelState.Hold;
+                case "CS_HIBERNATE": return ChannelState.Hibernate;
+                case "CS_HANGUP": return ChannelState.Hangup;
+                case "CS_DONE": return ChannelState.Done;
+                default: return ChannelState.Unknown;
+            }
+        }
+
+        public string StateToString(ChannelState state)
+        {
+            return "Unknown";
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/AnyCommand.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/AnyCommand.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,36 @@
+namespace FreeSwitch.EventSocket.Commands
+{
+    public class AnyCommand : Api
+    {
+        private readonly string _name;
+        private readonly string _value;
+
+        public AnyCommand(string name, string arguments)
+        {
+            _name = name;
+            _value = arguments;
+        }
+
+        public override string Command
+        {
+            get { return _name; }
+        }
+
+        public override string Arguments
+        {
+            get { return _value; }
+        }
+
+        public override CommandReply CreateReply(string dataToParse)
+        {
+            if (dataToParse.Length > 0 && (dataToParse[0] == '+') || dataToParse == "OK")
+                return new CommandReply(true);
+            else
+            {
+                CommandReply reply = new CommandReply(false);
+                reply.ErrCode = dataToParse;
+                return reply;
+            }
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Api.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Api.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,10 @@
+namespace FreeSwitch.EventSocket.Commands
+{
+    public abstract class Api : CmdBase
+    {
+        public override string ToString()
+        {
+            return string.Format("api {0} {1}", Command, Arguments);
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/AuthCommand.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/AuthCommand.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,34 @@
+namespace FreeSwitch.EventSocket.Commands
+{
+    public class AuthCommand : CmdBase
+    {
+        private readonly string _password;
+
+        public AuthCommand(string password)
+        {
+            _password = password;
+        }
+
+        public override string Command
+        {
+            get { return "auth"; }
+        }
+
+        public override string Arguments
+        {
+            get { return _password; }
+        }
+
+        public override CommandReply CreateReply(string dataToParse)
+        {
+            if (dataToParse.Contains("+OK"))
+                return new CommandReply(true);
+            else
+            {
+                CommandReply reply = new CommandReply(false);
+                reply.ErrCode = dataToParse;
+                return reply;
+            }
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/CmdBase.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/CmdBase.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,55 @@
+namespace FreeSwitch.EventSocket.Commands
+{
+    #region Delegates
+
+    public delegate void ReplyHandler(CmdBase command, CommandReply reply);
+
+    #endregion
+
+    public abstract class CmdBase
+    {
+        public event ReplyHandler OnReply;
+
+        private object _contextData;
+
+        public abstract string Command
+        {
+            get;
+        }
+
+        public abstract string Arguments
+        {
+            get;
+        }
+
+        /// <summary>
+        /// You can attach something that you need to
+        /// identify the command.
+        /// </summary>
+        public object ContextData
+        {
+            get { return _contextData; }
+            set { _contextData = value; }
+        }
+
+        public virtual void HandleReply(CommandReply reply)
+        {
+            // a command is only invoked once.
+            if (OnReply != null)
+            {
+                OnReply(this, reply);
+                OnReply = null;                
+            }
+        }
+
+        public virtual CommandReply CreateReply(string dataToParse)
+        {
+            return null;
+        }
+
+        public override string ToString()
+        {
+            return string.Format("{0} {1}", Command, Arguments);
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/CommandReply.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/CommandReply.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,35 @@
+namespace FreeSwitch.EventSocket.Commands
+{
+    /// <summary>
+    /// Baseclass for replies that commands get.
+    /// </summary>
+    public class CommandReply
+    {
+        private bool _success;
+        private string _errCode;
+
+        public CommandReply(bool success)
+        {
+            _success = success;
+        }
+
+        public bool Success
+        {
+            get { return _success; }
+        }
+
+        public string ErrCode
+        {
+            get { return _errCode; }
+            set { _errCode = value; }
+        }
+
+        public override string ToString()
+        {
+            if (_success)
+                return "Success";
+            else
+                return "Failed: " + _errCode;
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ExecuteJavascript.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ExecuteJavascript.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,63 @@
+using System.Collections.Generic;
+
+namespace FreeSwitch.EventSocket.Commands
+{
+    public class ExecuteJavascript : Api
+    {
+        private readonly string _scriptName;
+        private readonly IList<string> _arguments = new List<string>();
+
+        public ExecuteJavascript()
+        {
+            
+        }
+
+        public ExecuteJavascript(string scriptName)
+        {
+            _scriptName = scriptName;
+        }
+
+        /// <summary>
+        /// Arguments to javascript
+        /// </summary>
+        /// <seealso cref="Arguments"/>
+        public IList<string> Args
+        {
+            get { return _arguments; }
+        }
+
+        public override string Command
+        {
+            get { return "jsrun"; }
+        }
+
+        /// <summary>
+        /// Args to the CmdBase api
+        /// </summary>
+        /// <seealso cref="Args"/>
+        public override string Arguments
+        {
+            get { return _scriptName + " " + JoinArguments(); }
+        }
+
+        public override CommandReply CreateReply(string dataToParse)
+        {
+            if (dataToParse == "OK")
+                return new CommandReply(true);
+            else
+            {
+                CommandReply reply = new CommandReply(false);
+                reply.ErrCode = dataToParse;
+                return reply;
+            }
+        }
+
+        private string JoinArguments()
+        {
+            string args = string.Empty;
+            foreach (string arg in Args)
+                args += arg + " ";
+            return args;
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/GetVariable.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/GetVariable.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket.Commands
+{
+    public class GetVariable : Api
+    {
+        private readonly string _channelId;
+        private readonly string _name;
+
+        public GetVariable()
+        {
+            
+        }
+
+        public GetVariable(string uuid, string name)
+        {
+            _channelId = uuid;
+            _name = name;
+        }
+
+        public override string Command
+        {
+            get { return "uuid_getvar"; }
+        }
+
+        public override string Arguments
+        {
+            get { return _channelId + " " + _name; }
+        }
+
+        public override CommandReply CreateReply(string dataToParse)
+        {
+            if (dataToParse.Substring(0, 2) == "OK")
+            {
+                return new GetVariableReply(true, dataToParse.Substring(3));
+            }
+            else
+            {
+                GetVariableReply reply = new GetVariableReply(false, string.Empty);
+                reply.ErrCode = dataToParse;
+                return reply;
+            }
+        }
+    }
+
+
+    public class GetVariableReply : CommandReply
+    {
+        private string _value;
+
+        public GetVariableReply(bool success, string value)
+            : base(success)
+        {
+            _value = value;
+        }
+
+        public string SessionId
+        {
+            get { return _value; }
+        }
+
+        public string Value
+        {
+            get { return _value; }
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/HoldCmd.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/HoldCmd.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,29 @@
+namespace FreeSwitch.EventSocket.Commands
+{
+    public class HoldCmd : Api
+    {
+        private readonly string _sessionId;
+        private readonly bool _activate;
+
+        public HoldCmd(string sessionId, bool activate)
+        {
+            _sessionId = sessionId;
+            _activate = activate;
+        }
+
+        public override string Command
+        {
+            get { return "hold"; }
+        }
+
+        public override string Arguments
+        {
+            get { return (_activate ? string.Empty : "off ") + _sessionId; }
+        }
+
+        public override CommandReply CreateReply(string dataToParse)
+        {
+            return base.CreateReply(dataToParse);
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Originate.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Originate.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,108 @@
+using System.Collections.Generic;
+using FreeSwitch.EventSocket.General;
+
+namespace FreeSwitch.EventSocket.Commands
+{
+    public class OriginateReply : CommandReply
+    {
+        private readonly string _sessionId;
+
+        public OriginateReply(bool success, string sessionId) : base(success)
+        {
+            _sessionId = sessionId;
+        }
+
+        public string SessionId
+        {
+            get { return _sessionId; }
+        }
+    }
+
+    public class Originate : Api
+    {
+        private SofiaSipAddress _caller;
+        private Address _destination;
+        private readonly IList<ChannelVariable> _variables = new List<ChannelVariable>();
+        private string _callerIdName = null;
+        private string _callerIdNumber = null;
+
+        public Originate()
+        {}
+
+        public Originate(SofiaSipAddress caller, Address destination)
+        {
+            _caller = caller;
+            _destination = destination;
+        }
+
+        public SofiaSipAddress Caller
+        {
+            get { return _caller; }
+            set { _caller = value; }
+        }
+
+        public Address Destination
+        {
+            get { return _destination; }
+            set { _destination = value; }
+        }
+
+        public IList<ChannelVariable> Variables
+        {
+            get { return _variables; }
+        }
+
+        public string CallerIdNumber
+        {
+            get { return _callerIdNumber; }
+            set { _callerIdNumber = value; }
+        }
+
+        public string CallerIdName
+        {
+            get { return _callerIdName; }
+            set { _callerIdName = value; }
+        }
+
+        public override string Command
+        {
+            get { return "originate"; }
+        }
+
+        public override string Arguments
+        {
+            get
+            {
+                _variables.Add(new ChannelVariable("origination_caller_id_name", CallerIdName ?? _caller.Extension));
+                if (!string.IsNullOrEmpty(_callerIdNumber))
+                    _variables.Add(new ChannelVariable("origination_caller_id_number", _callerIdNumber));
+
+                string variables = string.Empty;
+                foreach (ChannelVariable var in _variables)
+                    variables += var + ",";
+                if (variables.Length > 0)
+                    variables = "{" + variables.Remove(variables.Length - 1, 1) + "}";
+
+                return variables + Caller + " " + Destination;
+            }
+        }
+
+        public override CommandReply CreateReply(string dataToParse)
+        {
+            dataToParse = dataToParse.Replace(" ", string.Empty);
+            string[] nameValue = dataToParse.Split(':');
+            if (nameValue[0].ToLower() == "success")
+                return new OriginateReply(true, nameValue[1]);
+            else
+            {
+                OriginateReply reply = new OriginateReply(false, string.Empty);
+                if (nameValue.Length > 1)
+                    reply.ErrCode = nameValue[1];
+                else
+                    reply.ErrCode = dataToParse;
+                return reply;
+            }
+        }
+
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ParkCmd.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/ParkCmd.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,22 @@
+namespace FreeSwitch.EventSocket.Commands
+{
+    public class ParkCmd : Api
+    {
+        private readonly string _uuid;
+
+        public ParkCmd(string uuid)
+        {
+            _uuid = uuid;    
+        }
+
+        public override string Command
+        {
+            get { return "uuid_park"; }
+        }
+
+        public override string Arguments
+        {
+            get { return _uuid; }
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Playback.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/Playback.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,34 @@
+namespace FreeSwitch.EventSocket.Commands
+{
+    /// <summary>
+    /// Play a file
+    /// </summary>
+    public class PlaybackCmd : SendMsg
+    {
+        private readonly string _fileName;
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="uuid">channel identifier</param>
+        /// <param name="fileName">Path and filename to sound file</param>
+        /// <remarks>Path should be relative to FS path.</remarks>
+        /// <example>
+        /// mgr.SendApi(new PlaybackCmd(evt.UniqueId, "sounds\\sv\\welcome.wav", PlaybackCmd.All));
+        /// </example>
+        public PlaybackCmd(string uuid, string fileName) : base(uuid)
+        {
+            _fileName = fileName;
+        }
+
+        public override string Command
+        {
+            get { return "playback"; }
+        }
+
+        public override string Arguments
+        {
+            get { return _fileName; }
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/RecordCmd.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/RecordCmd.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,72 @@
+using System;
+
+namespace FreeSwitch.EventSocket.Commands
+{
+    public class RecordCmd : Api
+    {
+        //<uuid> [start|stop] <path> [<limit>]
+        private readonly string _uuid;
+        private readonly bool _start;
+        private readonly string _path;
+        private readonly int _limit;
+
+        /// <param name="uuid">channel id</param>
+        /// <param name="path">FS relative path to sound file</param>
+        public RecordCmd(string uuid, string path)
+        {
+            if (string.IsNullOrEmpty(uuid))
+                throw new ArgumentException("uuid");
+            if (string.IsNullOrEmpty(path))
+                throw new ArgumentException("path");
+
+            _uuid = uuid;
+            _path = path;
+        }
+
+        /// <param name="uuid">channel id</param>
+        /// <param name="path">FS relative path to sound file</param>
+        /// <param name="limit">number of seconds that maximum can be recorded.</param>
+        public RecordCmd(string uuid, string path, int limit)
+        {
+            if (string.IsNullOrEmpty(uuid))
+                throw new ArgumentException("uuid");
+            if (string.IsNullOrEmpty(path))
+                throw new ArgumentException("path");
+
+            _uuid = uuid;
+            _path = path;
+            _limit = limit;
+        }
+
+        /// <param name="uuid">channel id</param>
+        /// <param name="path">FS relative path to sound file</param>
+        /// <param name="stop">stop the recording if true</param>
+        public RecordCmd(string uuid, string path, bool stop) : this(uuid, path)
+        {
+            _start = !stop;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="uuid">channel id</param>
+        /// <param name="path">FS relative path to sound file</param>
+        /// <param name="stop">stop the recording if true</param>
+        /// <param name="limit">number of seconds that maximum can be recorded.</param>
+        public RecordCmd(string uuid, string path, bool stop, int limit)
+            : this(uuid, path, limit)
+        {
+            _start = !stop;
+        }
+
+        public override string Command
+        {
+            get { return "uuid_record"; }
+        }
+
+        public override string Arguments
+        {
+            get { return _uuid + (_start ? "start" : "stop") + " " + _path + " " + _limit; }
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SendMsg.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SendMsg.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,26 @@
+namespace FreeSwitch.EventSocket.Commands
+{
+    public abstract class SendMsg : CmdBase
+    {
+        private readonly string _uuid;
+        private readonly string _callCommand = "execute";
+
+        public SendMsg(string uuid)
+        {
+            _uuid = uuid;
+        }
+
+        public SendMsg(string uuid, string callCommand)
+        {
+            _callCommand = callCommand;
+            _uuid = uuid;
+        }
+
+        public override string ToString()
+        {
+            return
+                string.Format("SendMsg {0}\ncall-command: {1}\nexecute-app-name: {2}\nexecute-app-arg: {3}\n", _uuid,
+                              _callCommand, Command, Arguments);
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SetVariable.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SetVariable.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,44 @@
+namespace FreeSwitch.EventSocket.Commands
+{
+    public class SetVariable : Api
+    {
+        private readonly string _channelId;
+        private readonly string _name;
+        private readonly string _value;
+
+        public SetVariable()
+        {
+            
+        }
+
+        public SetVariable(string uuid, string name, string value)
+        {
+            _channelId = uuid;
+            _name = name;
+            _value = value;
+        }
+
+        public override string Command
+        {
+            get { return "uuid_setvar"; }
+        }
+
+        public override string Arguments
+        {
+            get { return _channelId + " " + _name + " " + _value; }
+        }
+
+        public override CommandReply CreateReply(string dataToParse)
+        {
+            if (dataToParse == "OK")
+                return new CommandReply(true);
+            else
+            {
+                CommandReply reply = new CommandReply(false);
+                reply.ErrCode = dataToParse;
+                return reply;
+            }
+        }
+
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SleepCmd.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/SleepCmd.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,22 @@
+namespace FreeSwitch.EventSocket.Commands
+{
+    public class SleepCmd : SendMsg
+    {
+        private readonly int _ms;
+
+        public SleepCmd(string uuid, int ms) : base(uuid)
+        {
+            _ms = ms;
+        }
+
+        public override string Command
+        {
+            get { return "sleep"; }
+        }
+
+        public override string Arguments
+        {
+            get { return _ms.ToString(); }
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/TransferCmd.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Commands/TransferCmd.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,36 @@
+namespace FreeSwitch.EventSocket.Commands
+{
+    public class TransferCmd : PbxCommand
+    {
+        private readonly string _sessionId;
+        private readonly string _destination;
+
+        /// <summary>
+        /// Transfer a call to somewhere.
+        /// </summary>
+        /// <param name="sessionId"></param>
+        /// <param name="destination"></param>
+        public TransferCmd(string sessionId, string destination)
+        {
+            _sessionId = sessionId;
+            _destination = destination;
+        }
+
+        public override PbxCommandReply CreateReply(string dataToParse)
+        {
+            if (dataToParse == "OK")
+                return new PbxCommandReply(true);
+            else
+            {
+                PbxCommandReply reply = new PbxCommandReply(false);
+                reply.ErrCode = dataToParse;
+                return reply;
+            }
+        }
+
+        public override string ToString()
+        {
+            return "transfer " + _sessionId + " " + _destination;
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventManager.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventManager.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,143 @@
+using System;
+using System.Collections.Specialized;
+using System.IO;
+using FreeSwitch.EventSocket.Commands;
+
+namespace FreeSwitch.EventSocket
+{
+    public delegate void EventHandler(EventBase receivedEvent);
+
+    public delegate void EventsWriter(string text);
+
+    public class EventManager
+    {
+        private readonly EventSocket _socket = new EventSocket();
+        public event EventHandler EventReceived;
+        private EventsWriter _writer;
+        private TextWriter _myWriter;
+        public string Password
+        {
+            set { _socket.Password = value; }
+        }
+
+        public EventManager()
+        {
+            _writer = MyWriter;
+            _myWriter = new StreamWriter(new FileStream("C:\\temp\\WatcherRow.log", FileMode.Create, FileAccess.Write, FileShare.ReadWrite));
+        }
+
+        private void MyWriter(string text)
+        {
+            _myWriter.Write(text);
+        }
+
+
+        public EventManager(EventsWriter writer)
+        {
+            _writer = writer;
+        }
+
+        public void Start(string hostname)
+        {
+            _socket.MessageReceived += OnMessage;
+            _socket.Connect(hostname);
+            _socket.DataReceived += OnData;
+        }
+
+        private void OnData(string data)
+        {
+            _writer(data);
+        }
+
+        /// <summary>
+        /// Send a command to the server.
+        /// </summary>
+        /// <param name="cmd"></param>
+        /// <exception cref="IOException">If socket is not connected</exception>
+        /// <exception cref="InvalidOperationException"></exception>
+        /// <exception cref="ObjectDisposedException"></exception>
+        public void Send(CmdBase cmd)
+        {
+            _socket.Send(cmd);
+        }
+
+        public void Send(SendMsg cmd)
+        {
+            _socket.Send(cmd);
+        }
+
+        protected void OnMessage(PlainEventMsg msg)
+        {
+            NameValueCollection parameters = msg.BodyToNameValue(true);
+            string eventName = parameters["event-name"];
+            if (eventName == null)
+                return;
+
+            if (string.Compare(parameters["event-name"], "custom", true) == 0)
+                eventName = parameters["event-subclass"];
+            else
+                eventName = parameters["event-name"];
+
+            //Quickhack for Sofia::Register (convert to sofia_register)
+            eventName = eventName.Replace("::", "_");
+            eventName = StringHelper.UpperCaseToCamelCase(eventName);
+
+            // Try to load the event (check if we've created an event class for the registered event)
+            EventBase eb = EventBase.CreateEvent(eventName);
+
+            // Yep, we got an event class. Let it parse the event information
+            if (eb != null)
+            {
+                eb.SetParameters(parameters);
+                eb.Parse(parameters);
+                if (EventReceived != null)
+                    EventReceived(eb);
+
+                /*
+                EventChannelState channel = eb as EventChannelState;
+                if (channel != null)
+                {
+                    Console.WriteLine("[" + eb.Name + "/" + channel.ChannelInfo.State + "] (uid: " +
+                                      channel.UniqueId + ")");
+                    Console.WriteLine("  ChannelInfo:");
+                    Console.WriteLine("    Name: " + channel.ChannelInfo.Name);
+                    Console.WriteLine("    State: " + channel.ChannelInfo.State);
+                    if (channel.Caller != null)
+                    {
+                        Console.WriteLine("  CallerInfo:");
+                        Console.WriteLine("    Id: " + channel.Caller.UniqueId);
+                        Console.WriteLine("    UserName: " + channel.Caller.UserName);
+                        Console.WriteLine("    CallerId: " + channel.Caller.CallerIdName + "/" +
+                                          channel.Caller.CallerIdNumber);
+                        Console.WriteLine("    ChannelName: " + channel.Caller.ChannelName);
+                        Console.WriteLine("    DestinationNumber: " + channel.Caller.DestinationNumber);
+                    }
+
+                    if (channel.Originator != null)
+                    {
+                        Console.WriteLine("  Originator:");
+                        Console.WriteLine("    Id: " + channel.Originator.UniqueId);
+                        Console.WriteLine("    UserName: " + channel.Originator.UserName);
+                        Console.WriteLine("    CallerId: " + channel.Originator.CallerIdName + "/" +
+                                          channel.Originator.CallerIdNumber);
+                        Console.WriteLine("    ChannelName: " + channel.Originator.ChannelName);
+                        Console.WriteLine("    DestinationNumber: " + channel.Originator.DestinationNumber);
+                    }
+                }
+                //}*/
+            }
+            else
+                Console.WriteLine("* Failed to load '" + eventName + "'.");
+        }
+
+        public void Subscribe(Events events)
+        {
+            _socket.Subscribe(events);
+        }
+
+        public void Subscribe(params Event[] events)
+        {
+            _socket.Subscribe(new Events(events));
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventParser.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventParser.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,99 @@
+using EventSocketParser;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventParser
+    {
+        private PlainEventMsg _msg;
+        private readonly StringParser _parser;
+
+        public EventParser(string text)
+        {
+            _parser = new StringParser(text);
+        }
+
+        public PlainEventMsg ParseMessage()
+        {
+            _parser.ClearSavedPositions();
+            _msg = new PlainEventMsg();
+
+            // Save pos if we cant parse the whole message
+            _parser.SavePos();
+
+            ReadHeader();
+            if (!_msg.ValidateHeader())
+            {
+                _parser.RestorePos();
+                return null;
+            }
+
+            // skip empty line between body and header
+            _parser.ReadLine(true);
+
+            // we got no body.
+            if (_msg.ContentLength == -1)
+                return _msg;
+
+            // Unfortunately, \n\n doesnt appear after all content.
+            if (_msg.ContentLength != 0)
+                _msg.Body = _parser.Read(_msg.ContentLength);
+            else
+                _msg.Body = _parser.ReadToEmptyLine();
+
+            // assume that we have not got a complete packet yet.
+            if (!_msg.Validate())
+            {
+                _parser.RestorePos();
+                return null;
+            }
+
+            return _msg;
+        }
+
+        public bool ReadHeader()
+        {
+            // skip empty lines
+            while (!_parser.EOF && _parser.PeekWord(true, true) == string.Empty)
+                _parser.ReadLine(false);
+
+            if (_parser.EOF)
+                return false;
+
+            string name = _parser.Read(':', true);
+            while (name != string.Empty)
+            {
+                switch (name)
+                {
+                    case "Content-Length":
+                        _msg.ContentLength = int.Parse(_parser.ReadLine(true));
+                        break;
+                    case "Content-Type":
+                        _msg.ContentType = _parser.ReadLine(true);
+                        break;
+                    case "Reply-Text":
+                        _msg.Body = _parser.ReadLine();
+                        break;
+                }
+
+                // empty line == end of header
+                if (_parser.EOL)
+                    break;
+
+                name = _parser.Read(':', true);
+            }
+
+            return _msg.ContentType != string.Empty;
+        }
+
+        public void Append(string value)
+        {
+            _parser.RemoveUsedContent();
+            _parser.Append(value);
+        }
+
+        public void Clear()
+        {
+            _parser.Clear();
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,298 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using FreeSwitch.EventSocket.Commands;
+
+namespace FreeSwitch.EventSocket
+{
+    public delegate void MessageHandler(PlainEventMsg msg);
+
+    public class EventSocket
+    {
+        #region Delegates
+
+        public delegate void EventSocketHandler(EventSocket client);
+
+        public delegate void DataHandler(string data);
+
+        #endregion
+
+        private readonly Queue<CmdBase> _commands = new Queue<CmdBase>();
+        private bool _autoConnect = true;
+        private Events _events;
+        private string _hostName;
+        private readonly EventParser _parser = new EventParser(string.Empty);
+        public event DataHandler DataReceived;
+        private string _password = "ClueCon";
+        private int _port = 8021;
+        private object _lockobj = new object();
+        private readonly byte[] _readBuffer = new byte[8192];
+        private string _temp = string.Empty;
+        private Socket _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+        private NetworkStream _stream;
+        private Timer _timer;
+        private bool _authed = false;
+        const int RetryTimeout = 5000;
+
+        public string Password
+        {
+            get { return _password; }
+            set { _password = value; }
+        }
+
+        public bool AutoConnect
+        {
+            get { return _autoConnect; }
+            set { _autoConnect = value; }
+        }
+
+        public event MessageHandler MessageReceived;
+
+        public event EventSocketHandler Disconnected;
+        public event EventSocketHandler Connected;
+
+        public void Connect(string server)
+        {
+            int pos = server.IndexOf(':');
+            if (pos == -1)
+                _hostName = server;
+            else
+            {
+                _port = int.Parse(server.Substring(pos + 1));
+                _hostName = server.Substring(0, pos);
+            }
+
+            Connect();
+        }
+
+        public void Connect()
+        {
+            if (_hostName == null)
+                throw new InvalidOperationException("Must call the other Connect method first to set hostname/port.");
+
+            try
+            {
+                TryConnect();
+            }
+            catch (SocketException)
+            {
+                Console.WriteLine("EventSocket: Connect failed");
+                HandleDisconnect();
+            }
+        }
+
+        private void TryConnect()
+        {
+            lock (_lockobj)
+            {
+                Console.WriteLine("EventSocket.TryConnect: Connecting to " + _hostName + ":" + _port);
+                
+                _socket.Connect(_hostName, _port);
+                if (_stream == null)
+                    _stream = new NetworkStream(_socket, false);
+
+                if (Connected != null)
+                    Connected(this);
+                BeginRead();
+
+                if (_timer != null)
+                {
+                    Timer tmr = _timer;
+                    _timer = null;
+                    tmr.Change(Timeout.Infinite, Timeout.Infinite);
+                    tmr.Dispose();
+                }
+            }
+        }
+
+        private void BeginRead()
+        {
+            _stream.BeginRead(_readBuffer, 0, _readBuffer.Length, OnReadCompleted, null);
+        }
+
+        private void OnReadCompleted(IAsyncResult ar)
+        {
+            int bytesRead;
+            try
+            {
+                bytesRead = _stream.EndRead(ar);
+                if (bytesRead == 0)
+                {
+                    HandleDisconnect();
+                    return;
+                }
+            }
+            catch (IOException)
+            {
+                // Remote end disconnected.
+                HandleDisconnect();
+                return;
+            }
+
+            string text = Encoding.ASCII.GetString(_readBuffer, 0, bytesRead);
+            if (DataReceived != null)
+                DataReceived(text);
+            _temp += text;
+            _parser.Append(text);
+            ParseMessages();
+
+            _stream.BeginRead(_readBuffer, 0, _readBuffer.Length, OnReadCompleted, null);
+        }
+
+        /// <summary>
+        /// Subscribe on the specified events.
+        /// </summary>
+        /// <param name="events">The events.</param>
+        public void Subscribe(Events events)
+        {
+            _events = events;
+            if (_socket.Connected && _authed)
+                RequestEvents();
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="s"></param>
+        /// <exception cref="InvalidOperationException"></exception>
+        /// <exception cref="ObjectDisposedException"></exception>
+        private void Write(string s)
+        {
+            if (_socket == null)
+                return;
+            if (!_socket.Connected)
+            {
+                try
+                {
+                    Console.WriteLine("EventSocket.Write: Trying to connect eventsocket.");
+                    TryConnect();
+                    Console.WriteLine("EventSocket.Write: Connected.");
+                }
+                catch (SocketException)
+                {
+                    return;
+                }
+            }
+
+            byte[] bytes = Encoding.ASCII.GetBytes(s);
+            _stream.Write(bytes, 0, bytes.Length);
+        }
+
+        private void ParseMessages()
+        {
+            PlainEventMsg msg = _parser.ParseMessage();
+            while (msg != null)
+            {
+                if (msg.ContentType == "auth/request")
+                {
+                    AuthCommand cmd = new AuthCommand(_password);
+                    cmd.OnReply += OnAuthed;
+                    _commands.Enqueue(cmd);
+                    Write(cmd + "\n\n");
+                }
+                else if (msg.ContentType == "command/reply"
+                         || msg.ContentType == "api/response")
+                {
+                    if (_commands.Count > 0)
+                    {
+                        CmdBase cmd = _commands.Dequeue();
+                        Console.WriteLine("Reply to " + cmd.GetType().Name + ": " + msg.Body);
+                        cmd.HandleReply(cmd.CreateReply(msg.Body));
+                    }
+                    else
+                    {
+                        Console.ForegroundColor = ConsoleColor.Red;
+                        Console.WriteLine("Got command reply or api response, but no actual command/api: " + msg.Body);
+                        Console.ForegroundColor = ConsoleColor.Gray;
+                    }
+                }
+                else
+                {
+                    if (MessageReceived != null)
+                        MessageReceived(msg);
+                }
+                msg = _parser.ParseMessage();
+            }
+        }
+
+        private void OnAuthed(CmdBase command, CommandReply reply)
+        {
+            _authed = true;
+            RequestEvents();
+        }
+
+        private void HandleDisconnect()
+        {
+            _parser.Clear();
+            _authed = false;
+            _socket.Close();
+            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+            if (_stream != null)
+            {
+                _stream.Dispose();
+                _stream = null;
+            }
+
+            if (Disconnected != null)
+                Disconnected.Invoke(this);
+            if (AutoConnect && _timer == null)
+            {
+                Console.WriteLine("EventSocket: Launching timer.");
+                _timer = new Timer(TryConnect, this, RetryTimeout, RetryTimeout);
+            }
+        }
+
+        private void RequestEvents()
+        {
+            if (_events.Count <= 0 && _authed)
+                return;
+
+            Write("event plain " + GetEventString() + "\n\n");
+        }
+
+        private string GetEventString()
+        {
+            string events = string.Empty;
+            for (int i = 0; i < _events.Count; ++i)
+                events += StringHelper.CamelCaseToUpperCase(_events[i].ToString()) + " ";
+            return events;
+        }
+
+        /// <summary>
+        /// Send a command to FreeSwitch.
+        /// Do you want a response? Then use the delegate in the Command class.
+        /// </summary>
+        /// <param name="command">Command to send.</param>
+        /// <exception cref="IOException">If socket is not connected.</exception>
+        /// <exception cref="InvalidOperationException"></exception>
+        /// <exception cref="ObjectDisposedException"></exception>
+        public void Send(CmdBase command)
+        {
+            if (!_socket.Connected)
+                throw new IOException("Socket is not connected.");
+
+            _commands.Enqueue(command);
+
+            // All commands need replies.
+            Write(command + "\n\n");
+        }
+
+        private static void TryConnect(object state)
+        {
+            EventSocket client = (EventSocket) state;
+            try
+            {
+                Console.WriteLine("EventSocket.Timer: Trying to connect eventsocket.");
+                client.TryConnect();
+                Console.WriteLine("EventSocket.Timer: Connected.");
+            }
+            catch (SocketException err)
+            {
+                Console.WriteLine("Eventsocket.TryConnect: " + err.Message);
+            }
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/EventSocket.pfx
==============================================================================
Binary file. No diff available.

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,107 @@
+using System.Collections.Generic;
+
+namespace FreeSwitch.EventSocket
+{
+    #region Event enum
+    public enum Event
+    {
+        Custom,
+        ChannelCreate,
+        ChannelDestroy,
+        ChannelState,
+        ChannelAnswer,
+        ChannelApplication,
+        ChannelHangup,
+        ChannelExecute,
+        ChannelExecuteComplete,
+        ChannelBridge,
+        ChannelUnbridge,
+        ChannelProgress,
+        ChannelOriginate,
+        ChannelOutgoing,
+        ChannelPark,
+        ChannelUnpark,
+        Api,
+        Log,
+        InboundChan,
+        OutboundChan,
+        Startup,
+        Shutdown,
+        Publish,
+        Unpublish,
+        Talk,
+        Notalk,
+        SessionCrash,
+        ModuleLoad,
+        Dtmf,
+        Message,
+        PresenceIn,
+        PresenceOut,
+        PresenceProbe,
+        SofiaRegister,
+        SofiaExpires,
+        Roster,
+        Codec,
+        BackgroundJob,
+        DetectedSpeech,
+        PrivateCommand,
+        Heartbeat,
+        All
+    }
+    #endregion
+
+    #region Events class
+    public class Events
+    {
+        private IList<Event> m_events = new List<Event>();
+
+        public Events() { }
+        public Events(params Event[] parameters)
+        {
+            foreach (Event e in parameters)
+            {
+                Add(e);
+            }
+        }
+
+        public void Add(Event e)
+        {
+            m_events.Add(e);
+        }
+
+        public Event this[int index]
+        {
+            get { return m_events[index]; }
+        }
+
+        public void Clear()
+        {
+            m_events.Clear();
+        }
+
+        public int Count
+        {
+            get { return m_events.Count; }
+        }
+
+        public static Events GetChannelEvents()
+        {
+            Events e = new Events();
+            e.Add(Event.ChannelAnswer);
+            e.Add(Event.ChannelBridge);
+            e.Add(Event.ChannelCreate);
+            e.Add(Event.ChannelDestroy);
+            e.Add(Event.ChannelExecute);
+            e.Add(Event.ChannelHangup);
+            e.Add(Event.ChannelOutgoing);
+            e.Add(Event.ChannelPark);
+            e.Add(Event.ChannelProgress);
+            e.Add(Event.ChannelState);
+            e.Add(Event.ChannelUnbridge);
+            e.Add(Event.ChannelUnpark);
+            return e;
+        }
+    }
+    #endregion
+
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventApiCommand.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventApiCommand.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    class EventApiCommand : EventBase
+    {
+        private string m_command;
+
+        public override bool ParseCommand(string name, string value)
+        {
+            switch (name)
+            {
+                case "api-command":
+                    m_command = value;
+                    break;
+                default:
+                    return base.ParseCommand(name, value);
+            }
+
+            return true;
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventBase.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventBase.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,139 @@
+using System;
+using System.Collections.Specialized;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventBase
+    {
+        private string m_callingFile;
+        private string m_callingFunction;
+        private int m_callingLineNumber;
+        private string m_coreId;
+        private DateTime m_dateGMT;
+        private DateTime m_dateLocal;
+        private string m_name;
+        private readonly NameValueCollection _parameters = new NameValueCollection();
+        private NameValueCollection _allParameters;
+
+        #region Properties
+
+        public string Name
+        {
+            get { return m_name; }
+            set { m_name = value; }
+        }
+
+        public string CoreId
+        {
+            get { return m_coreId; }
+            set { m_coreId = value; }
+        }
+
+        public DateTime DateLocal
+        {
+            get { return m_dateLocal; }
+            set { m_dateLocal = value; }
+        }
+
+        public DateTime DateGMT
+        {
+            get { return m_dateGMT; }
+            set { m_dateGMT = value; }
+        }
+
+        public string CallingFile
+        {
+            get { return m_callingFile; }
+            set { m_callingFile = value; }
+        }
+
+        public string CallingFunction
+        {
+            get { return m_callingFunction; }
+            set { m_callingFunction = value; }
+        }
+
+        public int CallingLineNumber
+        {
+            get { return m_callingLineNumber; }
+            set { m_callingLineNumber = value; }
+        }
+
+        #endregion
+
+        public virtual bool IsChannelEvent
+        {
+            get { return false; }
+        }
+
+        public NameValueCollection Parameters
+        {
+            get { return _parameters; }
+        }
+
+        public NameValueCollection AllParameters
+        {
+            get { return _allParameters; }
+        }
+
+        internal void SetParameters(NameValueCollection allparams)
+        {
+            _allParameters = allparams;
+        }
+
+        public void Parse(NameValueCollection variables)
+        {
+            for (int i = 0; i < variables.Count; ++i)
+                ParseCommand(variables.GetKey(i), variables.Get(i));
+        }
+
+        public static EventBase CreateEvent(string eventName)
+        {
+            try
+            {
+                string eventNamea = "Event" + eventName;
+                Type t = Type.GetType("FreeSwitch.EventSocket.Event" + eventName);
+                if (t == null)
+                    return null;
+                return (EventBase) Activator.CreateInstance(t);
+            }
+            catch (TypeLoadException)
+            {
+                return null;
+            }
+        }
+
+        public virtual bool ParseCommand(string name, string value)
+        {
+            switch (name)
+            {
+                case "event-name":
+                    m_name = value;
+                    break;
+                case "core-uuid":
+                    m_coreId = value;
+                    break;
+                case "event-date-local":
+                    m_dateLocal = DateTime.Parse(value);
+                    break;
+                case "event-date-gmt":
+                    m_dateGMT = DateTime.Parse(value);
+                    break;
+                case "event-calling-file":
+                    m_callingFile = value;
+                    break;
+                case "event-calling-function":
+                    m_callingFunction = value;
+                    break;
+                case "event-calling-line-number":
+                    int.TryParse(value, out m_callingLineNumber);
+                    break;
+                default:
+                    Parameters.Add(name, value);
+                    //Console.WriteLine(m_name + ", Unhandled parameter: [" + name + "] " + value);
+                    return false;
+            }
+            return true;
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventHeartbeat.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventHeartbeat.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,57 @@
+namespace FreeSwitch.EventSocket
+{
+    class EventHeartbeat : EventBase
+    {
+        private string _info;
+        private string _upTime;
+        private int _sessionCount;
+
+        public string Info
+        {
+            get { return _info; }
+            set { _info = value; }
+        }
+
+        public string UpTime
+        {
+            get { return _upTime; }
+            set { _upTime = value; }
+        }
+
+        public int SessionCount
+        {
+            get { return _sessionCount; }
+            set { _sessionCount = value; }
+        }
+
+        public override bool ParseCommand(string name, string value)
+        {
+            switch (name)
+            {
+                case "event-info":
+                    Info = value;
+                    break;
+                case "up-time":
+                    UpTime = value;
+                    break;
+                case "session-count":
+                    int.TryParse(value, out _sessionCount);
+                    break;
+
+                default:
+                    return base.ParseCommand(name, value);
+            }
+
+            return true;
+
+        }
+    }
+
+/*
+ Event-Info: System%20Ready
+Up-Time: 0%20years,%200%20days,%201%20hour,%2048%20minutes,%207%20seconds,%20265
+%20milliseconds,%20625%20microseconds%0A
+Session-Count: 0
+Event-Name: HEARTBEAT
+ */
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventMessageQuery.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventMessageQuery.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class EventMessageQuery : EventBase
+    {
+        private string _account;
+
+        public string Account
+        {
+            get { return _account; }
+            set { _account = value; }
+        }
+
+        public override bool ParseCommand(string name, string value)
+        {
+            if (name == "message-account")
+                Account = value;
+            else
+                return base.ParseCommand(name, value);
+
+            return true;
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventMessageWaiting.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventMessageWaiting.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,133 @@
+namespace FreeSwitch.EventSocket
+{
+    public class EventMessageWaiting : EventBase
+    {
+        private string _account;
+        private int _newMessages;
+        private int _newUrgentMessages;
+        private int _totalMessages;
+        private int _totalUrgentMessages;
+
+        /// <summary>
+        /// Messages are for this account
+        /// </summary>
+        public string Account
+        {
+            get { return _account; }
+            set { _account = value; }
+        }
+
+        /// <summary>
+        /// Total count of messages
+        /// </summary>
+        public bool MessagesWaiting
+        {
+            get { return _newMessages != 0 || _newUrgentMessages != 0; }
+        }
+
+        /// <summary>
+        /// Number of new messages
+        /// </summary>
+        public int NewMessages
+        {
+            get { return _newMessages; }
+            set { _newMessages = value; }
+        }
+
+        /// <summary>
+        /// Number of new urgent messages
+        /// </summary>
+        public int NewUrgentMessages
+        {
+            get { return _newUrgentMessages; }
+            set { _newUrgentMessages = value; }
+        }
+
+        /// <summary>
+        /// Total number of new/saved/old messages
+        /// </summary>
+        public int TotalMessages
+        {
+            get { return _totalMessages; }
+            set { _totalMessages = value; }
+        }
+
+        /// <summary>
+        /// Total number of new urgent messages
+        /// </summary>
+        public int TotalUrgentMessages
+        {
+            get { return _totalUrgentMessages; }
+            set { _totalUrgentMessages = value; }
+        }
+
+        public override bool ParseCommand(string name, string value)
+        {
+            switch (name)
+            {
+                case "mwi-messages-waiting":
+                    // are calculated by using voice messages
+                    break;
+                case "mwi-message-account":
+                    _account = value;
+                    break;
+                case "mwi-voice-message":
+                    return ParseVoiceMessages(value);
+                default:
+                    return base.ParseCommand(name, value);
+            }
+
+            return true;
+        }
+
+        private bool ParseVoiceMessages(string value)
+        {
+            /*
+             switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", 
+				total_new_messages, total_saved_messages, total_new_urgent_messages, total_saved_urgent_messages);
+             * */
+            int pos = value.IndexOf('/');
+            if (pos == -1)
+                return false;
+            if (!int.TryParse(value.Substring(0, pos), out _newMessages))
+                return false;
+
+            int oldPos = pos + 1;
+            pos = value.IndexOf(' ', pos);
+            if (pos == -1)
+                return false;
+            if (!int.TryParse(value.Substring(oldPos, pos - oldPos), out _totalMessages))
+                return false;
+
+            oldPos = pos + 2;
+            pos = value.IndexOf('/', pos);
+            if (pos == -1)
+                return false;
+            if (!int.TryParse(value.Substring(oldPos, pos - oldPos), out _newUrgentMessages))
+                return false;
+
+            oldPos = pos + 1;
+            pos = value.IndexOf(')', pos);
+            if (pos == -1)
+                return false;
+            if (!int.TryParse(value.Substring(oldPos, pos - oldPos), out _totalUrgentMessages))
+                return false;
+
+            return true;
+        }
+
+        public override string ToString()
+        {
+            string str = base.ToString();
+            str += "WMI-Messages-Waiting: " + (MessagesWaiting ? "yes" : "no") + "\n";
+            str += "WMI-Message-Account: " + _account + "\n";
+            if (_newUrgentMessages != 0 || _newMessages != 0)
+                str += string.Format("WMI-Voice-Message: {0}/{1} ({2}/{3})\n",
+                                     _newMessages,
+                                     _totalMessages,
+                                     _newMessages,
+                                     _totalUrgentMessages);
+            return str;
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventReSchedule.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Events/EventReSchedule.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    class EventReSchedule : EventBase
+    {
+        private int m_taskId;
+        private string m_description;
+        private string m_group;
+        private string m_runtime;
+
+        public int TaskId
+        {
+            get { return m_taskId; }
+            set { m_taskId = value; }
+        }
+
+        public string Description
+        {
+            get { return m_description; }
+            set { m_description = value; }
+        }
+
+        public string Group
+        {
+            get { return m_group; }
+            set { m_group = value; }
+        }
+
+        public string Runtime
+        {
+            get { return m_runtime; }
+            set { m_runtime = value; }
+        }
+
+        public override bool ParseCommand(string name, string value)
+        {
+            switch (name)
+            {
+                case "task-id":
+                    int.TryParse(value, out m_taskId);
+                    break;
+                case "task-desc":
+                    m_description = value;
+                    break;
+                case "task-group":
+                    m_group = value;
+                    break;
+                case "task-runtime":
+                    m_runtime = value;
+                    break;
+                default:
+                    return base.ParseCommand(name, value);
+            }
+
+            return true;
+
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/FreeSwitch.EventSocket.csproj
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/FreeSwitch.EventSocket.csproj	Thu May  1 14:27:39 2008
@@ -0,0 +1,123 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{3F8895F6-F710-4323-B96A-4EFB6BC97E08}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>FreeSwitch.EventSocket</RootNamespace>
+    <AssemblyName>FreeSwitch.EventSocket</AssemblyName>
+    <StartupObject>
+    </StartupObject>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>EventSocket.pfx</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+    <Reference Include="Tiny.Net, Version=1.0.0.1, Culture=neutral, PublicKeyToken=15480ee9e0247fcb, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\dlls\Debug\Tiny.Net.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ChannelEvents\EventChannelApplication.cs" />
+    <Compile Include="ChannelEvents\EventChannelExecuteComplete.cs" />
+    <Compile Include="ChannelEvents\EventChannelOriginate.cs" />
+    <Compile Include="ChannelEvents\EventChannelBridge.cs" />
+    <Compile Include="ChannelEvents\ChannelEvent.cs" />
+    <Compile Include="ChannelEvents\EventChannelAnswer.cs" />
+    <Compile Include="ChannelEvents\EventChannelProgress.cs" />
+    <Compile Include="ChannelEvents\EventChannelUnbridge.cs" />
+    <Compile Include="ChannelEvents\EventChannelUnpark.cs" />
+    <Compile Include="ChannelEvents\EventCodec.cs" />
+    <Compile Include="ChannelInfo.cs" />
+    <Compile Include="Commands\AnyCommand.cs">
+    </Compile>
+    <Compile Include="Commands\Api.cs" />
+    <Compile Include="Commands\AuthCommand.cs" />
+    <Compile Include="Commands\CmdBase.cs" />
+    <Compile Include="Commands\CommandReply.cs" />
+    <Compile Include="Commands\ExecuteJavascript.cs" />
+    <Compile Include="Commands\GetVariable.cs" />
+    <Compile Include="Commands\HoldCmd.cs" />
+    <Compile Include="Commands\Originate.cs" />
+    <Compile Include="Commands\ParkCmd.cs" />
+    <Compile Include="Commands\Playback.cs" />
+    <Compile Include="Commands\RecordCmd.cs" />
+    <Compile Include="Commands\SendMsg.cs" />
+    <Compile Include="Commands\SetVariable.cs" />
+    <Compile Include="Commands\SleepCmd.cs" />
+    <Compile Include="EventManager.cs" />
+    <Compile Include="ChannelEvents\EventDtmfStatus.cs" />
+    <Compile Include="Ivr\IvrInterface.cs" />
+    <Compile Include="PlainEventMsg.cs" />
+    <Compile Include="EventParser.cs" />
+    <Compile Include="Events.cs" />
+    <Compile Include="Events\EventApiCommand.cs" />
+    <Compile Include="Events\EventBase.cs" />
+    <Compile Include="ChannelEvents\EventChannelCreate.cs" />
+    <Compile Include="ChannelEvents\EventChannelDestroy.cs" />
+    <Compile Include="ChannelEvents\EventChannelExecute.cs" />
+    <Compile Include="ChannelEvents\EventChannelHangup.cs" />
+    <Compile Include="ChannelEvents\EventChannelOutgoing.cs" />
+    <Compile Include="ChannelEvents\EventChannelState.cs" />
+    <Compile Include="EventSocket.cs" />
+    <Compile Include="Events\EventHeartbeat.cs" />
+    <Compile Include="Events\EventReSchedule.cs" />
+    <Compile Include="General\Address.cs" />
+    <Compile Include="General\ChannelVariable.cs" />
+    <Compile Include="General\SipAddress.cs" />
+    <Compile Include="General\SofiaSipAddress.cs" />
+    <Compile Include="PartyInfo.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Events\EventMessageQuery.cs" />
+    <Compile Include="ChannelEvents\EventDtmf.cs" />
+    <Compile Include="SipEvents\EventPresenceIn.cs" />
+    <Compile Include="SipEvents\EventPresenceOut.cs" />
+    <Compile Include="SipEvents\EventPresenceProbe.cs" />
+    <Compile Include="SipEvents\EventRoster.cs" />
+    <Compile Include="Events\EventMessageWaiting.cs" />
+    <Compile Include="SipEvents\SipEvent.cs" />
+    <Compile Include="SipEvents\EventPresence.cs" />
+    <Compile Include="SipEvents\EventSofiaExpire.cs" />
+    <Compile Include="SipEvents\EventSofiaRegister.cs" />
+    <Compile Include="StringHelper.cs" />
+    <Compile Include="StringParser.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="EventSocket.pfx" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PostBuildEvent>copy $(TargetPath) $(SolutionDir)..\..\dlls\$(ConfigurationName)</PostBuildEvent>
+  </PropertyGroup>
+</Project>
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/Address.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/Address.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket.General
+{
+    public class Address
+    {
+        private string _extension;
+
+        public Address()
+        {
+            
+        }
+
+        public Address(string extension)
+        {
+            _extension = extension;
+        }
+
+        public string Extension
+        {
+            get { return _extension; }
+            set { _extension = value; }
+        }
+
+        public override string ToString()
+        {
+            return Extension;
+        }
+    }
+
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/ChannelVariable.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/ChannelVariable.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,33 @@
+namespace FreeSwitch.EventSocket.General
+{
+    /// <summary>
+    /// Channel variables are used in freeswitch to store information
+    /// that can be used by javascript programs.
+    /// </summary>
+    public class ChannelVariable
+    {
+        private readonly string _name;
+        private readonly string _value;
+
+        public ChannelVariable(string name, string value)
+        {
+            _name = name;
+            _value = value;
+        }
+
+        public string Name
+        {
+            get { return _name; }
+        }
+
+        public string Value
+        {
+            get { return _value; }
+        }
+
+        public override string ToString()
+        {
+            return _name + "=" + _value;
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/SipAddress.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/SipAddress.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket.General
+{
+    public class SipAddress : Address
+    {
+        private string _domain;
+
+        public SipAddress(string domain, string extension)
+            : base(extension)
+        {
+            _domain = domain;
+        }
+
+        public string Domain
+        {
+            get { return _domain; }
+            set { _domain = value; }
+        }
+
+        public override string ToString()
+        {
+            return Extension + "@" + Domain;
+        }
+
+        public static SipAddress Parse(string fullAddress)
+        {
+            string[] parts = fullAddress.Split('@');
+            if (parts.Length == 2)
+            {
+                return new SipAddress(parts[1], parts[0]);
+            }
+            return null;
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/SofiaSipAddress.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/General/SofiaSipAddress.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,44 @@
+namespace FreeSwitch.EventSocket.General
+{
+    public class SofiaSipAddress : Address
+    {
+        private readonly string _domain;
+
+        public SofiaSipAddress(string domain, string userName)
+        {
+            Extension = userName;
+            _domain = domain;
+        }
+
+        public SofiaSipAddress(SipAddress address)
+        {
+            _domain = address.Domain;
+            Extension = address.Extension;
+        }
+
+        public override string ToString()
+        {
+            return "sofia/mydomain.com/" + Extension + "%" + _domain;
+        }
+
+        public static SofiaSipAddress Parse(string fullAddress)
+        {
+            string[] parts = fullAddress.Split('@');
+            if (parts.Length == 2)
+            {
+                return new SofiaSipAddress(parts[1], parts[0]);
+            }
+            else
+            {
+                parts = fullAddress.Split('/');
+                if (parts.Length == 3)
+                {
+                    return new SofiaSipAddress(parts[1], parts[2]);
+                }
+            }
+
+            return null;
+            
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Ivr/IvrInterface.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Ivr/IvrInterface.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,212 @@
+using System;
+using System.Threading;
+using FreeSwitch.EventSocket.Commands;
+
+namespace FreeSwitch.EventSocket.Ivr
+{
+    public class IvrInterface
+    {
+        public const string AllDigits = "*#0123456789";
+        private readonly string _uuid;
+        private readonly string _baseSoundPath = "sounds\\";
+        private string _dtmf = string.Empty;
+        private EventManager _mgr;
+        public event DtmfHandler DtmfReceived;
+        private readonly int _dtmfWaitCount = 0;
+        private ManualResetEvent _dtmfWaitEvent;
+        private bool _abortSpeechOnDtmf;
+        private bool _answered;
+        private IvrInterfaceHandler _handler = null;
+        private string _lastAbortDigits = "*";
+
+        public IvrInterface(EventManager mgr, string uuid)
+        {
+            if (mgr == null)
+                throw new ArgumentNullException("mgr");
+            if (string.IsNullOrEmpty(uuid))
+                throw new ArgumentNullException("uuid");
+
+            _mgr = mgr;
+            mgr.EventReceived += OnEvent;
+            _uuid = uuid;
+
+            mgr.Send(new ParkCmd(uuid));
+        }
+
+        public IAsyncResult BeginInvoke(IvrInterfaceHandler handler, AsyncCallback callback, object state)
+        {
+            _handler = handler;
+            return handler.BeginInvoke(this, callback, state);
+        }
+
+        public void EndInvoke(IAsyncResult result)
+        {
+            if (_handler != null)
+                _handler.EndInvoke(result);
+        }
+
+        /// <summary>
+        /// dont play phrases as long as we have DTMF in the buffer.
+        /// </summary>
+        public bool AbortSpeechOnDtmf
+        {
+            get { return _abortSpeechOnDtmf; }
+            set { _abortSpeechOnDtmf = value; }
+        }
+
+        public bool Answered
+        {
+            get { return _answered; }
+        }
+
+        private void OnEvent(EventBase receivedEvent)
+        {
+            if (receivedEvent is EventChannelAnswer)
+            {
+                _answered = true;
+            }
+/*            else if (receivedEvent is EventDtmfStatus)
+            {
+                // Let's always dequeue dtmf.
+                EventDtmfStatus evt = (EventDtmfStatus) receivedEvent;
+                if (evt.UniqueId == _uuid)
+                    _mgr.Send(new GetDtmfCmd(_uuid, evt.Count));
+            }*/
+            else if (receivedEvent is EventDtmf)
+            {
+                EventDtmf evt = (EventDtmf) receivedEvent;
+                lock (_dtmf)
+                    _dtmf += evt.Digit;
+                if (_dtmfWaitCount >= _dtmf.Length)
+                    _dtmfWaitEvent.Set();
+
+                if (DtmfReceived != null)
+                    DtmfReceived(this, new DtmfEventArgs(_dtmf));
+            }
+            else if (receivedEvent is EventChannelDestroy || receivedEvent is EventChannelHangup)
+            {
+                if (_mgr != null)
+                {
+                    _mgr.EventReceived -= OnEvent;
+                    _mgr = null;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Wait on dtmf.
+        /// </summary>
+        /// <param name="count">Number of digits to get</param>
+        /// <param name="timeout">number of seconds to wait on all digits.</param>
+        /// <remarks>You can also used the Dtmf event if you want to use asynchrounous programming.</remarks>
+        /// <seealso cref="DtmfReceived"/>
+        public string GetDtmf(int count, int timeout)
+        {
+            if (_mgr == null)
+                return string.Empty;
+            if (_dtmfWaitEvent != null)
+                throw new InvalidOperationException("Already waiting on an event.");
+
+            if (_dtmf.Length < count)
+            {
+                _dtmfWaitEvent = new ManualResetEvent(false);
+                if (!_dtmfWaitEvent.WaitOne(timeout * 1000, true))
+                {
+                    _dtmf = string.Empty;
+                    return string.Empty;
+                }
+            }
+
+            lock (_dtmf)
+            {
+                if (_dtmf.Length >= count)
+                {
+                    string dtmf = _dtmf.Substring(0, count);
+                    _dtmf = _dtmf.Remove(count);
+                    return dtmf;
+                }
+            }
+
+            return string.Empty;
+        }
+
+        public void Play(string path, string digitsToAbortOn)
+        {
+            if (_mgr == null)
+                return;
+
+            if (_abortSpeechOnDtmf && _dtmf != string.Empty)
+                return;
+
+            if (digitsToAbortOn != _lastAbortDigits)
+            {
+                _mgr.Send(new SetVariable(_uuid, "playback_terminators", digitsToAbortOn));
+                _lastAbortDigits = digitsToAbortOn;
+            }
+
+            _mgr.Send(new PlaybackCmd(_uuid, _baseSoundPath + path));
+        }
+
+        public void Record(string path, bool stop, int limit)
+        {
+            if (_mgr == null)
+                return;
+            _mgr.Send(new RecordCmd(_uuid, _baseSoundPath + path, stop, limit));
+        }
+
+        public void Record(string path, int limit)
+        {
+            if (_mgr == null)
+                return;
+            _mgr.Send(new RecordCmd(_uuid, _baseSoundPath + path, limit));
+        }
+
+        public void Sleep(int ms)
+        {
+            if (_mgr == null)
+                return;
+            _mgr.Send(new SleepCmd(_uuid, ms));
+        }
+    }
+
+    public class DtmfEventArgs : EventArgs
+    {
+        private string _dtmf;
+        private string _dtmfCopy;
+
+        public DtmfEventArgs(string dtmf)
+        {
+            _dtmf = dtmf;
+            _dtmfCopy = (string) _dtmf.Clone();
+        }
+
+        /// <summary>
+        /// You cannot remove digits from the buffer (since it's a copy of the real buffer).
+        /// </summary>
+        /// <seealso cref="RemoveDigits"/>
+        public string Dtmf
+        {
+            get { return _dtmfCopy; }
+        }
+
+        /// <summary>
+        /// Remove digits from the real buffer.
+        /// </summary>
+        /// <param name="count">number of digits to remove.</param>
+        public void RemoveDigits(int count)
+        {
+            lock (_dtmf)
+            {
+                if (count > _dtmf.Length)
+                    _dtmf = string.Empty;
+                else
+                    _dtmf = _dtmf.Remove(0, count);
+                _dtmfCopy = (string)_dtmf.Clone();
+            }
+        }
+    }
+
+    public delegate void DtmfHandler(object source, DtmfEventArgs args);
+
+    public delegate void IvrInterfaceHandler(IvrInterface app);
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/PartyInfo.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/PartyInfo.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,150 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    public class PartyInfo
+    {
+        private string m_userName = string.Empty;
+        private string m_dialplan = string.Empty;
+        private string m_callerIdName = string.Empty;
+        private string m_callerIdNumber = string.Empty;
+        private string m_destinationNumber = string.Empty;
+        private string m_uniqueId = string.Empty;
+        private string m_source = string.Empty;
+        private string m_context = string.Empty;
+        private string m_channelName = string.Empty;
+        private bool m_screenBit;
+        private bool m_privacyHideName;
+        private bool m_privacyHideNumber;
+
+        public PartyInfo()
+        {
+            m_userName = string.Empty;
+            m_dialplan = string.Empty;
+            m_callerIdName = string.Empty;
+        }
+
+        public string Dialplan
+        {
+            get { return m_dialplan; }
+            set { m_dialplan = value; }
+        }
+
+        public string CallerIdName
+        {
+            get { return m_callerIdName; }
+            set { m_callerIdName = value; }
+        }
+
+        public string CallerIdNumber
+        {
+            get { return m_callerIdNumber; }
+            set { m_callerIdNumber = value; }
+        }
+
+        public string DestinationNumber
+        {
+            get { return m_destinationNumber; }
+            set { m_destinationNumber = value; }
+        }
+
+        public string UniqueId
+        {
+            get { return m_uniqueId; }
+            set { m_uniqueId = value; }
+        }
+
+        public string Source
+        {
+            get { return m_source; }
+            set { m_source = value; }
+        }
+
+        public string Context
+        {
+            get { return m_context; }
+            set { m_context = value; }
+        }
+
+        public string ChannelName
+        {
+            get { return m_channelName; }
+            set { m_channelName = value; }
+        }
+
+        public bool ScreenBit
+        {
+            get { return m_screenBit; }
+            set { m_screenBit = value; }
+        }
+
+        public bool PrivacyHideName
+        {
+            get { return m_privacyHideName; }
+            set { m_privacyHideName = value; }
+        }
+
+        public bool PrivacyHideNumber
+        {
+            get { return m_privacyHideNumber; }
+            set { m_privacyHideNumber = value; }
+        }
+
+        public string UserName
+        {
+            get { return m_userName; }
+            set { m_userName = value; }
+        }
+
+        public bool Parse(string name, string value)
+        {
+            switch (name)
+            {
+                case "username":
+                    m_userName = value;
+                    break;
+                case "dialplan":
+                    Dialplan = value;
+                    break;
+                case "caller-id-name":
+                    CallerIdName = value;
+                    break;
+                case "caller-id-number":
+                    CallerIdNumber = value;
+                    break;
+                case "destination-number":
+                    DestinationNumber = value;
+                    break;
+                case "unique-id":
+                    UniqueId = value;
+                    break;
+                case "source":
+                    Source = value;
+                    break;
+                case "context":
+                    Context = value;
+                    break;
+                case "channel-name":
+                    ChannelName = value;
+                    break;
+                case "screen-bit":
+                    ScreenBit = value == "yes";
+                    break;
+                case "privacy-hide-name":
+                    PrivacyHideName = value == "yes";
+                    break;
+                case "privacy-hide-number":
+                    PrivacyHideNumber = value == "yes";
+                    break;
+                default:
+                    return false;
+            }
+
+            return true;
+
+        }
+
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/PlainEventMsg.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/PlainEventMsg.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Specialized;
+using EventSocketParser;
+
+namespace FreeSwitch.EventSocket
+{
+    public class PlainEventMsg
+    {
+        private string _contentType = string.Empty;
+        private int _contentLength = -1;
+        private string _body = string.Empty;
+
+        public string ContentType
+        {
+            get { return _contentType; }
+            set { _contentType = value; }
+        }
+
+        public int ContentLength
+        {
+            get { return _contentLength; }
+            set { _contentLength = value; }
+        }
+
+        public string Body
+        {
+            get { return _body; }
+            set { _body = value; }
+        }
+
+        public bool ValidateHeader()
+        {
+            if (_contentType == string.Empty)
+                return false;
+            if (_contentType == "command/reply")
+                return _body != string.Empty;
+
+            return true;
+        }
+
+        public bool Validate()
+        {
+            if (!ValidateHeader())
+                return false;
+
+            if (_contentLength > 0)
+                return _contentLength == _body.Length || _contentLength == _body.Length + 2; // include first and last line breaks that we skip in parsing
+
+            return true;
+        }
+
+
+        public NameValueCollection BodyToNameValue(bool urlDecodeValues)
+        {
+            NameValueCollection items = new NameValueCollection();
+            StringParser parser = new StringParser(_body);
+            string name = parser.Read(':', true);
+            while (!parser.EOF && name != string.Empty)
+            {
+                string value = parser.ReadLine(true);
+                if (items[name] == null)
+                {
+                    try
+                    {
+                        items.Add(name.ToLower(), Uri.UnescapeDataString(value));
+                    }
+                    catch (UriFormatException) 
+                    {
+                        // add the value unformatted
+                        items.Add(name.ToLower(), value);
+                    }
+                }
+
+                name = parser.Read(':', true);
+            }
+
+            return items;
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Program.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Program.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using FreeSwitch.EventSocket;
+
+namespace FreeSwitch.EventSocket
+{
+    class Program
+    {
+        /// <summary>
+        /// This method is called by the event delegate.
+        /// </summary>
+        /// <param name="eb">Reference to an event, each event has their own class.</param>
+        void HandleEvent(EventBase eb)
+        {
+            //Console.WriteLine(eb.DateLocal + "  Got Event: " + eb.Name);
+
+
+            if (eb is EventChannelHangup)
+                Console.WriteLine(eb.DateLocal + " Hangup reason: " + ((EventChannelHangup)eb).Cause.ToString());
+        }
+
+        static void Main(string[] args)
+        {
+            Program p = new Program();
+
+            /// Create a new FreeSwitch event socket.
+            EventManager eventManager = new EventManager();
+
+            // Hook all events to the same delegate. Can also provide one delegate per event.
+            eventManager.EventReceived += p.HandleEvent;
+            eventManager.Subscribe(new Events(Event.All));
+
+            // Connect to localhost
+            eventManager.Start("localhost");
+
+            
+            System.Threading.Thread.Sleep(1000000);
+            
+            //a.
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Properties/AssemblyInfo.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/Properties/AssemblyInfo.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("FreeSwitch.EventSocket")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("FreeSwitch.EventSocket")]
+[assembly: AssemblyCopyright("Copyright ©  2007")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("db16a54e-3305-4b56-92a1-70cc95179bc6")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresence.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresence.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,112 @@
+namespace FreeSwitch.EventSocket
+{
+    public class EventPresence : SipEvent
+    {
+        private PartyInfo _caller;
+        private string _rpid = string.Empty;
+        private string _status = string.Empty;
+        //private string _callId; // not "presencein/register", "presenceout/register"
+        //private string _contact; // not "presencein/register", "presenceout/register"
+        //private string _expires; //not "presencein/register", "presenceout/register"
+        private string _eventType = string.Empty;
+        private string _login = string.Empty;
+        private EventChannelState _channelState;
+
+        public string Login
+        {
+            get { return _login; }
+            set { _login = value; }
+        }
+
+        /// <summary>
+        /// "Click to call", "Registered", "unavailable", "Active (%d waiting)", "Idle"
+        /// </summary>
+        public string Status
+        {
+            get { return _status; }
+            set { _status = value; }
+        }
+
+        public string Rpid
+        {
+            get { return _rpid; }
+            set { _rpid = value; }
+        }
+
+        /// <summary>
+        /// Caller is only specified on state CS_RING
+        /// and not on CS_HANGUP
+        /// </summary>
+        public PartyInfo Caller
+        {
+            get { return _caller; }
+            set { _caller = value; }
+        }
+
+        /// <summary>
+        /// presence, 
+        /// </summary>
+        public string PresenceEventType
+        {
+            get { return _eventType; }
+            set { _eventType = value; }
+        }
+
+        /// <summary>
+        /// We *may* have channel state info
+        /// </summary>
+        public EventChannelState ChannelState
+        {
+            get { return _channelState; }
+            set { _channelState = value; }
+        }
+
+
+        /*
+        proto: sip
+        login: sip%3Amod_sofia%40192.168.0.58%3A5070
+        rpid: unknown
+        from: gauffin%40gauffin.com
+        status: Registered
+         * */
+        public override bool ParseCommand(string name, string value)
+        {
+            switch (name)
+            {
+                case "status":
+                    _status = value;
+                    break;
+                case "rpid":
+                    _rpid = value;
+                    break;
+                case "login":
+                    _login = value;
+                    break;
+                case "event_type":
+                    _eventType = value;
+                    break;
+
+                default:
+                    if (name.Length > 7 && name.Substring(0, 7) == "caller-")
+                    {
+                        if (Caller == null)
+                            Caller = new PartyInfo();
+                        return Caller.Parse(name.Substring(7), value);
+                    }
+                    else
+                    {
+                        if (base.ParseCommand(name, value))
+                            return true;
+                        else
+                        {
+                            if (_channelState == null)
+                                _channelState = new EventChannelState();
+                            return _channelState.ParseCommand(name, value);
+                        }
+                    }
+                        
+            }
+            return true;
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceIn.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceIn.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,6 @@
+namespace FreeSwitch.EventSocket
+{
+    public class EventPresenceIn : EventPresence
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceOut.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceOut.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,8 @@
+namespace FreeSwitch.EventSocket
+{
+    public class EventPresenceOut : EventPresence
+    {
+       
+
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceProbe.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventPresenceProbe.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket.SipEvents
+{
+    class EventPresenceProbe : EventPresence
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventRoster.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventRoster.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace FreeSwitch.EventSocket
+{
+    class EventRoster : SipEvent
+    {
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventSofiaExpire.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventSofiaExpire.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,63 @@
+namespace FreeSwitch.EventSocket
+{
+    public class EventSofiaExpire : EventPresence
+    {
+        private string _profileName;
+        private string _userName;
+        private string _domain;
+        private string _userAgent;
+
+        public string ProfileName
+        {
+            get { return _profileName; }
+            set { _profileName = value; }
+        }
+
+        public string UserName
+        {
+            get { return _userName; }
+            set { _userName = value; }
+        }
+
+        public string Domain
+        {
+            get { return _domain; }
+            set { _domain = value; }
+        }
+
+        public string UserAgent
+        {
+            get { return _userAgent; }
+            set { _userAgent = value; }
+        }
+
+        /*
+				switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", argv[6]);
+			switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "user", "%s", argv[1]);
+			switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "host", "%s", argv[2]);
+			switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "user-agent", "%s", argv[5]);	
+         * */
+        public override bool ParseCommand(string name, string value)
+        {
+            switch (name)
+            {
+                case "profile-name":
+                    _profileName = value;
+                    break;
+                case "user":
+                    _userName = value;
+                    break;
+                case "host":
+                    _domain = value;
+                    break;
+                case "user-agent":
+                    _userAgent = value;
+                    break;
+                default:
+                    return base.ParseCommand(name, value);
+            }
+            return true;
+
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventSofiaRegister.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/EventSofiaRegister.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,92 @@
+namespace FreeSwitch.EventSocket
+{
+    /*
+     * profile-name: gauffin.com
+from-user: jonas
+from-host: gauffin.com
+contact: %22Jonas%20Gauffin%22%20%3Csip%3Ajonas%40192.168.1.101%3A5060%3E
+*/
+
+    /// <summary>
+    /// Sofia_reg.c way down in sofia_reg_handle_register
+    /// </summary>
+    public class EventSofiaRegister : EventBase
+    {
+        private string _domain;
+        private string _profileName;
+        private string _user;
+        private string _contact;
+        private string _callId;
+        private int _expires;
+
+        public string ProfileName
+        {
+            get { return _profileName; }
+            set { _profileName = value; }
+        }
+
+        public string UserName
+        {
+            get { return _user; }
+            set { _user = value; }
+        }
+
+        public string Domain
+        {
+            get { return _domain; }
+            set { _domain = value; }
+        }
+
+        public string Contact
+        {
+            get { return _contact; }
+            set { _contact = value; }
+        }
+
+        public string CallId
+        {
+            get { return _callId; }
+            set { _callId = value; }
+        }
+
+        public int Expires
+        {
+            get { return _expires; }
+            set { _expires = value; }
+        }
+
+        /*
+			switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", profile->name);
+			switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-user", "%s", to_user);
+			switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-host", "%s", to_host);
+			switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
+        */        
+        public override bool ParseCommand(string name, string value)
+        {
+            switch (name)
+            {
+                case "profile-name":
+                    _profileName = value;
+                    break;
+                case "from-user":
+                    _user = value;
+                    break;
+                case "from-host":
+                    _domain = value;
+                    break;
+                case "contact":
+                    _contact = value;
+                    break;
+                case "call-id":
+                    _callId = value;
+                    break;
+                case "expires":
+                    int.TryParse(value, out _expires);
+                    break;
+                default:
+                    return base.ParseCommand(name, value);
+            }
+            return true;
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/SipEvent.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/SipEvents/SipEvent.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,39 @@
+namespace FreeSwitch.EventSocket
+{
+    public class SipEvent : EventBase
+    {
+        private string _from;
+        private string _protocol;
+
+        public string Protocol
+        {
+            get { return _protocol; }
+            set { _protocol = value; }
+        }
+
+        /// <summary>
+        /// username at domain
+        /// </summary>
+        public string From
+        {
+            get { return _from; }
+            set { _from = value; }
+        }
+
+        public override bool ParseCommand(string name, string value)
+        {
+            switch (name)
+            {
+                case "from":
+                    _from = value;
+                    break;
+                case "proto":
+                    _protocol = value;
+                    break;
+                default:
+                    return base.ParseCommand(name, value);
+            }
+            return true;
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringHelper.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringHelper.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,55 @@
+namespace FreeSwitch.EventSocket
+{
+    public static class StringHelper
+    {
+        /// <summary>
+        /// This method converts a enum value to the correct format
+        /// that FreeSwitch uses (WORD1_WORD2) instead of the CamelCase that
+        /// we use in .net.
+        /// </summary>
+        /// <param name="name"></param>
+        /// <returns></returns>
+        public static string UpperCaseToCamelCase(string name)
+        {
+            bool isFirst = true;
+            string result = string.Empty;
+            foreach (char ch in name)
+            {
+                if (isFirst)
+                {
+                    result += char.ToUpper(ch);
+                    isFirst = false;
+                }
+                else
+                {
+                    if (ch == '_')
+                        isFirst = true;
+                    else
+                        result += char.ToLower(ch);
+                }
+            }
+            return result;
+        }
+
+        public static string CamelCaseToUpperCase(string name)
+        {
+            string result = string.Empty;
+            bool isFirst = true;
+            foreach (char ch in name)
+            {
+                if (char.IsUpper(ch))
+                {
+                    if (!isFirst)
+                        result += '_';
+                    else
+                        isFirst = false;
+                    result += char.ToUpper(ch);
+                }
+                else
+                    result += char.ToUpper(ch);
+            }
+
+            return result;
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringParser.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/FreeSwitchEventSocket/StringParser.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,269 @@
+using System.Collections.Generic;
+
+namespace EventSocketParser
+{
+    internal class StringParser
+    {
+        private readonly Stack<int> _savedPositions = new Stack<int>();
+        private int _pos;
+        private string _text;
+
+        public StringParser(string text)
+        {
+            _pos = 0;
+            _text = text;
+        }
+
+        public bool EOF
+        {
+            get { return IsEOF(_pos); }
+        }
+
+        /// <summary>
+        /// true if we are currently on a emty line
+        /// </summary>
+        public bool EOL
+        {
+            get
+            {
+                if (EOF)
+                    return false;
+                else if (_text[_pos] == '\n')
+                    return true;
+                else if (_pos < _text.Length - 2)
+                    return _text[_pos] == '\r' && _text[_pos + 1] == '\n';
+                else
+                    return false;
+            }
+        }
+
+        public void SavePos()
+        {
+            _savedPositions.Push(_pos);
+        }
+
+        public void RestorePos()
+        {
+            _pos = _savedPositions.Pop();
+        }
+
+        public void RemoveSavedPos()
+        {
+            _savedPositions.Pop();
+        }
+
+        public void ClearSavedPositions()
+        {
+            _savedPositions.Clear();
+        }
+
+        private bool IsEOF(int pos)
+        {
+            return pos >= _text.Length - 1;
+        }
+
+        public bool IsEmptyLine(bool skipWhitespaces)
+        {
+            if (EOF)
+                return false;
+            else if (_pos == _text.Length - 1)
+                return _text[_pos] == '\n';
+            else
+                return _text[_pos] == '\r' && _text[_pos + 1] == '\n';
+        }
+
+        public string PeekWord(bool skipWS, bool stopAtEOL)
+        {
+            int startpos = _pos;
+            if (skipWS)
+                SkipWS();
+            int pos = FindWS(stopAtEOL);
+            _pos = startpos;
+
+            if (pos != -1)
+                return _text.Substring(_pos, pos - _pos);
+            else
+                return string.Empty;
+        }
+
+        public string GetWord(bool skipWS, bool stopAtEOL)
+        {
+            int startpos = _pos;
+            if (skipWS)
+                SkipWS();
+            int pos = FindWS(stopAtEOL);
+
+            _pos = pos;
+
+            if (pos != -1)
+                return _text.Substring(startpos, pos - startpos);
+            else
+                return string.Empty;
+        }
+
+        public string ReadLine()
+        {
+            return ReadLine(false);
+        }
+
+        public string ReadLine(bool trimWhiteSpaces)
+        {
+            if (EOF)
+                return string.Empty;
+
+            if (trimWhiteSpaces)
+                SkipWS();
+
+            // loop until we get new line chars
+            int startpos = _pos;
+            while (!EOF && !IsEOL())
+                ++_pos;
+
+            // Save _pos, trim whitespaces, restore _pos
+            int pos = _pos;
+            if (trimWhiteSpaces)
+                TrimEnd();
+            int endpos = _pos;
+            _pos = pos;
+
+            // Move to after new line chars            
+            if (_text[_pos] == '\r')
+                _pos += 2;
+            else
+                ++_pos;
+
+            // .. and the result is line without whitespaces at the end and without new line chars.
+            return _text.Substring(startpos, endpos - startpos);
+        }
+
+        public string ReadToEmptyLine()
+        {
+            int chars = 4;
+            int pos = _text.IndexOf("\n\n", _pos);
+            if (pos == -1)
+            {
+                chars = 2;
+                pos = _text.IndexOf("\n\n", _pos);
+            }
+            if (pos == -1)
+                return string.Empty;
+
+            int startpos = _pos;
+            _pos = pos + chars;
+            return _text.Substring(startpos, pos - startpos);
+        }
+
+        public string Read(int chars)
+        {
+            if (_text.Length - _pos < chars)
+                return string.Empty;
+
+            string result = _text.Substring(_pos, chars);
+            _pos += chars;
+            return result;
+        }
+
+        public string ReadToEnd()
+        {
+            string result = _text.Substring(_pos, _text.Length - _pos);
+            _pos = _text.Length;
+            return result;
+        }
+
+        public string Read(char delimiter, bool skipWS)
+        {
+            if (skipWS)
+                SkipWS();
+
+            // find delimiter
+            int startpos = _pos;
+            while (!EOF && _text[_pos] != delimiter)
+                ++_pos;
+
+            // did not find it, reset pos
+            if (EOF)
+            {
+                _pos = startpos;
+                return string.Empty;
+            }
+            else
+            {
+                ++_pos; // skip delimiter
+                int endpos = TrimEnd(); // skip 
+                return _text.Substring(startpos, endpos - startpos);
+            }
+        }
+
+        private int TrimEnd()
+        {
+            int pos = _pos;
+            while (IsWS(_text[pos]))
+                --pos;
+            return pos;
+        }
+
+        private int FindWS(bool stopAtEOL)
+        {
+            if (!stopAtEOL)
+                return FindWS();
+
+            int pos = _pos;
+            while (!IsEOF(pos) && !IsEOL(_text[pos]) && !IsWS(_text[pos]))
+                ++pos;
+
+            return IsEOF(pos) ? -1 : pos;
+        }
+
+        private bool IsEOL()
+        {
+            if (_text[_pos] == '\r' && _text[_pos + 1] == '\n')
+                return true;
+            else if (_text[_pos] == '\n')
+                return true;
+            else
+                return false;
+        }
+
+        private bool IsEOL(char ch)
+        {
+            return ch == '\r' || ch == '\n';
+        }
+
+        private bool IsWS(char ch)
+        {
+            return ch == '\t' || ch == ' ';
+        }
+
+        private int FindWS()
+        {
+            int pos = _pos;
+            while (!IsEOF(pos) && !IsWS(_text[pos]))
+                ++pos;
+
+            return IsEOF(pos) ? -1 : pos;
+        }
+
+        public void SkipWS()
+        {
+            while (!EOF && IsWS(_text[_pos]))
+                ++_pos;
+        }
+
+        public void RemoveUsedContent()
+        {
+            _text = _text.Remove(0, _pos);
+            _pos = 0;
+        }
+
+        public void Append(string value)
+        {
+            _text += value;
+        }
+
+        public void Clear()
+        {
+            _text = string.Empty;
+            _pos = 0;
+        }
+    }
+}
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/IvrSocket.csproj
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/IvrSocket.csproj	Thu May  1 14:27:39 2008
@@ -0,0 +1,54 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{22F26D13-0A0E-4345-9FEC-CE13FC8F37FD}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>IvrSocket</RootNamespace>
+    <AssemblyName>IvrSocket</AssemblyName>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Voicemail.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\FreeSwitchEventSocket\FreeSwitch.EventSocket.csproj">
+      <Project>{3F8895F6-F710-4323-B96A-4EFB6BC97E08}</Project>
+      <Name>FreeSwitch.EventSocket</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Program.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Program.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,38 @@
+using System;
+using FreeSwitch.EventSocket;
+
+namespace IvrSocket
+{
+    class Program
+    {
+        private static EventManager mgr;
+        static void Main(string[] args)
+        {
+            mgr = new EventManager();
+            mgr.EventReceived += IvrManager;
+            mgr.Subscribe(Event.All);
+            mgr.Start("localhost");
+            Console.ReadLine();
+        }
+
+        private static void IvrManager(EventBase receivedEvent)
+        {
+            Console.WriteLine(receivedEvent.Name);
+            if (receivedEvent is ChannelEvent)
+            {
+                ChannelEvent evt = (ChannelEvent) receivedEvent;
+                Console.WriteLine(evt.Name + ": " + evt.UniqueId);
+            }
+            if (receivedEvent is EventChannelAnswer)
+            {
+                EventChannelAnswer answer = (EventChannelAnswer)receivedEvent;
+                if (answer.Parameters["variable_ivr_name"] == "voicemail")
+                   new Voicemail(mgr, answer.UniqueId);
+            }
+            else if (receivedEvent is EventChannelHangup)
+            {
+                Console.WriteLine("Bye bye baby!");
+            }
+        }
+    }
+}

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Properties/AssemblyInfo.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Properties/AssemblyInfo.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("IvrSocket")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("IvrSocket")]
+[assembly: AssemblyCopyright("Copyright ©  2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("3e447189-bfd8-4412-93bb-da3543dd2ca6")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

Added: freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Voicemail.cs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/verifier/EventSocket/trunk/IvrSocket/Voicemail.cs	Thu May  1 14:27:39 2008
@@ -0,0 +1,28 @@
+using System;
+using System.Threading;
+using FreeSwitch.EventSocket;
+using FreeSwitch.EventSocket.Ivr;
+
+namespace IvrSocket
+{
+    /// <summary>
+    /// Very simple voicemail app =)
+    /// </summary>
+    class Voicemail
+    {
+        private readonly IvrInterface _ivr;
+
+        public Voicemail(EventManager mgr, string uuid)
+        {
+            _ivr = new IvrInterface(mgr, uuid);
+            _ivr.BeginInvoke(OnIvr, null, null);
+        }
+
+        private void OnIvr(IvrInterface app)
+        {
+            _ivr.Play("sv\\system\\record_after_beep.wav", IvrInterface.AllDigits);
+            //_ivr.Sleep(5000);
+            //_ivr.Record("voicemails\\" + Guid.NewGuid() + ".wav", 60);
+        }
+    }
+}



More information about the Freeswitch-svn mailing list