You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2016/01/20 16:05:52 UTC

[2/5] qpid-proton git commit: PROTON-1083: [C++ binding] Completely separate internal/API handlers and events - There is now no inheritance relationship between proton_handler and messaging_handler - API handlers are messaging_handler/library internal is

PROTON-1083: [C++ binding] Completely separate internal/API handlers and events
- There is now no inheritance relationship between proton_handler and messaging_handler
- API handlers are messaging_handler/library internal is proton_handler
- API User has no access to lower level proton_handler
x Order of handler processing is subtly different now
-- flow controller gets called after user's event handler not before
- No inheritance relationship between proton_event and messaging_event/event
- Removed the old handler completely
- Removed a load of dynamic_casts that are now unnecessary
- A bunch of header include tidies up.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/d5c68c48
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/d5c68c48
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/d5c68c48

Branch: refs/heads/master
Commit: d5c68c48eb6be1c8afd96e5443341c5887ce964a
Parents: babdc00
Author: Andrew Stitcher <as...@apache.org>
Authored: Mon Jan 18 18:42:58 2016 -0500
Committer: Andrew Stitcher <as...@apache.org>
Committed: Wed Jan 20 00:51:32 2016 -0500

----------------------------------------------------------------------
 examples/cpp/broker.hpp                         |   3 +
 examples/cpp/client.cpp                         |   1 +
 examples/cpp/connection_options.cpp             |   1 +
 examples/cpp/direct_recv.cpp                    |   1 +
 examples/cpp/direct_send.cpp                    |   1 +
 examples/cpp/helloworld.cpp                     |   1 +
 examples/cpp/helloworld_direct.cpp              |   1 +
 examples/cpp/queue_browser.cpp                  |   1 +
 examples/cpp/recurring_timer.cpp                |   1 +
 examples/cpp/selected_recv.cpp                  |   1 +
 examples/cpp/server.cpp                         |   2 +
 examples/cpp/server_direct.cpp                  |   1 +
 examples/cpp/simple_recv.cpp                    |   1 +
 examples/cpp/simple_send.cpp                    |   1 +
 examples/cpp/ssl.cpp                            |   1 +
 examples/cpp/ssl_client_cert.cpp                |   1 +
 proton-c/bindings/cpp/CMakeLists.txt            |   1 -
 .../cpp/include/proton/connection_engine.hpp    |   4 +-
 .../cpp/include/proton/connection_options.hpp   |   6 +-
 .../bindings/cpp/include/proton/container.hpp   |   3 +-
 proton-c/bindings/cpp/include/proton/event.hpp  |   3 -
 .../bindings/cpp/include/proton/handler.hpp     |  69 ---
 proton-c/bindings/cpp/include/proton/link.hpp   |   2 +-
 .../cpp/include/proton/link_options.hpp         |   6 +-
 .../cpp/include/proton/messaging_adapter.hpp    |  70 ---
 .../cpp/include/proton/messaging_handler.hpp    |  29 +-
 .../cpp/include/proton/proton_handler.hpp       |  86 ----
 .../cpp/src/blocking_connection_impl.cpp        |   2 +-
 proton-c/bindings/cpp/src/blocking_fetcher.hpp  |   1 +
 proton-c/bindings/cpp/src/connection.cpp        |   1 -
 proton-c/bindings/cpp/src/connection_engine.cpp |  17 +-
 .../bindings/cpp/src/connection_options.cpp     |   9 +-
 proton-c/bindings/cpp/src/connector.cpp         |  18 +-
 proton-c/bindings/cpp/src/connector.hpp         |  17 +-
 proton-c/bindings/cpp/src/container.cpp         |  10 +-
 proton-c/bindings/cpp/src/container_impl.cpp    |  45 +-
 proton-c/bindings/cpp/src/container_impl.hpp    |  15 +-
 proton-c/bindings/cpp/src/contexts.cpp          |   4 +-
 proton-c/bindings/cpp/src/contexts.hpp          |   8 +-
 proton-c/bindings/cpp/src/event.cpp             |   1 -
 proton-c/bindings/cpp/src/handler.cpp           |  37 --
 proton-c/bindings/cpp/src/link.cpp              |   2 +-
 proton-c/bindings/cpp/src/link_options.cpp      |  11 +-
 proton-c/bindings/cpp/src/messaging_adapter.cpp | 377 +++++++--------
 proton-c/bindings/cpp/src/messaging_adapter.hpp |  70 +++
 proton-c/bindings/cpp/src/messaging_event.cpp   |  92 +---
 proton-c/bindings/cpp/src/messaging_event.hpp   |  18 +-
 proton-c/bindings/cpp/src/messaging_handler.cpp |  60 +--
 proton-c/bindings/cpp/src/proton_event.cpp      | 170 +++----
 proton-c/bindings/cpp/src/proton_event.hpp      | 484 +++++++++----------
 proton-c/bindings/cpp/src/proton_handler.cpp    |  92 ++--
 proton-c/bindings/cpp/src/proton_handler.hpp    | 104 ++++
 tests/tools/apps/cpp/reactor_send.cpp           |   1 +
 53 files changed, 860 insertions(+), 1104 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/broker.hpp
----------------------------------------------------------------------
diff --git a/examples/cpp/broker.hpp b/examples/cpp/broker.hpp
index 4cd4f4b..c89eb5d 100644
--- a/examples/cpp/broker.hpp
+++ b/examples/cpp/broker.hpp
@@ -27,7 +27,10 @@
  * the important differences between the examples.
  */
 
+#include "proton/event.hpp"
+#include "proton/message.hpp"
 #include "proton/messaging_handler.hpp"
+#include "proton/sender.hpp"
 #include "proton/url.hpp"
 
 #include <iostream>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/client.cpp b/examples/cpp/client.cpp
index f8186e0..704315b 100644
--- a/examples/cpp/client.cpp
+++ b/examples/cpp/client.cpp
@@ -21,6 +21,7 @@
 
 #include "options.hpp"
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/connection.hpp"
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/connection_options.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/connection_options.cpp b/examples/cpp/connection_options.cpp
index 6a79224..e40dac5 100644
--- a/examples/cpp/connection_options.cpp
+++ b/examples/cpp/connection_options.cpp
@@ -21,6 +21,7 @@
 
 #include "proton/container.hpp"
 #include "proton/messaging_handler.hpp"
+#include "proton/event.hpp"
 #include "proton/url.hpp"
 #include "proton/transport.hpp"
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/direct_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/direct_recv.cpp b/examples/cpp/direct_recv.cpp
index ad16d26..b027ef4 100644
--- a/examples/cpp/direct_recv.cpp
+++ b/examples/cpp/direct_recv.cpp
@@ -23,6 +23,7 @@
 
 #include "proton/container.hpp"
 #include "proton/acceptor.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/link.hpp"
 #include "proton/url.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/direct_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/direct_send.cpp b/examples/cpp/direct_send.cpp
index 0b7095e..def523f 100644
--- a/examples/cpp/direct_send.cpp
+++ b/examples/cpp/direct_send.cpp
@@ -24,6 +24,7 @@
 #include "proton/acceptor.hpp"
 #include "proton/connection.hpp"
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/value.hpp"
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/helloworld.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld.cpp b/examples/cpp/helloworld.cpp
index b18c151..15ffe54 100644
--- a/examples/cpp/helloworld.cpp
+++ b/examples/cpp/helloworld.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/url.hpp"
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/helloworld_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld_direct.cpp b/examples/cpp/helloworld_direct.cpp
index 5e4c316..3b53e17 100644
--- a/examples/cpp/helloworld_direct.cpp
+++ b/examples/cpp/helloworld_direct.cpp
@@ -21,6 +21,7 @@
 
 #include "proton/acceptor.hpp"
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 
 #include <iostream>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/queue_browser.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/queue_browser.cpp b/examples/cpp/queue_browser.cpp
index 1206c71..56b8015 100644
--- a/examples/cpp/queue_browser.cpp
+++ b/examples/cpp/queue_browser.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/url.hpp"
 #include "proton/link_options.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/recurring_timer.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/recurring_timer.cpp b/examples/cpp/recurring_timer.cpp
index d234b4c..1987357 100644
--- a/examples/cpp/recurring_timer.cpp
+++ b/examples/cpp/recurring_timer.cpp
@@ -22,6 +22,7 @@
 #include "options.hpp"
 
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/task.hpp"
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/selected_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/selected_recv.cpp b/examples/cpp/selected_recv.cpp
index d591fd6..16bab7c 100644
--- a/examples/cpp/selected_recv.cpp
+++ b/examples/cpp/selected_recv.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/url.hpp"
 #include "proton/link_options.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/server.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server.cpp b/examples/cpp/server.cpp
index fc2b462..db186ba 100644
--- a/examples/cpp/server.cpp
+++ b/examples/cpp/server.cpp
@@ -21,7 +21,9 @@
 
 #include "options.hpp"
 
+#include "proton/connection.hpp"
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/url.hpp"
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/server_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server_direct.cpp b/examples/cpp/server_direct.cpp
index 7ad5889..c29757c 100644
--- a/examples/cpp/server_direct.cpp
+++ b/examples/cpp/server_direct.cpp
@@ -23,6 +23,7 @@
 
 #include "proton/acceptor.hpp"
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/url.hpp"
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/simple_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_recv.cpp b/examples/cpp/simple_recv.cpp
index 1e0d071..a28b793 100644
--- a/examples/cpp/simple_recv.cpp
+++ b/examples/cpp/simple_recv.cpp
@@ -22,6 +22,7 @@
 #include "options.hpp"
 
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/link.hpp"
 #include "proton/value.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/simple_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_send.cpp b/examples/cpp/simple_send.cpp
index 64c34bf..0f627ed 100644
--- a/examples/cpp/simple_send.cpp
+++ b/examples/cpp/simple_send.cpp
@@ -22,6 +22,7 @@
 #include "options.hpp"
 
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/connection.hpp"
 #include "proton/value.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/ssl.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl.cpp b/examples/cpp/ssl.cpp
index 568e223..fb775b2 100644
--- a/examples/cpp/ssl.cpp
+++ b/examples/cpp/ssl.cpp
@@ -21,6 +21,7 @@
 
 #include "proton/acceptor.hpp"
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/connection_options.hpp"
 #include "proton/transport.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/examples/cpp/ssl_client_cert.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/ssl_client_cert.cpp b/examples/cpp/ssl_client_cert.cpp
index 7a9f411..10218ee 100644
--- a/examples/cpp/ssl_client_cert.cpp
+++ b/examples/cpp/ssl_client_cert.cpp
@@ -21,6 +21,7 @@
 
 #include "proton/acceptor.hpp"
 #include "proton/container.hpp"
+#include "proton/event.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/connection_options.hpp"
 #include "proton/transport.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index be8cc1c..4c55af4 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -48,7 +48,6 @@ set(qpid-proton-cpp-source
   src/connection_engine.cpp
   src/error.cpp
   src/event.cpp
-  src/handler.cpp
   src/link.cpp
   src/link_options.cpp
   src/message.cpp

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/include/proton/connection_engine.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection_engine.hpp b/proton-c/bindings/cpp/include/proton/connection_engine.hpp
index 3a39be1..28ecce4 100644
--- a/proton-c/bindings/cpp/include/proton/connection_engine.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection_engine.hpp
@@ -28,7 +28,7 @@
 
 namespace proton {
 
-class handler;
+class messaging_handler;
 class connection;
 
 /// Pointers to a byte range to use as a buffer.
@@ -84,7 +84,7 @@ class connection_engine {
     /**
      * Create an engine that will advertise id as the AMQP container-id for its connection.
      */
-    PN_CPP_EXTERN connection_engine(handler&, const std::string& id=std::string());
+    PN_CPP_EXTERN connection_engine(messaging_handler&, const std::string& id=std::string());
 
     PN_CPP_EXTERN ~connection_engine();
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/include/proton/connection_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection_options.hpp b/proton-c/bindings/cpp/include/proton/connection_options.hpp
index e221e5b..633fd82 100644
--- a/proton-c/bindings/cpp/include/proton/connection_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection_options.hpp
@@ -32,7 +32,7 @@
 
 namespace proton {
 
-class handler;
+class proton_handler;
 class connection;
 
 /** Options for creating a connection.
@@ -63,7 +63,7 @@ class connection_options {
 
     // TODO: Document options
 
-    PN_CPP_EXTERN connection_options& handler(class handler *);
+    PN_CPP_EXTERN connection_options& handler(class messaging_handler *);
     PN_CPP_EXTERN connection_options& max_frame_size(uint32_t max);
     PN_CPP_EXTERN connection_options& max_channels(uint16_t max);
     PN_CPP_EXTERN connection_options& idle_timeout(uint32_t t);
@@ -82,7 +82,7 @@ class connection_options {
 
   private:
     void apply(connection&) const;
-    class handler* handler() const;
+    proton_handler* handler() const;
     static pn_connection_t *pn_connection(connection &);
     class client_domain &client_domain();
     class server_domain &server_domain();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/include/proton/container.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/container.hpp b/proton-c/bindings/cpp/include/proton/container.hpp
index 7c417de..d4dac36 100644
--- a/proton-c/bindings/cpp/include/proton/container.hpp
+++ b/proton-c/bindings/cpp/include/proton/container.hpp
@@ -87,7 +87,7 @@ class container {
     PN_CPP_EXTERN class reactor reactor() const;
 
     // Schedule a timer task event in delay milliseconds.
-    PN_CPP_EXTERN task schedule(int delay, handler *h = 0);
+    PN_CPP_EXTERN task schedule(int delay, messaging_handler *h = 0);
 
     /** Copy the connection options to a template which will be
         applied to subsequent outgoing connections.  These are applied first
@@ -108,6 +108,7 @@ class container {
 
   private:
     pn_unique_ptr<container_impl> impl_;
+    friend class connector;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/include/proton/event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/event.hpp b/proton-c/bindings/cpp/include/proton/event.hpp
index ea8ded2..62dd9b0 100644
--- a/proton-c/bindings/cpp/include/proton/event.hpp
+++ b/proton-c/bindings/cpp/include/proton/event.hpp
@@ -39,9 +39,6 @@ class event {
   public:
     virtual PN_CPP_EXTERN ~event();
 
-    /// Dispatch this event to a handler.
-    virtual PN_CPP_EXTERN void dispatch(handler &h) = 0;
-
     /// Return the name of the event type
     virtual PN_CPP_EXTERN std::string name() const = 0;
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/include/proton/handler.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/handler.hpp b/proton-c/bindings/cpp/include/proton/handler.hpp
deleted file mode 100644
index 9b8f5e9..0000000
--- a/proton-c/bindings/cpp/include/proton/handler.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef PROTON_CPP_HANDLER_H
-#define PROTON_CPP_HANDLER_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "proton/export.hpp"
-#include "proton/event.hpp"
-#include "proton/event.h"
-#include "proton/reactor.h"
-#include <vector>
-
-namespace proton {
-
-/** Base class for event handlers.
- *
- * A handler can have child handlers which are called in order, after the parent handler.
- *
- * Note: handlers are not deleted automatically. They must not be deleted while
- * they are still in use.
- *
- * There are two simple strategies you can use:
- *
- * 1. Destroy handlers only after the container that uses them is closed.
- *
- * 2. Allocate handlers with `new` and call `delete this` in the appropriate
- * `on_*_closed` or `on_*_final` event that indicates the handler is no longer needed.
- *
- */
-class handler {
-  public:
-    PN_CPP_EXTERN handler();
-    PN_CPP_EXTERN virtual ~handler();
-
-    /// Called if a handler function is not over-ridden to handle an event.
-    PN_CPP_EXTERN virtual void on_unhandled(event &e);
-
-    /// Add a child handler, equivalent to this->push_back(&h)
-    /// h must not be deleted before this handler.
-    PN_CPP_EXTERN virtual void add_child_handler(handler &h);
-
-  public:
-    std::vector<handler*> children_;
-    typedef std::vector<handler*>::iterator iterator;
-  private:
-    pn_ptr<pn_handler_t> pn_handler_;
-    friend class container_impl;
-};
-
-}
-
-#endif  /*!PROTON_CPP_HANDLER_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/include/proton/link.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/link.hpp b/proton-c/bindings/cpp/include/proton/link.hpp
index aafaf77..c876fa0 100644
--- a/proton-c/bindings/cpp/include/proton/link.hpp
+++ b/proton-c/bindings/cpp/include/proton/link.hpp
@@ -104,7 +104,7 @@ class link : public object<pn_link_t> , public endpoint
     PN_CPP_EXTERN class session session() const;
 
     /** Set a custom handler for this link. */
-    PN_CPP_EXTERN void handler(class handler &);
+    PN_CPP_EXTERN void handler(proton_handler &);
 
     /** Unset any custom handler */
     PN_CPP_EXTERN void detach_handler();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/include/proton/link_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/link_options.hpp b/proton-c/bindings/cpp/include/proton/link_options.hpp
index f3c5da6..02613c1 100644
--- a/proton-c/bindings/cpp/include/proton/link_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/link_options.hpp
@@ -58,7 +58,7 @@ enum lifetime_policy_t {
     DELETE_ON_NO_LINKS_OR_MESSAGES = 0x2E
 };
 
-class handler;
+class proton_handler;
 class link;
 
 /** Options for creating a link.
@@ -88,7 +88,7 @@ class link_options {
     PN_CPP_EXTERN void override(const link_options& other);
 
     /** Set a handler for events scoped to the link.  If NULL, link-scoped events on the link are discarded. */
-    PN_CPP_EXTERN link_options& handler(class handler *);
+    PN_CPP_EXTERN link_options& handler(class messaging_handler *);
     /** Receiver-only option to specify whether messages are browsed or
         consumed.  Setting browsing to true is Equivalent to setting
         distribution_mode(COPY).  Setting browsing to false is equivalent to
@@ -115,7 +115,7 @@ class link_options {
   private:
     friend class link;
     void apply(link&) const;
-    class handler* handler() const;
+    proton_handler* handler() const;
 
     class impl;
     pn_unique_ptr<impl> impl_;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp b/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
deleted file mode 100644
index 5a52658..0000000
--- a/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef PROTON_CPP_MESSAGING_ADAPTER_H
-#define PROTON_CPP_MESSAGING_ADAPTER_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "proton/messaging_handler.hpp"
-
-#include "proton/event.h"
-#include "proton/reactor.h"
-
-///@cond INTERNAL
-
-namespace proton {
-
-// Combine's Python's: endpoint_state_handler, incoming_message_handler, outgoing_message_handler
-
-class messaging_adapter : public proton_handler, public messaging_handler
-{
-  public:
-    PN_CPP_EXTERN messaging_adapter(messaging_handler &delegate);
-    PN_CPP_EXTERN virtual ~messaging_adapter();
-    PN_CPP_EXTERN virtual void on_reactor_init(event &e);
-    PN_CPP_EXTERN virtual void on_link_flow(event &e);
-    PN_CPP_EXTERN virtual void on_delivery(event &e);
-    PN_CPP_EXTERN virtual void on_unhandled(event &e);
-    PN_CPP_EXTERN virtual void on_connection_remote_open(event &e);
-    PN_CPP_EXTERN virtual void on_connection_remote_close(event &e);
-    PN_CPP_EXTERN virtual void on_session_remote_open(event &e);
-    PN_CPP_EXTERN virtual void on_session_remote_close(event &e);
-    PN_CPP_EXTERN virtual void on_link_remote_open(event &e);
-    PN_CPP_EXTERN virtual void on_link_remote_close(event &e);
-    PN_CPP_EXTERN virtual void on_transport_tail_closed(event &e);
-
-    PN_CPP_EXTERN virtual void on_connection_close(event &e);
-    PN_CPP_EXTERN virtual void on_connection_error(event &e);
-    PN_CPP_EXTERN virtual void on_connection_open(event &e);
-    PN_CPP_EXTERN virtual void on_session_close(event &e);
-    PN_CPP_EXTERN virtual void on_session_error(event &e);
-    PN_CPP_EXTERN virtual void on_session_open(event &e);
-    PN_CPP_EXTERN virtual void on_link_close(event &e);
-    PN_CPP_EXTERN virtual void on_link_error(event &e);
-    PN_CPP_EXTERN virtual void on_link_open(event &e);
-
-    PN_CPP_EXTERN virtual void on_timer_task(event &e);
-  private:
-    messaging_handler &delegate_;  // The handler for generated messaging_event's
-};
-
-}
-///@endcond INTERNAL
-#endif  /*!PROTON_CPP_MESSAGING_ADAPTER_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/include/proton/messaging_handler.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/messaging_handler.hpp b/proton-c/bindings/cpp/include/proton/messaging_handler.hpp
index 39dc3e0..5a20b81 100644
--- a/proton-c/bindings/cpp/include/proton/messaging_handler.hpp
+++ b/proton-c/bindings/cpp/include/proton/messaging_handler.hpp
@@ -21,9 +21,9 @@
  * under the License.
  *
  */
-
-#include "proton/proton_handler.hpp"
+#include "proton/export.hpp"
 #include "proton/event.h"
+#include "proton/pn_unique_ptr.hpp"
 
 #include <stdexcept>
 
@@ -32,17 +32,12 @@ namespace proton {
 class event;
 class messaging_adapter;
 
-class messaging_exception : public std::runtime_error {
-  public:
-    messaging_exception(event& e);
-};
-
 /** messaging_handler base class. Provides a simpler set of events than
  * proton::proton_handler and automates some common tasks.  Subclass and
  * over-ride event handling member functions.
  * @see proton::messaging_event for meaning of events.
  */
-class messaging_handler : virtual public handler
+class messaging_handler
 {
   public:
     /** Create a messaging_handler
@@ -85,21 +80,17 @@ class messaging_handler : virtual public handler
     PN_CPP_EXTERN virtual void on_transaction_abort(event &e);
 
     PN_CPP_EXTERN virtual void on_timer(event &e);
+
+    PN_CPP_EXTERN virtual void on_unhandled(event &e);
+    PN_CPP_EXTERN virtual void on_unhandled_error(event &e);
     ///@}
 
   private:
-    int prefetch_;
-    bool auto_accept_;
-    bool auto_settle_;
-    bool peer_close_iserror_;
     pn_unique_ptr<messaging_adapter> messaging_adapter_;
-    pn_unique_ptr<handler> flow_controller_;
-    PN_CPP_EXTERN messaging_handler(
-        bool raw_handler, int prefetch=10, bool auto_accept=true,
-        bool auto_settle=true, bool peer_close_is_error=false);
-    friend class container_impl;
-    friend class messaging_adapter;
-    PN_CPP_EXTERN void create_helpers();
+    friend class container;
+    friend class connection_engine;
+    friend class connection_options;
+    friend class link_options;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/include/proton/proton_handler.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/proton_handler.hpp b/proton-c/bindings/cpp/include/proton/proton_handler.hpp
deleted file mode 100644
index 4d22770..0000000
--- a/proton-c/bindings/cpp/include/proton/proton_handler.hpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef PROTON_CPP_PROTONHANDLER_H
-#define PROTON_CPP_PROTONHANDLER_H
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "proton/handler.hpp"
-
-namespace proton {
-
-class event;
-class proton_event;
-
-/// Handler base class, subclass and over-ride event handling member functions.
-/// @see proton::proton_event for meaning of events.
-class proton_handler : virtual public handler
-{
-  public:
-    PN_CPP_EXTERN proton_handler();
-
-    ///@name Over-ride these member functions to handle events
-    ///@{
-    PN_CPP_EXTERN virtual void on_reactor_init(event &e);
-    PN_CPP_EXTERN virtual void on_reactor_quiesced(event &e);
-    PN_CPP_EXTERN virtual void on_reactor_final(event &e);
-    PN_CPP_EXTERN virtual void on_timer_task(event &e);
-    PN_CPP_EXTERN virtual void on_connection_init(event &e);
-    PN_CPP_EXTERN virtual void on_connection_bound(event &e);
-    PN_CPP_EXTERN virtual void on_connection_unbound(event &e);
-    PN_CPP_EXTERN virtual void on_connection_local_open(event &e);
-    PN_CPP_EXTERN virtual void on_connection_local_close(event &e);
-    PN_CPP_EXTERN virtual void on_connection_remote_open(event &e);
-    PN_CPP_EXTERN virtual void on_connection_remote_close(event &e);
-    PN_CPP_EXTERN virtual void on_connection_final(event &e);
-    PN_CPP_EXTERN virtual void on_session_init(event &e);
-    PN_CPP_EXTERN virtual void on_session_local_open(event &e);
-    PN_CPP_EXTERN virtual void on_session_local_close(event &e);
-    PN_CPP_EXTERN virtual void on_session_remote_open(event &e);
-    PN_CPP_EXTERN virtual void on_session_remote_close(event &e);
-    PN_CPP_EXTERN virtual void on_session_final(event &e);
-    PN_CPP_EXTERN virtual void on_link_init(event &e);
-    PN_CPP_EXTERN virtual void on_link_local_open(event &e);
-    PN_CPP_EXTERN virtual void on_link_local_close(event &e);
-    PN_CPP_EXTERN virtual void on_link_local_detach(event &e);
-    PN_CPP_EXTERN virtual void on_link_remote_open(event &e);
-    PN_CPP_EXTERN virtual void on_link_remote_close(event &e);
-    PN_CPP_EXTERN virtual void on_link_remote_detach(event &e);
-    PN_CPP_EXTERN virtual void on_link_flow(event &e);
-    PN_CPP_EXTERN virtual void on_link_final(event &e);
-    PN_CPP_EXTERN virtual void on_delivery(event &e);
-    PN_CPP_EXTERN virtual void on_transport(event &e);
-    PN_CPP_EXTERN virtual void on_transport_error(event &e);
-    PN_CPP_EXTERN virtual void on_transport_head_closed(event &e);
-    PN_CPP_EXTERN virtual void on_transport_tail_closed(event &e);
-    PN_CPP_EXTERN virtual void on_transport_closed(event &e);
-    PN_CPP_EXTERN virtual void on_selectable_init(event &e);
-    PN_CPP_EXTERN virtual void on_selectable_updated(event &e);
-    PN_CPP_EXTERN virtual void on_selectable_readable(event &e);
-    PN_CPP_EXTERN virtual void on_selectable_writable(event &e);
-    PN_CPP_EXTERN virtual void on_selectable_expired(event &e);
-    PN_CPP_EXTERN virtual void on_selectable_error(event &e);
-    PN_CPP_EXTERN virtual void on_selectable_final(event &e);
-    PN_CPP_EXTERN virtual void on_unhandled(event &e);
-    ///@}
-};
-
-}
-
-#endif  /*!PROTON_CPP_PROTONHANDLER_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/blocking_connection_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_connection_impl.cpp b/proton-c/bindings/cpp/src/blocking_connection_impl.cpp
index e0b7c93..db457b0 100644
--- a/proton-c/bindings/cpp/src/blocking_connection_impl.cpp
+++ b/proton-c/bindings/cpp/src/blocking_connection_impl.cpp
@@ -50,7 +50,7 @@ blocking_connection_impl::blocking_connection_impl(const url& url, duration time
 {
     container_->reactor().start();
     container_->reactor().timeout(timeout);
-    handler *h = static_cast<handler*>(this); // Set this as handler.
+    messaging_handler* h = this; // Set this as handler.
     connection_ = container_->connect(url, connection_options().handler(h));
     wait(connection_opening(connection_));
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/blocking_fetcher.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_fetcher.hpp b/proton-c/bindings/cpp/src/blocking_fetcher.hpp
index d766bfc..337df3e 100644
--- a/proton-c/bindings/cpp/src/blocking_fetcher.hpp
+++ b/proton-c/bindings/cpp/src/blocking_fetcher.hpp
@@ -21,6 +21,7 @@
  * under the License.
  *
  */
+#include "proton/delivery.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/message.hpp"
 #include <string>

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/connection.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connection.cpp b/proton-c/bindings/cpp/src/connection.cpp
index 7469954..75465af 100644
--- a/proton-c/bindings/cpp/src/connection.cpp
+++ b/proton-c/bindings/cpp/src/connection.cpp
@@ -21,7 +21,6 @@
 #include "proton/container.hpp"
 #include "proton/connection.hpp"
 #include "proton/transport.hpp"
-#include "proton/handler.hpp"
 #include "proton/session.hpp"
 #include "proton/error.hpp"
 #include "connector.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/connection_engine.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connection_engine.cpp b/proton-c/bindings/cpp/src/connection_engine.cpp
index 2fadd00..639bd3c 100644
--- a/proton-c/bindings/cpp/src/connection_engine.cpp
+++ b/proton-c/bindings/cpp/src/connection_engine.cpp
@@ -19,10 +19,12 @@
 
 #include "proton/connection_engine.hpp"
 #include "proton/error.hpp"
+#include "proton/messaging_handler.hpp"
 
-#include "uuid.hpp"
-#include "proton_bits.hpp"
+#include "messaging_adapter.hpp"
 #include "messaging_event.hpp"
+#include "proton_bits.hpp"
+#include "uuid.hpp"
 
 #include <proton/connection.h>
 #include <proton/transport.h>
@@ -32,7 +34,7 @@ namespace proton {
 
 struct connection_engine::impl {
 
-    impl(class handler& h, pn_transport_t *t) :
+    impl(class proton_handler& h, pn_transport_t *t) :
         handler(h), transport(t), connection(pn_connection()), collector(pn_collector())
     {}
 
@@ -50,13 +52,14 @@ struct connection_engine::impl {
     pn_event_t *peek() { return pn_collector_peek(collector); }
     void pop() { pn_collector_pop(collector); }
 
-    class handler& handler;
+    class proton_handler& handler;
     pn_transport_t *transport;
     pn_connection_t *connection;
     pn_collector_t * collector;
 };
 
-connection_engine::connection_engine(handler &h, const std::string& id_) : impl_(new impl(h, pn_transport())) {
+connection_engine::connection_engine(messaging_handler &h, const std::string& id_) :
+    impl_(new impl(*h.messaging_adapter_.get(), pn_transport())) {
     if (!impl_->transport || !impl_->connection || !impl_->collector)
         throw error("connection_engine setup failed");
     std::string id = id_.empty() ? uuid().str() : id_;
@@ -96,8 +99,8 @@ void connection_engine::run() {
           default:
             break;
         }
-        messaging_event mevent(e, pn_event_type(e), 0);
-        mevent.dispatch(impl_->handler);
+        proton_event pevent(e, pn_event_type(e), 0);
+        pevent.dispatch(impl_->handler);
         impl_->pop();
     }
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/connection_options.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connection_options.cpp b/proton-c/bindings/cpp/src/connection_options.cpp
index 3a3e0e1..4e5fb44 100644
--- a/proton-c/bindings/cpp/src/connection_options.cpp
+++ b/proton-c/bindings/cpp/src/connection_options.cpp
@@ -19,12 +19,15 @@
  *
  */
 #include "proton/connection_options.hpp"
+#include "proton/messaging_handler.hpp"
 #include "proton/reconnect_timer.hpp"
 #include "proton/transport.hpp"
 #include "proton/ssl.hpp"
 #include "proton/sasl.hpp"
+
 #include "contexts.hpp"
 #include "connector.hpp"
+#include "messaging_adapter.hpp"
 #include "msg.hpp"
 
 #include "proton/transport.h"
@@ -42,7 +45,7 @@ template <class T> struct option {
 
 class connection_options::impl {
   public:
-    option<class handler*> handler;
+    option<proton_handler*> handler;
     option<uint32_t> max_frame_size;
     option<uint16_t> max_channels;
     option<uint32_t> idle_timeout;
@@ -155,7 +158,7 @@ connection_options& connection_options::operator=(const connection_options& x) {
 
 void connection_options::override(const connection_options& x) { impl_->override(*x.impl_); }
 
-connection_options& connection_options::handler(class handler *h) { impl_->handler = h; return *this; }
+connection_options& connection_options::handler(class messaging_handler *h) { impl_->handler = h->messaging_adapter_.get(); return *this; }
 connection_options& connection_options::max_frame_size(uint32_t n) { impl_->max_frame_size = n; return *this; }
 connection_options& connection_options::max_channels(uint16_t n) { impl_->max_frame_size = n; return *this; }
 connection_options& connection_options::idle_timeout(uint32_t t) { impl_->idle_timeout = t; return *this; }
@@ -175,6 +178,6 @@ connection_options& connection_options::sasl_config_path(const std::string &p) {
 void connection_options::apply(connection& c) const { impl_->apply(c); }
 class client_domain &connection_options::client_domain() { return impl_->client_domain.value; }
 class server_domain &connection_options::server_domain() { return impl_->server_domain.value; }
-handler* connection_options::handler() const { return impl_->handler.value; }
+proton_handler* connection_options::handler() const { return impl_->handler.value; }
 pn_connection_t* connection_options::pn_connection(connection &c) { return c.pn_object(); }
 } // namespace proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/connector.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connector.cpp b/proton-c/bindings/cpp/src/connector.cpp
index 9469496..4e5139c 100644
--- a/proton-c/bindings/cpp/src/connector.cpp
+++ b/proton-c/bindings/cpp/src/connector.cpp
@@ -20,15 +20,17 @@
  */
 
 #include "connector.hpp"
+
 #include "proton/connection.hpp"
 #include "proton/transport.hpp"
 #include "proton/container.hpp"
-#include "proton/event.hpp"
 #include "proton/url.hpp"
 #include "proton/reconnect_timer.hpp"
 #include "proton/task.hpp"
 #include "proton/sasl.hpp"
+
 #include "container_impl.hpp"
+#include "proton_event.hpp"
 
 #include "proton/connection.h"
 #include "proton/transport.h"
@@ -74,24 +76,24 @@ void connector::connect() {
     transport_configured_ = true;
 }
 
-void connector::on_connection_local_open(event &) {
+void connector::on_connection_local_open(proton_event &) {
     connect();
 }
 
-void connector::on_connection_remote_open(event &) {
+void connector::on_connection_remote_open(proton_event &) {
     if (reconnect_timer_) {
         reconnect_timer_->reset();
     }
 }
 
-void connector::on_connection_init(event &) {
+void connector::on_connection_init(proton_event &) {
 }
 
-void connector::on_transport_tail_closed(event &e) {
+void connector::on_transport_tail_closed(proton_event &e) {
     on_transport_closed(e);
 }
 
-void connector::on_transport_closed(event &e) {
+void connector::on_transport_closed(proton_event &e) {
     if (!connection_) return;
     if (connection_.state() & endpoint::LOCAL_ACTIVE) {
         if (reconnect_timer_) {
@@ -106,7 +108,7 @@ void connector::on_transport_closed(event &e) {
                 }
                 else {
                     // log "Disconnected, reconnecting in " <<  delay << " milliseconds"
-                    connection_.container().schedule(delay, this);
+                    connection_.container().impl_.get()->schedule(delay, this);
                     return;
                 }
             }
@@ -116,7 +118,7 @@ void connector::on_transport_closed(event &e) {
     connection_  = 0;
 }
 
-void connector::on_timer_task(event &) {
+void connector::on_timer_task(proton_event &) {
     connect();
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/connector.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connector.hpp b/proton-c/bindings/cpp/src/connector.hpp
index 458e2ba..65a1db4 100644
--- a/proton-c/bindings/cpp/src/connector.hpp
+++ b/proton-c/bindings/cpp/src/connector.hpp
@@ -22,11 +22,14 @@
  *
  */
 
-#include "proton/proton_handler.hpp"
+#include "proton/connection.hpp"
 #include "proton/connection_options.hpp"
 #include "proton/url.hpp"
 #include "proton/event.h"
 #include "proton/reactor.h"
+
+#include "proton_handler.hpp"
+
 #include <string>
 
 
@@ -48,12 +51,12 @@ class connector : public proton_handler
     void apply_options();
     void reconnect_timer(const class reconnect_timer &);
     bool transport_configured();
-    virtual void on_connection_local_open(event &e);
-    virtual void on_connection_remote_open(event &e);
-    virtual void on_connection_init(event &e);
-    virtual void on_transport_closed(event &e);
-    virtual void on_transport_tail_closed(event &e);
-    virtual void on_timer_task(event &e);
+    virtual void on_connection_local_open(proton_event &e);
+    virtual void on_connection_remote_open(proton_event &e);
+    virtual void on_connection_init(proton_event &e);
+    virtual void on_transport_closed(proton_event &e);
+    virtual void on_transport_tail_closed(proton_event &e);
+    virtual void on_timer_task(proton_event &e);
 
   private:
     connection connection_;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/container.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container.cpp b/proton-c/bindings/cpp/src/container.cpp
index 01dcf2a..60bfcbd 100644
--- a/proton-c/bindings/cpp/src/container.cpp
+++ b/proton-c/bindings/cpp/src/container.cpp
@@ -19,11 +19,10 @@
  *
  */
 #include "proton/container.hpp"
-#include "messaging_event.hpp"
+
 #include "proton/connection.hpp"
 #include "proton/link_options.hpp"
 #include "proton/session.hpp"
-#include "proton/messaging_adapter.hpp"
 #include "proton/acceptor.hpp"
 #include "proton/error.hpp"
 #include "proton/url.hpp"
@@ -34,6 +33,9 @@
 #include "container_impl.hpp"
 #include "connector.hpp"
 #include "contexts.hpp"
+#include "messaging_adapter.hpp"
+#include "messaging_event.hpp"
+
 #include "proton/connection.h"
 #include "proton/session.h"
 
@@ -46,7 +48,7 @@ container::container(const std::string& id) {
 }
 
 container::container(messaging_handler &mhandler, const std::string& id) {
-    impl_.reset(new container_impl(*this, &mhandler, id));
+    impl_.reset(new container_impl(*this, mhandler.messaging_adapter_.get(), id));
 }
 
 container::~container() {}
@@ -73,7 +75,7 @@ acceptor container::listen(const proton::url &url, const connection_options &opt
     return impl_->listen(url, opts);
 }
 
-task container::schedule(int delay, handler *h) { return impl_->schedule(delay, h); }
+task container::schedule(int delay, messaging_handler *h) { return impl_->schedule(delay, h ? h->messaging_adapter_.get() : 0); }
 
 void container::client_connection_options(const connection_options &o) { impl_->client_connection_options(o); }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.cpp b/proton-c/bindings/cpp/src/container_impl.cpp
index 5a50cdd..dcc48a9 100644
--- a/proton-c/bindings/cpp/src/container_impl.cpp
+++ b/proton-c/bindings/cpp/src/container_impl.cpp
@@ -21,10 +21,8 @@
 #include "proton/container.hpp"
 #include "proton/connection_options.hpp"
 #include "proton/event.hpp"
-#include "messaging_event.hpp"
 #include "proton/connection.hpp"
 #include "proton/session.hpp"
-#include "proton/messaging_adapter.hpp"
 #include "proton/acceptor.hpp"
 #include "proton/error.hpp"
 #include "proton/url.hpp"
@@ -35,10 +33,12 @@
 #include "proton/sasl.hpp"
 #include "proton/transport.hpp"
 
-#include "msg.hpp"
-#include "container_impl.hpp"
 #include "connector.hpp"
+#include "container_impl.hpp"
 #include "contexts.hpp"
+#include "messaging_adapter.hpp"
+#include "messaging_event.hpp"
+#include "msg.hpp"
 #include "uuid.hpp"
 
 #include "proton/connection.h"
@@ -67,18 +67,18 @@ struct handler_context {
     static void dispatch(pn_handler_t *c_handler, pn_event_t *c_event, pn_event_type_t type)
     {
         handler_context& hc(handler_context::get(c_handler));
-        messaging_event mevent(c_event, type, hc.container_);
-        mevent.dispatch(*hc.handler_);
+        proton_event pevent(c_event, type, hc.container_);
+        pevent.dispatch(*hc.handler_);
         return;
     }
 
     container *container_;
-    handler *handler_;
+    proton_handler *handler_;
 };
 
 
 // Used to sniff for connector events before the reactor's global handler sees them.
-class override_handler : public handler
+class override_handler : public proton_handler
 {
   public:
     pn_ptr<pn_handler_t> base_handler;
@@ -86,22 +86,19 @@ class override_handler : public handler
 
     override_handler(pn_handler_t *h, container_impl &c) : base_handler(h), container_impl_(c) {}
 
-    virtual void on_unhandled(event &e) {
-        proton_event *pne = dynamic_cast<proton_event *>(&e);
-        // If not a Proton reactor event, nothing to override, nothing to pass along.
-        if (!pne) return;
-        int type = pne->type();
-        if (!type) return;  // Also not from the reactor
+    virtual void on_unhandled(proton_event &pe) {
+        proton_event::event_type type = pe.type();
+        if (type==proton_event::EVENT_NONE) return;  // Also not from the reactor
 
-        pn_event_t *cevent = pne->pn_event();
+        pn_event_t *cevent = pe.pn_event();
         pn_connection_t *conn = pn_event_connection(cevent);
         if (conn) {
-            handler *override = connection_context::get(conn).handler.get();
-            if (override && type != PN_CONNECTION_INIT) {
+            proton_handler *override = connection_context::get(conn).handler.get();
+            if (override && type != proton_event::CONNECTION_INIT) {
                 // Send event to connector
-                e.dispatch(*override);
+                pe.dispatch(*override);
             }
-            else if (!override && type == PN_CONNECTION_INIT) {
+            else if (!override && type == proton_event::CONNECTION_INIT) {
                 // Newly accepted connection from lister socket
                 connection c(conn);
                 container_impl_.configure_server_connection(c);
@@ -113,7 +110,7 @@ class override_handler : public handler
 
 } // namespace
 
-pn_ptr<pn_handler_t> container_impl::cpp_handler(handler *h) {
+pn_ptr<pn_handler_t> container_impl::cpp_handler(proton_handler *h) {
     if (!h->pn_handler_) {
         h->pn_handler_ = take_ownership(
             pn_handler_new(&handler_context::dispatch,
@@ -126,7 +123,7 @@ pn_ptr<pn_handler_t> container_impl::cpp_handler(handler *h) {
     return h->pn_handler_;
 }
 
-container_impl::container_impl(container& c, handler *h, const std::string& id) :
+container_impl::container_impl(container& c, messaging_adapter *h, const std::string& id) :
     container_(c), reactor_(reactor::create()), handler_(h), id_(id),
     link_id_(0)
 {
@@ -154,7 +151,7 @@ container_impl::~container_impl() {}
 connection container_impl::connect(const proton::url &url, const connection_options &user_opts) {
     connection_options opts = client_connection_options(); // Defaults
     opts.override(user_opts);
-    handler *h = opts.handler();
+    proton_handler *h = opts.handler();
 
     pn_ptr<pn_handler_t> chandler = h ? cpp_handler(h) : pn_ptr<pn_handler_t>();
     connection conn(reactor_.connection(chandler.get()));
@@ -196,7 +193,7 @@ receiver container_impl::open_receiver(const proton::url &url, const proton::lin
 acceptor container_impl::listen(const proton::url& url, const connection_options &user_opts) {
     connection_options opts = server_connection_options(); // Defaults
     opts.override(user_opts);
-    handler *h = opts.handler();
+    proton_handler *h = opts.handler();
     pn_ptr<pn_handler_t> chandler = h ? cpp_handler(h) : pn_ptr<pn_handler_t>();
     pn_acceptor_t *acptr = pn_reactor_acceptor(reactor_.pn_object(), url.host().c_str(), url.port().c_str(), chandler.get());
     if (!acptr)
@@ -218,7 +215,7 @@ std::string container_impl::next_link_name() {
     return s.str();
 }
 
-task container_impl::schedule(int delay, handler *h) {
+task container_impl::schedule(int delay, proton_handler *h) {
     pn_ptr<pn_handler_t> task_handler;
     if (h)
         task_handler = cpp_handler(h);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/container_impl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.hpp b/proton-c/bindings/cpp/src/container_impl.hpp
index 66c3aa6..035fb18 100644
--- a/proton-c/bindings/cpp/src/container_impl.hpp
+++ b/proton-c/bindings/cpp/src/container_impl.hpp
@@ -28,6 +28,8 @@
 #include "proton/duration.hpp"
 #include "proton/reactor.hpp"
 
+#include "proton_handler.hpp"
+
 #include "proton/reactor.h"
 
 #include <string>
@@ -45,7 +47,7 @@ class task;
 class container_impl
 {
   public:
-    PN_CPP_EXTERN container_impl(container&, handler *, const std::string& id);
+    PN_CPP_EXTERN container_impl(container&, messaging_adapter*, const std::string& id);
     PN_CPP_EXTERN ~container_impl();
     PN_CPP_EXTERN connection connect(const url&, const connection_options&);
     PN_CPP_EXTERN sender open_sender(const url&, const proton::link_options &, const connection_options &);
@@ -61,8 +63,8 @@ class container_impl
     const proton::link_options& link_options() { return link_options_; }
 
     void configure_server_connection(connection &c);
-    task schedule(int delay, handler *h);
-    pn_ptr<pn_handler_t> cpp_handler(handler *h);
+    task schedule(int delay, proton_handler *h);
+    pn_ptr<pn_handler_t> cpp_handler(proton_handler *h);
 
     std::string next_link_name();
 
@@ -70,10 +72,9 @@ class container_impl
 
     container& container_;
     reactor reactor_;
-    handler *handler_;
-    pn_unique_ptr<messaging_adapter> messaging_adapter_;
-    pn_unique_ptr<handler> override_handler_;
-    pn_unique_ptr<handler> flow_controller_;
+    proton_handler *handler_;
+    pn_unique_ptr<proton_handler> override_handler_;
+    pn_unique_ptr<proton_handler> flow_controller_;
     std::string id_;
     uint64_t link_id_;
     connection_options client_connection_options_;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/contexts.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/contexts.cpp b/proton-c/bindings/cpp/src/contexts.cpp
index 9b77d89..fba68c6 100644
--- a/proton-c/bindings/cpp/src/contexts.cpp
+++ b/proton-c/bindings/cpp/src/contexts.cpp
@@ -23,12 +23,12 @@
 #include "msg.hpp"
 
 #include "proton/error.hpp"
-#include "proton/handler.hpp"
 
 #include "proton/object.h"
+#include "proton/link.h"
 #include "proton/message.h"
+#include "proton/reactor.h"
 #include "proton/session.h"
-#include "proton/link.h"
 
 #include <typeinfo>
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/contexts.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/contexts.hpp b/proton-c/bindings/cpp/src/contexts.hpp
index bb35bdf..98dd328 100644
--- a/proton-c/bindings/cpp/src/contexts.hpp
+++ b/proton-c/bindings/cpp/src/contexts.hpp
@@ -26,15 +26,17 @@
 #include "proton/message.hpp"
 #include "proton/connection.hpp"
 #include "proton/container.hpp"
-#include "proton/handler.hpp"
+
+#include "proton_handler.hpp"
 
 struct pn_session_t;
 struct pn_event_t;
 struct pn_record_t;
+struct pn_acceptor_t;
 
 namespace proton {
 
-class handler;
+class proton_handler;
 class container_impl;
 
 // Base class for C++ classes that are used as proton contexts.
@@ -62,7 +64,7 @@ class connection_context : public context {
 
     connection_context() : default_session(0), container_impl(0) {}
 
-    pn_unique_ptr<class handler> handler;
+    pn_unique_ptr<proton_handler> handler;
     pn_session_t *default_session;   // Owned by connection
     class container_impl* container_impl;
     message event_message;  // re-used by messaging_adapter for performance

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/event.cpp b/proton-c/bindings/cpp/src/event.cpp
index fd0e995..6490584 100644
--- a/proton-c/bindings/cpp/src/event.cpp
+++ b/proton-c/bindings/cpp/src/event.cpp
@@ -25,7 +25,6 @@
 #include "proton/delivery.hpp"
 #include "proton/error.hpp"
 #include "proton/event.hpp"
-#include "proton/handler.hpp"
 #include "proton/receiver.hpp"
 #include "proton/sender.hpp"
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/handler.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/handler.cpp b/proton-c/bindings/cpp/src/handler.cpp
deleted file mode 100644
index f40ee1f..0000000
--- a/proton-c/bindings/cpp/src/handler.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-#include "proton/handler.hpp"
-#include "proton/event.hpp"
-
-namespace proton {
-
-// container_impl.cpp sets pn_handler_ as needed.
-
-handler::handler() {}
-handler::~handler() {}
-
-void handler::on_unhandled(event &) {}
-
-void handler::add_child_handler(handler &e) {
-    children_.push_back(&e);
-}
-
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/link.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/link.cpp b/proton-c/bindings/cpp/src/link.cpp
index 37337c0..075bc9f 100644
--- a/proton-c/bindings/cpp/src/link.cpp
+++ b/proton-c/bindings/cpp/src/link.cpp
@@ -79,7 +79,7 @@ class session link::session() const {
     return pn_link_session(pn_object());
 }
 
-void link::handler(class handler &h) {
+void link::handler(proton_handler &h) {
     pn_record_t *record = pn_link_attachments(pn_object());
     connection_context& cc(connection_context::get(connection()));
     pn_ptr<pn_handler_t> chandler = cc.container_impl->cpp_handler(&h);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/link_options.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/link_options.cpp b/proton-c/bindings/cpp/src/link_options.cpp
index d5f8fb4..03c30ea 100644
--- a/proton-c/bindings/cpp/src/link_options.cpp
+++ b/proton-c/bindings/cpp/src/link_options.cpp
@@ -18,9 +18,12 @@
  * under the License.
  *
  */
-#include "proton/link_options.hpp"
 #include "proton/link.hpp"
+#include "proton/link_options.hpp"
+#include "proton/messaging_handler.hpp"
+
 #include "msg.hpp"
+#include "messaging_adapter.hpp"
 
 
 namespace proton {
@@ -58,7 +61,7 @@ template <class T> struct option {
 
 class link_options::impl {
   public:
-    option<class handler*> handler;
+    option<proton_handler*> handler;
     option<terminus::distribution_mode_t> distribution_mode;
     option<bool> durable_subscription;
     option<link_delivery_mode_t> delivery_mode;
@@ -156,7 +159,7 @@ link_options& link_options::operator=(const link_options& x) {
 
 void link_options::override(const link_options& x) { impl_->override(*x.impl_); }
 
-link_options& link_options::handler(class handler *h) { impl_->handler = h; return *this; }
+link_options& link_options::handler(class messaging_handler *h) { impl_->handler = h->messaging_adapter_.get(); return *this; }
 link_options& link_options::browsing(bool b) { distribution_mode(b ? terminus::COPY : terminus::MOVE); return *this; }
 link_options& link_options::distribution_mode(terminus::distribution_mode_t m) { impl_->distribution_mode = m; return *this; }
 link_options& link_options::durable_subscription(bool b) {impl_->durable_subscription = b; return *this; }
@@ -167,6 +170,6 @@ link_options& link_options::lifetime_policy(lifetime_policy_t lp) {impl_->lifeti
 link_options& link_options::selector(const std::string &str) {impl_->selector = str; return *this; }
 
 void link_options::apply(link& l) const { impl_->apply(l); }
-handler* link_options::handler() const { return impl_->handler.value; }
+proton_handler* link_options::handler() const { return impl_->handler.value; }
 
 } // namespace proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/messaging_adapter.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_adapter.cpp b/proton-c/bindings/cpp/src/messaging_adapter.cpp
index ad8e850..e9ce0ea 100644
--- a/proton-c/bindings/cpp/src/messaging_adapter.cpp
+++ b/proton-c/bindings/cpp/src/messaging_adapter.cpp
@@ -18,12 +18,15 @@
  * under the License.
  *
  */
-#include "proton/messaging_adapter.hpp"
-#include "messaging_event.hpp"
+
+#include "messaging_adapter.hpp"
+
 #include "proton/sender.hpp"
 #include "proton/error.hpp"
-#include "msg.hpp"
+
 #include "contexts.hpp"
+#include "messaging_event.hpp"
+#include "msg.hpp"
 
 #include "proton/link.h"
 #include "proton/handlers.h"
@@ -33,92 +36,122 @@
 #include "proton/message.h"
 
 namespace proton {
-messaging_adapter::messaging_adapter(messaging_handler &delegate) :
-    messaging_handler(true, delegate.prefetch_, delegate.auto_settle_, delegate.auto_accept_, delegate.peer_close_iserror_),
-    delegate_(delegate)
-{}
+
+namespace {
+class c_flow_controller : public proton_handler
+{
+  public:
+    pn_handler_t *flowcontroller;
+
+    // TODO: pn_flowcontroller requires a window > 1.
+    c_flow_controller(int window) : flowcontroller(pn_flowcontroller(std::max(window, 2))) {}
+    ~c_flow_controller() {
+        pn_decref(flowcontroller);
+    }
+
+    void redirect(proton_event &pne) {
+        pn_handler_dispatch(flowcontroller, pne.pn_event(), pn_event_type_t(pne.type()));
+    }
+
+    virtual void on_link_local_open(proton_event &e) { redirect(e); }
+    virtual void on_link_remote_open(proton_event &e) { redirect(e); }
+    virtual void on_link_flow(proton_event &e) { redirect(e); }
+    virtual void on_delivery(proton_event &e) { redirect(e); }
+};
+
+} // namespace
+
+void messaging_adapter::create_helpers() {
+  if (prefetch_ > 0) {
+    flow_controller_.reset(new c_flow_controller(prefetch_));
+    add_child_handler(*flow_controller_);
+  }
+}
+
+messaging_adapter::messaging_adapter(messaging_handler &delegate,
+                                     int prefetch, bool auto_accept, bool auto_settle, bool peer_close_iserror) :
+    delegate_(delegate),
+    prefetch_(prefetch),
+    auto_accept_(auto_accept),
+    auto_settle_(auto_settle),
+    peer_close_iserror_(peer_close_iserror)
+{
+    create_helpers();
+    //add_child_handler(*this);
+}
 
 
 messaging_adapter::~messaging_adapter(){}
 
 
-void messaging_adapter::on_reactor_init(event &e) {
-    proton_event *pe = dynamic_cast<proton_event*>(&e);
-    if (pe) {
-        messaging_event mevent(messaging_event::START, *pe);
-        delegate_.on_start(mevent);
-    }
+void messaging_adapter::on_reactor_init(proton_event &pe) {
+    messaging_event mevent(messaging_event::START, pe);
+    delegate_.on_start(mevent);
 }
 
-void messaging_adapter::on_link_flow(event &e) {
-    proton_event *pe = dynamic_cast<proton_event*>(&e);
-    if (pe) {
-        pn_event_t *pne = pe->pn_event();
-        pn_link_t *lnk = pn_event_link(pne);
-        if (lnk && pn_link_is_sender(lnk) && pn_link_credit(lnk) > 0) {
-            // create on_message extended event
-            messaging_event mevent(messaging_event::SENDABLE, *pe);
-            delegate_.on_sendable(mevent);;
-        }
-   }
+void messaging_adapter::on_link_flow(proton_event &pe) {
+    pn_event_t *pne = pe.pn_event();
+    pn_link_t *lnk = pn_event_link(pne);
+    if (lnk && pn_link_is_sender(lnk) && pn_link_credit(lnk) > 0) {
+        // create on_message extended event
+        messaging_event mevent(messaging_event::SENDABLE, pe);
+        delegate_.on_sendable(mevent);;
+    }
 }
 
-void messaging_adapter::on_delivery(event &e) {
-    proton_event *pe = dynamic_cast<proton_event*>(&e);
-    if (pe) {
-        pn_event_t *cevent = pe->pn_event();
-        pn_link_t *lnk = pn_event_link(cevent);
-        delivery dlv = pe->delivery();
-
-        if (pn_link_is_receiver(lnk)) {
-            if (!dlv.partial() && dlv.readable()) {
-                // generate on_message
-                messaging_event mevent(messaging_event::MESSAGE, *pe);
-                pn_connection_t *pnc = pn_session_connection(pn_link_session(lnk));
-                connection_context& ctx = connection_context::get(pnc);
-                // Reusable per-connection message.
-                // Avoid expensive heap malloc/free overhead.
-                // See PROTON-998
-                class message &msg(ctx.event_message);
-                mevent.message_ = &msg;
-                mevent.message_->decode(lnk, dlv);
-                if (pn_link_state(lnk) & PN_LOCAL_CLOSED) {
-                    if (auto_accept_)
-                        dlv.release();
-                } else {
-                    delegate_.on_message(mevent);
-                    if (auto_accept_ && !dlv.settled())
-                        dlv.accept();
-                }
+void messaging_adapter::on_delivery(proton_event &pe) {
+    pn_event_t *cevent = pe.pn_event();
+    pn_link_t *lnk = pn_event_link(cevent);
+    delivery dlv = pe.delivery();
+
+    if (pn_link_is_receiver(lnk)) {
+        if (!dlv.partial() && dlv.readable()) {
+            // generate on_message
+            messaging_event mevent(messaging_event::MESSAGE, pe);
+            pn_connection_t *pnc = pn_session_connection(pn_link_session(lnk));
+            connection_context& ctx = connection_context::get(pnc);
+            // Reusable per-connection message.
+            // Avoid expensive heap malloc/free overhead.
+            // See PROTON-998
+            class message &msg(ctx.event_message);
+            mevent.message_ = &msg;
+            mevent.message_->decode(lnk, dlv);
+            if (pn_link_state(lnk) & PN_LOCAL_CLOSED) {
+                if (auto_accept_)
+                    dlv.release();
+            } else {
+                delegate_.on_message(mevent);
+                if (auto_accept_ && !dlv.settled())
+                    dlv.accept();
             }
-            else if (dlv.updated() && dlv.settled()) {
-                messaging_event mevent(messaging_event::DELIVERY_SETTLE, *pe);
-                delegate_.on_delivery_settle(mevent);
+        }
+        else if (dlv.updated() && dlv.settled()) {
+            messaging_event mevent(messaging_event::DELIVERY_SETTLE, pe);
+            delegate_.on_delivery_settle(mevent);
+        }
+    } else {
+        // sender
+        if (dlv.updated()) {
+            amqp_ulong rstate = dlv.remote_state();
+            if (rstate == PN_ACCEPTED) {
+                messaging_event mevent(messaging_event::DELIVERY_ACCEPT, pe);
+                delegate_.on_delivery_accept(mevent);
+            }
+            else if (rstate == PN_REJECTED) {
+                messaging_event mevent(messaging_event::DELIVERY_REJECT, pe);
+                delegate_.on_delivery_reject(mevent);
             }
-        } else {
-            // sender
-            if (dlv.updated()) {
-                amqp_ulong rstate = dlv.remote_state();
-                if (rstate == PN_ACCEPTED) {
-                    messaging_event mevent(messaging_event::DELIVERY_ACCEPT, *pe);
-                    delegate_.on_delivery_accept(mevent);
-                }
-                else if (rstate == PN_REJECTED) {
-                    messaging_event mevent(messaging_event::DELIVERY_REJECT, *pe);
-                    delegate_.on_delivery_reject(mevent);
-                }
-                else if (rstate == PN_RELEASED || rstate == PN_MODIFIED) {
-                    messaging_event mevent(messaging_event::DELIVERY_RELEASE, *pe);
-                    delegate_.on_delivery_release(mevent);
-                }
-
-                if (dlv.settled()) {
-                    messaging_event mevent(messaging_event::DELIVERY_SETTLE, *pe);
-                    delegate_.on_delivery_settle(mevent);
-                }
-                if (auto_settle_)
-                    dlv.settle();
+            else if (rstate == PN_RELEASED || rstate == PN_MODIFIED) {
+                messaging_event mevent(messaging_event::DELIVERY_RELEASE, pe);
+                delegate_.on_delivery_release(mevent);
             }
+
+            if (dlv.settled()) {
+                messaging_event mevent(messaging_event::DELIVERY_SETTLE, pe);
+                delegate_.on_delivery_settle(mevent);
+            }
+            if (auto_settle_)
+                dlv.settle();
         }
     }
 }
@@ -135,153 +168,93 @@ bool is_local_unititialised(pn_state_t state) {
 
 } // namespace
 
-void messaging_adapter::on_link_remote_close(event &e) {
-    proton_event *pe = dynamic_cast<proton_event*>(&e);
-    if (pe) {
-        pn_event_t *cevent = pe->pn_event();
-        pn_link_t *lnk = pn_event_link(cevent);
-        if (pn_condition_is_set(pn_link_remote_condition(lnk))) {
-            messaging_event mevent(messaging_event::LINK_ERROR, *pe);
-            on_link_error(mevent);
-        }
-        else {
-            messaging_event mevent(messaging_event::LINK_CLOSE, *pe);
-            on_link_close(mevent);
-        }
-        pn_link_close(lnk);
+void messaging_adapter::on_link_remote_close(proton_event &pe) {
+    pn_event_t *cevent = pe.pn_event();
+    pn_link_t *lnk = pn_event_link(cevent);
+    if (pn_condition_is_set(pn_link_remote_condition(lnk))) {
+        messaging_event mevent(messaging_event::LINK_ERROR, pe);
+        delegate_.on_link_error(mevent);
     }
-}
-
-void messaging_adapter::on_session_remote_close(event &e) {
-    proton_event *pe = dynamic_cast<proton_event*>(&e);
-    if (pe) {
-        pn_event_t *cevent = pe->pn_event();
-        pn_session_t *session = pn_event_session(cevent);
-        if (pn_condition_is_set(pn_session_remote_condition(session))) {
-            messaging_event mevent(messaging_event::SESSION_ERROR, *pe);
-            on_session_error(mevent);
-        }
-        else {
-            messaging_event mevent(messaging_event::SESSION_CLOSE, *pe);
-            on_session_close(mevent);
-        }
-        pn_session_close(session);
+    else {
+        messaging_event mevent(messaging_event::LINK_CLOSE, pe);
+        delegate_.on_link_close(mevent);
+        if (peer_close_iserror_)
+          delegate_.on_link_error(mevent);
     }
+    pn_link_close(lnk);
 }
 
-void messaging_adapter::on_connection_remote_close(event &e) {
-    proton_event *pe = dynamic_cast<proton_event*>(&e);
-    if (pe) {
-        pn_event_t *cevent = pe->pn_event();
-        pn_connection_t *connection = pn_event_connection(cevent);
-        if (pn_condition_is_set(pn_connection_remote_condition(connection))) {
-            messaging_event mevent(messaging_event::CONNECTION_ERROR, *pe);
-            on_connection_error(mevent);
-        }
-        else {
-            messaging_event mevent(messaging_event::CONNECTION_CLOSE, *pe);
-            on_connection_close(mevent);
-        }
-        pn_connection_close(connection);
+void messaging_adapter::on_session_remote_close(proton_event &pe) {
+    pn_event_t *cevent = pe.pn_event();
+    pn_session_t *session = pn_event_session(cevent);
+    if (pn_condition_is_set(pn_session_remote_condition(session))) {
+        messaging_event mevent(messaging_event::SESSION_ERROR, pe);
+        delegate_.on_session_error(mevent);
     }
-}
-
-void messaging_adapter::on_connection_remote_open(event &e) {
-    proton_event *pe = dynamic_cast<proton_event*>(&e);
-    if (pe) {
-        messaging_event mevent(messaging_event::CONNECTION_OPEN, *pe);
-        on_connection_open(mevent);
-        pn_connection_t *connection = pn_event_connection(pe->pn_event());
-        if (!is_local_open(pn_connection_state(connection)) && is_local_unititialised(pn_connection_state(connection))) {
-            pn_connection_open(connection);
-        }
+    else {
+        messaging_event mevent(messaging_event::SESSION_CLOSE, pe);
+        delegate_.on_session_close(mevent);
+        if (peer_close_iserror_)
+          delegate_.on_session_error(mevent);
     }
+    pn_session_close(session);
 }
 
-void messaging_adapter::on_session_remote_open(event &e) {
-    proton_event *pe = dynamic_cast<proton_event*>(&e);
-    if (pe) {
-        messaging_event mevent(messaging_event::SESSION_OPEN, *pe);
-        on_session_open(mevent);
-        pn_session_t *session = pn_event_session(pe->pn_event());
-        if (!is_local_open(pn_session_state(session)) && is_local_unititialised(pn_session_state(session))) {
-            pn_session_open(session);
-        }
+void messaging_adapter::on_connection_remote_close(proton_event &pe) {
+    pn_event_t *cevent = pe.pn_event();
+    pn_connection_t *connection = pn_event_connection(cevent);
+    if (pn_condition_is_set(pn_connection_remote_condition(connection))) {
+        messaging_event mevent(messaging_event::CONNECTION_ERROR, pe);
+        delegate_.on_connection_error(mevent);
     }
-}
-
-void messaging_adapter::on_link_remote_open(event &e) {
-    proton_event *pe = dynamic_cast<proton_event*>(&e);
-    if (pe) {
-        messaging_event mevent(messaging_event::LINK_OPEN, *pe);
-        on_link_open(mevent);
-        pn_link_t *link = pn_event_link(pe->pn_event());
-        if (!is_local_open(pn_link_state(link)) && is_local_unititialised(pn_link_state(link))) {
-            pn_link_open(link);
-        }
+    else {
+        messaging_event mevent(messaging_event::CONNECTION_CLOSE, pe);
+        delegate_.on_connection_close(mevent);
+        if (peer_close_iserror_)
+          delegate_.on_connection_error(mevent);
     }
+    pn_connection_close(connection);
 }
 
-void messaging_adapter::on_transport_tail_closed(event &e) {
-    proton_event *pe = dynamic_cast<proton_event*>(&e);
-    if (pe) {
-        pn_connection_t *conn = pn_event_connection(pe->pn_event());
-        if (conn && is_local_open(pn_connection_state(conn))) {
-            messaging_event mevent(messaging_event::DISCONNECT, *pe);
-            delegate_.on_disconnect(mevent);
-        }
+void messaging_adapter::on_connection_remote_open(proton_event &pe) {
+    messaging_event mevent(messaging_event::CONNECTION_OPEN, pe);
+    delegate_.on_connection_open(mevent);
+    pn_connection_t *connection = pn_event_connection(pe.pn_event());
+    if (!is_local_open(pn_connection_state(connection)) && is_local_unititialised(pn_connection_state(connection))) {
+        pn_connection_open(connection);
     }
 }
 
-
-void messaging_adapter::on_connection_open(event &e) {
-    delegate_.on_connection_open(e);
-}
-
-void messaging_adapter::on_session_open(event &e) {
-    delegate_.on_session_open(e);
-}
-
-void messaging_adapter::on_link_open(event &e) {
-    delegate_.on_link_open(e);
-}
-
-void messaging_adapter::on_connection_error(event &e) {
-    delegate_.on_connection_error(e);
-}
-
-void messaging_adapter::on_session_error(event &e) {
-    delegate_.on_session_error(e);
-}
-
-void messaging_adapter::on_link_error(event &e) {
-    delegate_.on_link_error(e);
-}
-
-void messaging_adapter::on_connection_close(event &e) {
-    delegate_.on_connection_close(e);
-    if (peer_close_iserror_)
-        on_connection_error(e);
+void messaging_adapter::on_session_remote_open(proton_event &pe) {
+    messaging_event mevent(messaging_event::SESSION_OPEN, pe);
+    delegate_.on_session_open(mevent);
+    pn_session_t *session = pn_event_session(pe.pn_event());
+    if (!is_local_open(pn_session_state(session)) && is_local_unititialised(pn_session_state(session))) {
+        pn_session_open(session);
+    }
 }
 
-void messaging_adapter::on_session_close(event &e) {
-    delegate_.on_session_close(e);
-    if (peer_close_iserror_)
-        on_session_error(e);
+void messaging_adapter::on_link_remote_open(proton_event &pe) {
+    messaging_event mevent(messaging_event::LINK_OPEN, pe);
+    delegate_.on_link_open(mevent);
+    pn_link_t *link = pn_event_link(pe.pn_event());
+    if (!is_local_open(pn_link_state(link)) && is_local_unititialised(pn_link_state(link))) {
+        pn_link_open(link);
+    }
 }
 
-void messaging_adapter::on_link_close(event &e) {
-    delegate_.on_link_close(e);
-    if (peer_close_iserror_)
-        on_link_error(e);
+void messaging_adapter::on_transport_tail_closed(proton_event &pe) {
+    pn_connection_t *conn = pn_event_connection(pe.pn_event());
+    if (conn && is_local_open(pn_connection_state(conn))) {
+        messaging_event mevent(messaging_event::DISCONNECT, pe);
+        delegate_.on_disconnect(mevent);
+    }
 }
 
-void messaging_adapter::on_timer_task(event& e)
+void messaging_adapter::on_timer_task(proton_event& pe)
 {
-    delegate_.on_timer(e);
-}
-
-void messaging_adapter::on_unhandled(event &) {
+    messaging_event mevent(messaging_event::TIMER, pe);
+    delegate_.on_timer(mevent);
 }
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/messaging_adapter.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_adapter.hpp b/proton-c/bindings/cpp/src/messaging_adapter.hpp
new file mode 100644
index 0000000..866644d
--- /dev/null
+++ b/proton-c/bindings/cpp/src/messaging_adapter.hpp
@@ -0,0 +1,70 @@
+#ifndef PROTON_CPP_MESSAGING_ADAPTER_H
+#define PROTON_CPP_MESSAGING_ADAPTER_H
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "proton/messaging_handler.hpp"
+
+#include "proton_handler.hpp"
+
+#include "proton/event.h"
+#include "proton/reactor.h"
+
+///@cond INTERNAL
+
+namespace proton {
+
+// Combine's Python's: endpoint_state_handler, incoming_message_handler, outgoing_message_handler
+
+class messaging_adapter : public proton_handler
+{
+  public:
+    PN_CPP_EXTERN messaging_adapter(messaging_handler &delegate,
+                                    int prefetch, bool auto_accept, bool auto_settle,
+                                    bool peer_close_is_error);
+    PN_CPP_EXTERN virtual ~messaging_adapter();
+
+    PN_CPP_EXTERN void on_reactor_init(proton_event &e);
+    PN_CPP_EXTERN void on_link_flow(proton_event &e);
+    PN_CPP_EXTERN void on_delivery(proton_event &e);
+    PN_CPP_EXTERN void on_connection_remote_open(proton_event &e);
+    PN_CPP_EXTERN void on_connection_remote_close(proton_event &e);
+    PN_CPP_EXTERN void on_session_remote_open(proton_event &e);
+    PN_CPP_EXTERN void on_session_remote_close(proton_event &e);
+    PN_CPP_EXTERN void on_link_remote_open(proton_event &e);
+    PN_CPP_EXTERN void on_link_remote_close(proton_event &e);
+    PN_CPP_EXTERN void on_transport_tail_closed(proton_event &e);
+    PN_CPP_EXTERN void on_timer_task(proton_event &e);
+
+  private:
+    messaging_handler &delegate_;  // The handler for generated messaging_event's
+    int prefetch_;
+    bool auto_accept_;
+    bool auto_settle_;
+    bool peer_close_iserror_;
+    pn_unique_ptr<proton_handler> flow_controller_;
+    void create_helpers();
+};
+
+}
+///@endcond INTERNAL
+#endif  /*!PROTON_CPP_MESSAGING_ADAPTER_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/messaging_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_event.cpp b/proton-c/bindings/cpp/src/messaging_event.cpp
index b31e6f9..0c6c51d 100644
--- a/proton-c/bindings/cpp/src/messaging_event.cpp
+++ b/proton-c/bindings/cpp/src/messaging_event.cpp
@@ -19,19 +19,20 @@
  *
  */
 
-#include "proton/reactor.h"
-#include "proton/event.h"
-#include "proton/link.h"
-
 #include "messaging_event.hpp"
 #include "proton/message.hpp"
-#include "proton/proton_handler.hpp"
 #include "proton/messaging_handler.hpp"
 #include "proton/sender.hpp"
 #include "proton/receiver.hpp"
 #include "proton/error.hpp"
-#include "msg.hpp"
+
 #include "contexts.hpp"
+#include "msg.hpp"
+#include "proton_handler.hpp"
+
+#include "proton/reactor.h"
+#include "proton/event.h"
+#include "proton/link.h"
 
 /*
  * Performance note:
@@ -40,56 +41,45 @@
 
 namespace proton {
 
-messaging_event::messaging_event(pn_event_t *ce, proton_event::event_type t, class container *c) :
-    proton_event(ce, t, c), type_(messaging_event::PROTON), parent_event_(0), message_(0)
-{}
-
 messaging_event::messaging_event(event_type t, proton_event &p) :
-    proton_event(NULL, PN_EVENT_NONE, p.container_), type_(t), parent_event_(&p), message_(0)
-{
-    if (type_ == messaging_event::PROTON)
-        throw error(MSG("invalid messaging event type"));
-}
+    type_(t), parent_event_(&p), message_(0)
+{}
 
 messaging_event::~messaging_event() {}
 
 messaging_event::event_type messaging_event::type() const { return type_; }
 
+container& messaging_event::container() const {
+    if (parent_event_)
+        return parent_event_->container();
+    throw error(MSG("No container context for event"));
+}
+
 connection messaging_event::connection() const {
-    if (type_ == messaging_event::PROTON)
-        return proton_event::connection();
     if (parent_event_)
         return parent_event_->connection();
     throw error(MSG("No connection context for event"));
 }
 
 sender messaging_event::sender() const {
-    if (type_ == messaging_event::PROTON)
-        return proton_event::sender();
     if (parent_event_)
         return parent_event_->sender();
     throw error(MSG("No sender context for event"));
 }
 
 receiver messaging_event::receiver() const {
-    if (type_ == messaging_event::PROTON)
-        return proton_event::receiver();
     if (parent_event_)
         return parent_event_->receiver();
     throw error(MSG("No receiver context for event"));
 }
 
 link messaging_event::link() const {
-    if (type_ == messaging_event::PROTON)
-        return proton_event::link();
     if (parent_event_)
         return parent_event_->link();
     throw error(MSG("No link context for event"));
 }
 
 delivery messaging_event::delivery() const {
-    if (type_ == messaging_event::PROTON)
-        return proton_event::delivery();
     if (parent_event_)
         return parent_event_->delivery();
     throw error(MSG("No delivery context for event"));
@@ -101,60 +91,8 @@ message &messaging_event::message() const {
     return *message_;
 }
 
-void messaging_event::dispatch(handler &h) {
-    if (type_ == messaging_event::PROTON) {
-        proton_event::dispatch(h);
-        return;
-    }
-
-    messaging_handler *handler = dynamic_cast<messaging_handler*>(&h);
-    if (handler) {
-        switch(type_) {
-
-        case messaging_event::START:            handler->on_start(*this); break;
-        case messaging_event::SENDABLE:         handler->on_sendable(*this); break;
-        case messaging_event::MESSAGE:          handler->on_message(*this); break;
-        case messaging_event::DISCONNECT:       handler->on_disconnect(*this); break;
-
-        case messaging_event::CONNECTION_CLOSE: handler->on_connection_close(*this); break;
-        case messaging_event::CONNECTION_ERROR: handler->on_connection_error(*this); break;
-        case messaging_event::CONNECTION_OPEN:  handler->on_connection_open(*this); break;
-
-        case messaging_event::SESSION_CLOSE:    handler->on_session_close(*this); break;
-        case messaging_event::SESSION_ERROR:    handler->on_session_error(*this); break;
-        case messaging_event::SESSION_OPEN:     handler->on_session_open(*this); break;
-
-        case messaging_event::LINK_CLOSE:       handler->on_link_close(*this); break;
-        case messaging_event::LINK_ERROR:       handler->on_link_error(*this); break;
-        case messaging_event::LINK_OPEN:        handler->on_link_open(*this); break;
-
-        case messaging_event::DELIVERY_ACCEPT:  handler->on_delivery_accept(*this); break;
-        case messaging_event::DELIVERY_REJECT:  handler->on_delivery_reject(*this); break;
-        case messaging_event::DELIVERY_RELEASE: handler->on_delivery_release(*this); break;
-        case messaging_event::DELIVERY_SETTLE:  handler->on_delivery_settle(*this); break;
-
-        case messaging_event::TRANSACTION_DECLARE: handler->on_transaction_declare(*this); break;
-        case messaging_event::TRANSACTION_COMMIT:  handler->on_transaction_commit(*this); break;
-        case messaging_event::TRANSACTION_ABORT:   handler->on_transaction_abort(*this); break;
-
-        case messaging_event::TIMER:            handler->on_timer(*this); break;
-
-        default:
-            throw error(MSG("Unknown messaging event type " << type_));
-        }
-    } else {
-        h.on_unhandled(*this);
-    }
-
-    // recurse through children
-    for (handler::iterator child = h.children_.begin(); child != h.children_.end(); ++child) {
-        dispatch(**child);
-    }
-}
-
 std::string messaging_event::name() const {
     switch (type()) {
-      case PROTON: return pn_event_type_name(pn_event_type_t(proton_event::type()));
       case START:            return "START";
       case MESSAGE:          return "MESSAGE";
       case SENDABLE:         return "SENDABLE";

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d5c68c48/proton-c/bindings/cpp/src/messaging_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_event.hpp b/proton-c/bindings/cpp/src/messaging_event.hpp
index 31ba7d2..64e8975 100644
--- a/proton-c/bindings/cpp/src/messaging_event.hpp
+++ b/proton-c/bindings/cpp/src/messaging_event.hpp
@@ -33,7 +33,7 @@ class connection;
 class message;
 
 /** An event for the proton::messaging_handler */
-class messaging_event : public proton_event
+class messaging_event : public event
 {
   public:
 
@@ -43,7 +43,6 @@ class messaging_event : public proton_event
 
     /** Event types for a messaging_handler */
     enum event_type {
-        PROTON = 0,  // Wrapped pn_event_t
         START,
         MESSAGE,
         SENDABLE,
@@ -67,17 +66,16 @@ class messaging_event : public proton_event
         TIMER
     };
 
-    messaging_event(pn_event_t *, proton_event::event_type, class container *);
     messaging_event(event_type t, proton_event &parent);
     ~messaging_event();
 
-    virtual PN_CPP_EXTERN void dispatch(handler &h);
-    virtual PN_CPP_EXTERN class connection connection() const;
-    virtual PN_CPP_EXTERN class sender sender() const;
-    virtual PN_CPP_EXTERN class receiver receiver() const;
-    virtual PN_CPP_EXTERN class link link() const;
-    virtual PN_CPP_EXTERN class delivery delivery() const;
-    virtual PN_CPP_EXTERN class message& message() const;
+    PN_CPP_EXTERN class container& container() const;
+    PN_CPP_EXTERN class connection connection() const;
+    PN_CPP_EXTERN class sender sender() const;
+    PN_CPP_EXTERN class receiver receiver() const;
+    PN_CPP_EXTERN class link link() const;
+    PN_CPP_EXTERN class delivery delivery() const;
+    PN_CPP_EXTERN class message& message() const;
 
     PN_CPP_EXTERN event_type type() const;
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org