From 4dd77097a814e2c03174a7f99d6ba984928c8b15 Mon Sep 17 00:00:00 2001
From: Patrick Simpson 
Date: Thu, 9 Feb 2017 12:20:06 +0100
Subject: [PATCH] Cleaned up MailEvent release. Added debug option to GAB to
 prevent MailEvent hooking.
---
 .../Features/GAB/FeatureGAB.cs                 | 18 +++++++++++++++---
 .../Stubs/OutlookWrappers/ComWrapper.cs        |  1 +
 .../AcaciaZPushPlugin/Utils/MailEvents.cs      | 16 +++++-----------
 3 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/FeatureGAB.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/FeatureGAB.cs
index e53bf0e..2e8d6e9 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/FeatureGAB.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/FeatureGAB.cs
@@ -64,8 +64,11 @@ namespace Acacia.Features.GAB
 
         public override void Startup()
         {
-            MailEvents.BeforeDelete += SuppressEventHandler_Delete;
-            MailEvents.Write += SuppressEventHandler_Modify;
+            if (SuppressModifications)
+            {
+                MailEvents.BeforeDelete += SuppressEventHandler_Delete;
+                MailEvents.Write += SuppressEventHandler_Modify;
+            }
             Watcher.AccountDiscovered += AccountDiscovered;
             Watcher.AccountRemoved += AccountRemoved;
             Watcher.AccountsScanned += AccountsScanned;
@@ -208,7 +211,16 @@ namespace Acacia.Features.GAB
             set { SetOption(OPTION_EMPTY_DELETED_ITEMS, value); }
         }
         private static readonly BoolOption OPTION_EMPTY_DELETED_ITEMS = new BoolOption("EmptyDeletedItems", true);
-        
+
+        [AcaciaOption("If enabled, modifications to the GAB folder are suppressed. " +
+                      "This should only be disabled for debug purposes.")]
+        public bool SuppressModifications
+        {
+            get { return GetOption(OPTION_SUPPRESS_MODIFICATIONS); }
+            set { SetOption(OPTION_SUPPRESS_MODIFICATIONS, value); }
+        }
+        private static readonly BoolOption OPTION_SUPPRESS_MODIFICATIONS = new BoolOption("SuppressModifications", true);
+
         #endregion
 
         #region Modification suppression
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ComWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ComWrapper.cs
index 61cf8cb..4c234c0 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ComWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ComWrapper.cs
@@ -35,6 +35,7 @@ namespace Acacia.Stubs.OutlookWrappers
         {
             Interlocked.Increment(ref Statistics.CreatedWrappers);
             this._createdTrace = new System.Diagnostics.StackTrace();
+            MustRelease = true;
         }
 
         ~ComWrapper()
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs
index 2978dae..59569be 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs
@@ -219,25 +219,22 @@ namespace Acacia.Utils
             NSOutlook.ItemEvents_10_Event hasEvents = item as NSOutlook.ItemEvents_10_Event;
             if (hasEvents != null)
             {
-                new MailEventHooker(item, hasEvents, this);
+                new MailEventHooker(hasEvents, this);
             }
-            else ComRelease.Release(item);
         }
 
         private class MailEventHooker : ComWrapper
         {
-            private object _item;
             private NSOutlook.ItemEvents_10_Event _itemEvents;
             private readonly MailEvents _events;
             // TODO: remove id and debug logging
             private int _id;
             private static int nextId;
 
-            public MailEventHooker(object item, NSOutlook.ItemEvents_10_Event itemEvents, MailEvents events)
+            public MailEventHooker(NSOutlook.ItemEvents_10_Event itemEvents, MailEvents events)
             {
-                this._id = ++nextId;
-                this._item = item;
                 this._itemEvents = itemEvents;
+                this._id = ++nextId;
                 this._events = events;
                 HookEvents(true);
             }
@@ -245,11 +242,8 @@ namespace Acacia.Utils
             protected override void DoRelease()
             {
                 Logger.Instance.Debug(this, "DoRelease: {0}", _id);
-
-                ComRelease.Release(_item);
-                _item = null;
-                ComRelease.Release(_itemEvents);
-                _itemEvents = null;
+                // TODO: It looks like release _itemEvents is not only not needed, but causes exceptions.
+                //       If that is really the case, this doesn't need to be a ComWrapper
             }
 
             private void HookEvents(bool add)