diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1b2b724d372a76ed6b58189fd053e489cc9da889..ce6e4b29d18c649ba9783bfcbd6e662d5cdabfde 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+* v0.94:
+
+ * ...
+
 * v0.93:
 
  * Large refactor of XML schema compiler
diff --git a/coolamqp/framing/compilation/xml_fields.py b/coolamqp/framing/compilation/xml_fields.py
index dfcb8f1156cd094118848e308a82a52ffa1d6a4a..794973f7ee226d16e65183ced558df16e8d2546a 100644
--- a/coolamqp/framing/compilation/xml_fields.py
+++ b/coolamqp/framing/compilation/xml_fields.py
@@ -10,6 +10,9 @@ class _Required(object):
 def nop(x):
     return x
 
+def _get_tagchild(elem, tag):
+    return [e for e in elem.getchildren() if e.tag == tag]
+
 __all__ = [
     '_name', '_docs', '_ComputedField', '_ValueField', '_SimpleField',
     '_docs_with_label', '_get_tagchild', '_ChildField'
@@ -73,8 +76,8 @@ class _SimpleField(_ValueField):
     def __init__(self, name, field_type=nop, default=_Required):
         super(_SimpleField, self).__init__(name, name, field_type, default)
 
-def _get_tagchild(elem, tag):
-    return [e for e in elem.getchildren() if e.tag == tag]
+
+
 
 
 class _ChildField(_ComputedField):
@@ -85,6 +88,7 @@ class _ChildField(_ComputedField):
         super(_ChildField, self).__init__(name, lambda elem: \
             postexec([fun(c) for c in _get_tagchild(elem, xml_tag)]))
 
+
 def get_docs(elem, label):
     """Parse an XML element. Return documentation"""
     for kid in elem.getchildren():
diff --git a/coolamqp/uplink/connection/connection.py b/coolamqp/uplink/connection/connection.py
index 688c28ffac5825180133b6d1586770ac24972089..73b3dbe1be70a8e9b0170304fff6dbd6324ed1e9 100644
--- a/coolamqp/uplink/connection/connection.py
+++ b/coolamqp/uplink/connection/connection.py
@@ -19,6 +19,34 @@ from coolamqp.objects import Callable
 logger = logging.getLogger(__name__)
 
 
+def alert_watches(watches, trigger):
+    """
+    Notify all watches in this collection.
+
+    Return a list of alive watches.
+    :param watches: list of Watch
+    :return: tuple of (list of Watch, bool - was any watch fired?)
+    """
+    watch_handled = False
+    alive_watches = []
+    while len(watches) > 0:
+        watch = watches.pop()
+
+        if watch.cancelled:
+            continue
+
+        watch_triggered = watch.is_triggered_by(trigger)
+        watch_handled |= watch_triggered
+
+        if watch.cancelled:
+            continue
+
+        if not any((watch_triggered, watch.oneshot, watch.cancelled)):
+            # Watch remains alive if it was NOT triggered, or it's NOT a oneshot
+            alive_watches.append(watch)
+    return alive_watches, watch_handled
+
+
 class Connection(object):
     """
     An object that manages a connection in a comprehensive way.
@@ -222,25 +250,8 @@ class Connection(object):
             watches = self.watches[frame.channel]  # a list
             self.watches[frame.channel] = []
 
-            alive_watches = []
-            while len(watches) > 0:
-                watch = watches.pop()
-
-                if watch.cancelled:
-                    # print('watch',watch,'was cancelled')
-                    continue
-
-                watch_triggered = watch.is_triggered_by(frame)
-                watch_handled |= watch_triggered
-
-                if watch.cancelled:
-                    # print('watch',watch,'was cancelled')
-                    continue
-
-                if ((not watch_triggered) or (not watch.oneshot)) and (
-                        not watch.cancelled):
-                    # Watch remains alive if it was NOT triggered, or it's NOT a oneshot
-                    alive_watches.append(watch)
+            alive_watches, f = alert_watches(watches, frame)
+            watch_handled |= f
 
             if frame.channel in self.watches:
                 # unwatch_all might have gotten called, check that
@@ -248,27 +259,11 @@ class Connection(object):
                     self.watches[frame.channel].append(watch)
 
         # ==================== process "any" watches
-        alive_watches = []
         any_watches = self.any_watches
         self.any_watches = []
-        while len(any_watches):
-            watch = any_watches.pop()
-
-            if watch.cancelled:
-                # print('any watch', watch, 'was cancelled')
-                continue
-
-            watch_triggered = watch.is_triggered_by(frame)
-            watch_handled |= watch_triggered
-
-            if watch.cancelled:
-                # print('any watch', watch, 'was cancelled')
-                continue
+        alive_watches, f = alert_watches(any_watches, frame)
 
-            if ((not watch_triggered) or (not watch.oneshot)) and (
-                    not watch.cancelled):
-                # Watch remains alive if it was NOT triggered, or it's NOT a oneshot
-                alive_watches.append(watch)
+        watch_handled |= f
 
         for watch in alive_watches:
             self.any_watches.append(watch)
diff --git a/setup.cfg b/setup.cfg
index 727a1befa4a34eb6ac43dbd06bf8f3203154e3e3..daeed6a7dba54953da7a5515fecd5d090e4028e0 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,7 @@
 [metadata]
 description-file = README.md
 name = CoolAMQP
-version = 0.93
+version = 0.94rc1
 license = MIT License
 classifiers = 
     Programming Language :: Python