<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[Freeswitch-trunk][15643] </title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<div id="header">FreeSWITCH Subversion</div>
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://fisheye.freeswitch.org/changelog/FreeSWITCH?cs=15643">15643</a></dd>
<dt>Author</dt> <dd>joshrivers</dd>
<dt>Date</dt> <dd>2009-11-23 17:22:27 -0600 (Mon, 23 Nov 2009)</dd>
</dl>

<h3>Log Message</h3>
<pre>Modifications to CoreSession and ManagedSession and related code to match renamed members.
Added mockable interface for ManagedSession.
Added mockable interface for Event.
Added wrapper for EventConsumer with simplified, mockable interface.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#freeswitchbranchesjoshriversmod_managed_working_branchsrcmodlanguagesmod_managedmanagedChannelVariablescs">freeswitch/branches/joshrivers/mod_managed_working_branch/src/mod/languages/mod_managed/managed/ChannelVariables.cs</a></li>
<li><a href="#freeswitchbranchesjoshriversmod_managed_working_branchsrcmodlanguagesmod_managedmanagedManagedSessioncs">freeswitch/branches/joshrivers/mod_managed_working_branch/src/mod/languages/mod_managed/managed/ManagedSession.cs</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="freeswitchbranchesjoshriversmod_managed_working_branchsrcmodlanguagesmod_managedmanagedChannelVariablescs"></a>
<div class="modfile"><h4>Modified: freeswitch/branches/joshrivers/mod_managed_working_branch/src/mod/languages/mod_managed/managed/ChannelVariables.cs (15642 => 15643)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/branches/joshrivers/mod_managed_working_branch/src/mod/languages/mod_managed/managed/ChannelVariables.cs        2009-11-23 23:19:42 UTC (rev 15642)
+++ freeswitch/branches/joshrivers/mod_managed_working_branch/src/mod/languages/mod_managed/managed/ChannelVariables.cs        2009-11-23 23:22:27 UTC (rev 15643)
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         ChannelVariables _variables; // Set on ManagedSession init
</span><del>-        public ChannelVariables Variables {
</del><ins>+        public IChannelVariables Variables {
</ins><span class="cx">             get {
</span><span class="cx">                 if (_variables == null) {
</span><span class="cx">                     _variables = new ChannelVariables(this);
</span><span class="lines">@@ -75,8 +75,49 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        public interface IChannelVariables
+        {
+            IDictionary&lt;string, string&gt; GetAllVariables();
+            bool BypassMedia { get; set; }
+            DateTime CreatedTime { get; }
+            DateTime? AnsweredTime { get; }
+            DateTime? HangupTime { get; }
+            DateTime? ProgressTime { get; }
+            DateTime? ProgressMediaTime { get; }
+            DateTime? TransferTime { get; }
+            string SofiaProfileName { get; }
+            string SipCallID { get; }
+            string SipReceivedIP { get; }
+            short? SipReceivedPort { get; }
+            string SipViaProtocolString { get; }
+            string SipFromUser { get; }
+            string SipFromUriString { get; }
+            string SipFromHost { get; }
+            string SipReqUser { get; }
+            string SipReqUriString { get; }
+            string SipReqHost { get; }
+            string SipToUser { get; }
+            string SipToUriString { get; }
+            string SipToHost { get; }
+            string SipContactUser { get; }
+            string SipContactUriString { get; }
+            string SipContactHost { get; }
+            short? SipContactPort { get; }
+            string SipDestinationUrlString { get; }
+            int? SipTermStatus { get; }
+            int? SipTermCause { get; }
+            string SwitchRSdp { get; }
+            string SwitchMSdp { get; }
+            string SipHangupPhrase { get; }
+            string ProtoSpecificHangupCause { get; }
+            string HangupCauseString { get; }
+            int? HangupCauseQ850 { get; }
+            string OriginateDispositionString { get; }
+            Native.switch_call_direction_t CallDirection { get; }
+        }
</ins><span class="cx">         /// &lt;summary&gt;Strongly typed access to common variables&lt;/summary&gt;
</span><del>-        public class ChannelVariables {
</del><ins>+        public class ChannelVariables : IChannelVariables
+        {
</ins><span class="cx">             readonly ManagedSession sess;
</span><span class="cx">             internal ChannelVariables(ManagedSession session) {
</span><span class="cx">                 this.sess = session;
</span><span class="lines">@@ -84,12 +125,12 @@
</span><span class="cx"> 
</span><span class="cx">             public IDictionary&lt;string, string&gt; GetAllVariables() {
</span><span class="cx">                 var dic = new Dictionary&lt;string, string&gt;(StringComparer.OrdinalIgnoreCase);
</span><del>-                var evt = Native.freeswitch.switch_channel_variable_first(sess.channel);
</del><ins>+                var evt = Native.freeswitch.switch_channel_variable_first(sess.Channel);
</ins><span class="cx">                 while(evt != null) {
</span><span class="cx">                     dic.Add(evt.name, evt.value);
</span><span class="cx">                     evt = evt.next;
</span><span class="cx">                 }
</span><del>-                Native.freeswitch.switch_channel_variable_last(sess.channel);
</del><ins>+                Native.freeswitch.switch_channel_variable_last(sess.Channel);
</ins><span class="cx">                 return dic;
</span><span class="cx">             }
</span><span class="cx"> 
</span></span></pre></div>
<a id="freeswitchbranchesjoshriversmod_managed_working_branchsrcmodlanguagesmod_managedmanagedManagedSessioncs"></a>
<div class="modfile"><h4>Modified: freeswitch/branches/joshrivers/mod_managed_working_branch/src/mod/languages/mod_managed/managed/ManagedSession.cs (15642 => 15643)</h4>
<pre class="diff"><span>
<span class="info">--- freeswitch/branches/joshrivers/mod_managed_working_branch/src/mod/languages/mod_managed/managed/ManagedSession.cs        2009-11-23 23:19:42 UTC (rev 15642)
+++ freeswitch/branches/joshrivers/mod_managed_working_branch/src/mod/languages/mod_managed/managed/ManagedSession.cs        2009-11-23 23:22:27 UTC (rev 15643)
</span><span class="lines">@@ -45,10 +45,71 @@
</span><span class="cx"> 
</span><span class="cx">     // This callback is used for originate
</span><span class="cx">     [UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
</span><del>-    public delegate switch_status_t switch_state_handler_t_delegate(IntPtr sessionPtr); 
</del><ins>+    public delegate switch_status_t switch_state_handler_t_delegate(IntPtr sessionPtr);
</ins><span class="cx"> 
</span><del>-    public partial class ManagedSession
</del><ins>+    public interface IManagedSession
</ins><span class="cx">     {
</span><ins>+        int Answer();
+        bool Answered();
+        int Allocated { get; set; }
+        bool BeginAllowThreads();
+        input_callback_state_t CallbackState { get; set; }
+        switch_call_cause_t CallCause { get; set; }
+        SWIGTYPE_p_switch_channel Channel { get; set; }
+        void CheckHangupHook();
+        int CollectDigits(int abs_timeout);
+        int CollectDigits(int digit_timeout, int abs_timeout);
+        Func&lt;Char, TimeSpan, string&gt; DtmfReceivedFunction { get; set; }
+        void Destroy();
+        bool EndAllowThreads();
+        Func&lt;Native.Event, string&gt; EventReceivedFunction { get; set; }
+        void Execute(string app, string data);
+        uint Flags { get; set; }
+        int FlushEvents();
+        int FlushDigits();
+        switch_input_args_t GetCallbackArguments();
+        string GetState();
+        string GetUuid();
+        string GetDigits(int maxdigits, string terminators, int timeout);
+        string GetDigits(int maxdigits, string terminators, int timeout, int interdigit);
+        SWIGTYPE_p_void GetPrivate(string var);
+        string GetVariable(string var);
+        string GetXmlCdr();
+        void Hangup(string cause);
+        string HangupCause();
+        Action HangupFunction { get; set; }
+        void HangupState();
+        switch_channel_state_t HookState { get; set; }
+        SWIGTYPE_p_switch_core_session InternalSession { get; set; }
+        bool IsAvailable { get; }
+        bool MediaReady();
+        bool Originate(CoreSession aLegSession, string destination, TimeSpan timeout);
+        string PlayAndGetDigits(int min_digits, int max_digits, int max_tries, int timeout, string terminators, string audio_files, string bad_input_audio_files, string digits_regex, string var_name);
+        int PreAnswer();
+        string Read(int min_digits, int max_digits, string prompt_audio_file, int timeout, string valid_terminators);
+        bool Ready();
+        int RecordFile(string file_name, int time_limit, int silence_threshold, int silence_hits);
+        int SetAutoHangup(bool val);
+        void SetPrivate(string var, SWIGTYPE_p_void val);
+        void SetVariable(string var, string val);
+        void Say(string tosay, string module_name, string say_type, string say_method);
+        void SayPhrase(string phrase_name, string phrase_data, string phrase_lang);
+        void SetTtsParameters(string tts_name, string voice_name);
+        int Speak(string text);
+        int StreamFile(string file, int starting_sample_count);
+        int Sleep(int ms, int sync);
+        void SendEvent(Event sendME);
+        void SetEventData(Event e);
+        int Transfer(string extension, string dialplan, string context);
+        string TextToSpeechEngine { get; set; }
+        string TextToSpeechVoice { get; set; }
+        Guid Uuid { get; }
+        string UuidString { get; set; }
+        ManagedSession.IChannelVariables Variables { get; }
+        void WaitForAnswer(CoreSession calling_session);
+    }
+    public partial class ManagedSession : IManagedSession
+    {
</ins><span class="cx">         // SWITCH_DECLARE(void) InitManagedSession(ManagedSession *session, MonoObject *dtmfDelegate, MonoObject *hangupDelegate)
</span><span class="cx">         [DllImport(&quot;mod_managed.dll&quot;, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
</span><span class="cx">         static extern void InitManagedSession(IntPtr sessionPtr, DtmfCallback dtmfDelegate, CdeclAction hangupDelegate);
</span><span class="lines">@@ -56,7 +117,8 @@
</span><span class="cx">         /// &lt;summary&gt;Initializes the native ManagedSession. Called after Originate completes successfully .&lt;/summary&gt;
</span><span class="cx">         internal void Initialize()
</span><span class="cx">         {
</span><del>-            if (allocated == 0) {
</del><ins>+            if (Allocated == 0)
+            {
</ins><span class="cx">                 throw new InvalidOperationException(&quot;Cannot initialize a ManagedSession until it is allocated (originated successfully).&quot;);
</span><span class="cx">             }
</span><span class="cx">             // P/Invoke generated function pointers stick around until the delegate is collected
</span><span class="lines">@@ -77,11 +139,13 @@
</span><span class="cx">         void hangupCallback()
</span><span class="cx">         {
</span><span class="cx">             Log.WriteLine(LogLevel.Debug, &quot;AppFunction is in hangupCallback.&quot;);
</span><del>-            try {
</del><ins>+            try
+            {
</ins><span class="cx">                 var f = HangupFunction;
</span><span class="cx">                 if (f != null) f();
</span><span class="cx">             }
</span><del>-            catch (Exception ex) {
</del><ins>+            catch (Exception ex)
+            {
</ins><span class="cx">                 Log.WriteLine(LogLevel.Warning, &quot;Exception in hangupCallback: {0}&quot;, ex.ToString());
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="lines">@@ -92,43 +156,54 @@
</span><span class="cx"> 
</span><span class="cx">         string inputCallback(IntPtr input, Native.switch_input_type_t inputType)
</span><span class="cx">         {
</span><del>-            try {
-                switch (inputType) {
</del><ins>+            try
+            {
+                switch (inputType)
+                {
</ins><span class="cx">                     case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_DTMF:
</span><del>-                        using (var dtmf = new Native.switch_dtmf_t(input, false)) {
</del><ins>+                        using (var dtmf = new Native.switch_dtmf_t(input, false))
+                        {
</ins><span class="cx">                             return dtmfCallback(dtmf);
</span><span class="cx">                         }
</span><span class="cx">                     case FreeSWITCH.Native.switch_input_type_t.SWITCH_INPUT_TYPE_EVENT:
</span><del>-                        using (var swevt = new Native.switch_event(input, false)) {
</del><ins>+                        using (var swevt = new Native.switch_event(input, false))
+                        {
</ins><span class="cx">                             return eventCallback(swevt);
</span><span class="cx">                         }
</span><span class="cx">                     default:
</span><span class="cx">                         return &quot;&quot;;
</span><span class="cx">                 }
</span><del>-            } catch (Exception ex) {
</del><ins>+            }
+            catch (Exception ex)
+            {
</ins><span class="cx">                 Log.WriteLine(LogLevel.Error, &quot;InputCallback threw exception: &quot; + ex.ToString());
</span><span class="cx">                 return &quot;-ERR InputCallback Exception: &quot; + ex.Message;
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        string dtmfCallback(Native.switch_dtmf_t dtmf) {
</del><ins>+        string dtmfCallback(Native.switch_dtmf_t dtmf)
+        {
</ins><span class="cx">             var f = DtmfReceivedFunction;
</span><del>-            return f == null ? &quot;&quot; 
</del><ins>+            return f == null ? &quot;&quot;
</ins><span class="cx">                 : f(((char)(byte)dtmf.digit), TimeSpan.FromMilliseconds(dtmf.duration));
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        string eventCallback(Native.switch_event swevt) {
-            using (var evt = new FreeSWITCH.Native.Event(swevt, 0)) {
</del><ins>+        string eventCallback(Native.switch_event swevt)
+        {
+            using (var evt = new FreeSWITCH.Native.Event(swevt, 0))
+            {
</ins><span class="cx">                 var f = EventReceivedFunction;
</span><del>-                return f == null ? &quot;&quot; 
</del><ins>+                return f == null ? &quot;&quot;
</ins><span class="cx">                     : f(evt);
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         [Obsolete(&quot;Use static Originate method.&quot;, false)]
</span><del>-        public bool Originate(CoreSession aLegSession, string destination, TimeSpan timeout) {
</del><ins>+        public bool Originate(CoreSession aLegSession, string destination, TimeSpan timeout)
+        {
</ins><span class="cx">             var res = 0 == this.originate(aLegSession, destination, (int)timeout.TotalMilliseconds, null);
</span><del>-            if (res) {
</del><ins>+            if (res)
+            {
</ins><span class="cx">                 this.Initialize();
</span><span class="cx">             }
</span><span class="cx">             return res;
</span><span class="lines">@@ -139,18 +214,22 @@
</span><span class="cx">         // The delegate needs to be stored so it doesn't get GC'd, so we can't just return GetFunctionPointerForDelegate right away.
</span><span class="cx"> 
</span><span class="cx">         /// &lt;summary&gt;Wraps a nice handler into a delegate suitable for reverse P/Invoke. This only currently works well for hangup/reporting handlers.&lt;/summary&gt;
</span><del>-        public static switch_state_handler_t_delegate CreateStateHandlerDelegate(Action&lt;ManagedSession&gt; handler) {
</del><ins>+        public static switch_state_handler_t_delegate CreateStateHandlerDelegate(Action&lt;ManagedSession&gt; handler)
+        {
</ins><span class="cx">             // We create a ManagedSession on top of the session so callbacks can use it &quot;nicely&quot;
</span><span class="cx">             // Then we sort of dispose it.
</span><del>-            switch_state_handler_t_delegate del = ptr =&gt; {
-                using (var sess = new ManagedSession(new SWIGTYPE_p_switch_core_session(ptr, false))) {
</del><ins>+            switch_state_handler_t_delegate del = ptr =&gt;
+            {
+                using (var sess = new ManagedSession(new SWIGTYPE_p_switch_core_session(ptr, false)))
+                {
</ins><span class="cx">                     handler(sess);
</span><span class="cx">                     return switch_status_t.SWITCH_STATUS_SUCCESS;
</span><span class="cx">                 }
</span><span class="cx">             };
</span><span class="cx">             return del;
</span><span class="cx">         }
</span><del>-        public static SWIGTYPE_p_f_p_switch_core_session__switch_status_t WrapStateHandlerDelegate(switch_state_handler_t_delegate del) {
</del><ins>+        public static SWIGTYPE_p_f_p_switch_core_session__switch_status_t WrapStateHandlerDelegate(switch_state_handler_t_delegate del)
+        {
</ins><span class="cx">             return new SWIGTYPE_p_f_p_switch_core_session__switch_status_t(Marshal.GetFunctionPointerForDelegate(del), false);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -162,15 +241,18 @@
</span><span class="cx">         switch_state_handler_table originate_table;
</span><span class="cx">         GCHandle originate_keepalive_handle; // Make sure the B Leg is not collected and disposed until we run ondestroy
</span><span class="cx"> 
</span><del>-        switch_status_t originate_ondestroy_method(IntPtr channelPtr) {
</del><ins>+        switch_status_t originate_ondestroy_method(IntPtr channelPtr)
+        {
</ins><span class="cx">             // CS_DESTROY lets the bleg be collected
</span><span class="cx">             // and frees originate_table memory
</span><span class="cx">             // Note that this (bleg ManagedSession) is invalid 
</span><span class="cx">             // to touch right now - the unmanaged memory has already been free'd
</span><del>-            if (this.originate_keepalive_handle.IsAllocated) {
</del><ins>+            if (this.originate_keepalive_handle.IsAllocated)
+            {
</ins><span class="cx">                 this.originate_keepalive_handle.Free(); // GC can now collect this bleg
</span><span class="cx">             }
</span><del>-            if (this.originate_table != null) {
</del><ins>+            if (this.originate_table != null)
+            {
</ins><span class="cx">                 this.originate_table.Dispose();
</span><span class="cx">                 this.originate_table = null;
</span><span class="cx">             }
</span><span class="lines">@@ -181,12 +263,15 @@
</span><span class="cx">         /// Performs originate. Returns ManagedSession on success, null on failure.
</span><span class="cx">         /// onHangup is called as a state handler, after the channel is truly hungup (CS_REPORTING).
</span><span class="cx">         /// &lt;/summary&gt;
</span><del>-        public static ManagedSession OriginateHandleHangup(CoreSession aLegSession, string destination, TimeSpan timeout, Action&lt;ManagedSession&gt; onHangup) {
</del><ins>+        public static ManagedSession OriginateHandleHangup(CoreSession aLegSession, string destination, TimeSpan timeout, Action&lt;ManagedSession&gt; onHangup)
+        {
</ins><span class="cx">             var bleg = new ManagedSession();
</span><span class="cx"> 
</span><span class="cx">             bleg.originate_ondestroy_delegate = bleg.originate_ondestroy_method;
</span><del>-            bleg.originate_onhangup_delegate = CreateStateHandlerDelegate(sess_b =&gt; {
-                if (onHangup != null) {
</del><ins>+            bleg.originate_onhangup_delegate = CreateStateHandlerDelegate(sess_b =&gt;
+            {
+                if (onHangup != null)
+                {
</ins><span class="cx">                     onHangup(sess_b);
</span><span class="cx">                 }
</span><span class="cx">             });
</span><span class="lines">@@ -196,35 +281,95 @@
</span><span class="cx">             bleg.originate_table.flags = (int)switch_state_handler_flag_t.SSH_FLAG_STICKY;
</span><span class="cx">             var res = 0 == bleg.originate(aLegSession, destination, (int)timeout.TotalSeconds, bleg.originate_table);
</span><span class="cx">             bleg.originate_keepalive_handle = GCHandle.Alloc(bleg, GCHandleType.Normal); // Prevent GC from eating the bleg
</span><del>-            if (res) {
</del><ins>+            if (res)
+            {
</ins><span class="cx">                 bleg.Initialize();
</span><span class="cx">                 return bleg;
</span><del>-            } else {
</del><ins>+            }
+            else
+            {
</ins><span class="cx">                 // Dispose to free the lock
</span><span class="cx">                 // The bleg lives on with its unmanaged memory freed 
</span><span class="cx">                 // Until CS_DESTROY gets called
</span><del>-                bleg.Dispose(); 
</del><ins>+                bleg.Dispose();
</ins><span class="cx">                 return null;
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Convenience
</span><del>-        public bool IsAvailable {
</del><ins>+        public bool IsAvailable
+        {
</ins><span class="cx">             get { return this.Ready(); }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        public Guid Uuid {
-            get {
-                if (allocated == 0) throw new InvalidOperationException(&quot;Session has not been initialized.&quot;);
</del><ins>+        public Guid Uuid
+        {
+            get
+            {
+                if (Allocated == 0) throw new InvalidOperationException(&quot;Session has not been initialized.&quot;);
</ins><span class="cx">                 return new Guid(this.GetUuid());
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        public switch_call_cause_t CallCause {
-            get {
-                if (allocated == 0) throw new InvalidOperationException(&quot;Session has not been initialized.&quot;);
-                return freeswitch.switch_channel_get_cause(this.channel);
</del><ins>+        public switch_call_cause_t CallCause
+        {
+            get
+            {
+                if (Allocated == 0) throw new InvalidOperationException(&quot;Session has not been initialized.&quot;);
+                return freeswitch.switch_channel_get_cause(this.Channel);
</ins><span class="cx">             }
</span><ins>+            set
+            {
+                if (Allocated == 0) throw new InvalidOperationException(&quot;Session has not been initialized.&quot;);
+                base.CallCause = value;
+            }
</ins><span class="cx">         }
</span><span class="cx">     }
</span><ins>+
+    public interface IEvent
+    {
+        switch_event InternalEvent { get; set; }
+        string serialized_string { get; set; }
+        int mine { get; set; }
+        string Serialize(string format);
+        bool SetPriority(switch_priority_t priority);
+        string GetHeader(string header_name);
+        string GetBody();
+        string GetEventType();
+        bool AddBody(string value);
+        bool AddHeader(string header_name, string value);
+        bool DeleteHeader(string header_name);
+        bool Fire();
+    }
+    public partial class Event :  IEvent { }
+
+    public interface IManagedEventConsumer
+    {
+        IEvent Pop(bool block);
+    }
+    public class ManagedEventConsumer : IDisposable, IManagedEventConsumer
+    {
+        private EventConsumer _eventConsumer;
+        public ManagedEventConsumer(string eventClass, string EventSubclass)
+        {
+            this._eventConsumer = new EventConsumer(eventClass, EventSubclass);
+        }
+
+        public IEvent Pop(bool block)
+        {
+            if (block)
+            {
+                return this._eventConsumer.pop(1);
+            }
+            else
+            {
+                return this._eventConsumer.pop(0);
+            }
+        }
+
+        public void Dispose()
+        {
+            this._eventConsumer.Dispose();
+        }
+    }
</ins><span class="cx"> }
</span></span></pre>
</div>
</div>
<div id="footer">See you at ClueCon</div>

</body>
</html>