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 2015/11/20 16:35:44 UTC

[3/3] qpid-proton git commit: NO-JIRA: C++: Changed the API to no longer require use of external reference counting pointers. Squashed commit of: commit e488552ac50c2c1cb569c94450e10dbde6d5a5eb commit c7a86c91b7b41f3659d28d1229cd7073eb1f2e2a commit 2034e

NO-JIRA: C++: Changed the API to no longer require use of external reference counting
pointers.
Squashed commit of:
commit e488552ac50c2c1cb569c94450e10dbde6d5a5eb
commit c7a86c91b7b41f3659d28d1229cd7073eb1f2e2a
commit 2034e83fca2f24c118e83f01ce0cd468c7796c4d
commit 72f0b533fc4e9f7a761d1141d62fadf15a0ce84c
commit 5f4991f7f73e795d4624582f0cc2b4e9381c9d5a
commit 756bcfdcdcda36cddfaead71f4cddb3f1b4dee16
commit 0bc309e5989f07320317a9f1198d5c27d1285119
commit c0bb30077a1fa522535cc92c46d3582c26aa4005
commit 29c9ec4aa3642135140606fcbea72608e9ade611


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

Branch: refs/heads/master
Commit: 645fe09e47477372f84ae176518148c2bd3de396
Parents: aa226be
Author: Andrew Stitcher <as...@apache.org>
Authored: Fri Nov 20 10:17:20 2015 -0500
Committer: Andrew Stitcher <as...@apache.org>
Committed: Fri Nov 20 10:17:20 2015 -0500

----------------------------------------------------------------------
 examples/cpp/broker.hpp                         |  43 +--
 examples/cpp/client.cpp                         |  14 +-
 examples/cpp/direct_recv.cpp                    |   6 +-
 examples/cpp/direct_send.cpp                    |   8 +-
 examples/cpp/encode_decode.cpp                  |   2 +-
 examples/cpp/example_test.py                    |   4 +-
 examples/cpp/helloworld.cpp                     |   2 +-
 examples/cpp/helloworld_blocking.cpp            |   1 +
 examples/cpp/helloworld_direct.cpp              |   7 +-
 examples/cpp/recurring_timer.cpp                |  10 +-
 examples/cpp/server.cpp                         |  12 +-
 examples/cpp/server_direct.cpp                  |  12 +-
 examples/cpp/simple_recv.cpp                    |   4 +-
 examples/cpp/simple_send.cpp                    |   6 +-
 proton-c/bindings/cpp/CMakeLists.txt            |   4 +-
 .../bindings/cpp/include/proton/acceptor.hpp    |   6 +-
 .../cpp/include/proton/blocking_connection.hpp  |   3 +-
 .../cpp/include/proton/blocking_link.hpp        |   5 +-
 .../cpp/include/proton/blocking_receiver.hpp    |   2 +-
 .../cpp/include/proton/blocking_sender.hpp      |   6 +-
 .../bindings/cpp/include/proton/connection.hpp  |  29 +-
 .../bindings/cpp/include/proton/container.hpp   |  12 +-
 .../bindings/cpp/include/proton/counted_ptr.hpp |   2 +-
 proton-c/bindings/cpp/include/proton/data.hpp   |  37 ++-
 .../bindings/cpp/include/proton/decoder.hpp     | 112 ++++----
 .../bindings/cpp/include/proton/delivery.hpp    |  12 +-
 .../bindings/cpp/include/proton/encoder.hpp     | 105 +++----
 .../bindings/cpp/include/proton/endpoint.hpp    |  37 +--
 proton-c/bindings/cpp/include/proton/engine.hpp |   2 +-
 proton-c/bindings/cpp/include/proton/event.hpp  |  16 +-
 .../bindings/cpp/include/proton/event_loop.hpp  |   5 +-
 proton-c/bindings/cpp/include/proton/facade.hpp | 145 ----------
 .../bindings/cpp/include/proton/handler.hpp     |   1 +
 proton-c/bindings/cpp/include/proton/link.hpp   |  54 +++-
 .../bindings/cpp/include/proton/message.hpp     |  11 +-
 .../bindings/cpp/include/proton/message_id.hpp  |   7 +-
 .../cpp/include/proton/messaging_adapter.hpp    |   1 -
 proton-c/bindings/cpp/include/proton/object.hpp | 113 ++++++++
 .../bindings/cpp/include/proton/reactor.hpp     |  38 ++-
 .../bindings/cpp/include/proton/receiver.hpp    |   6 +-
 proton-c/bindings/cpp/include/proton/sender.hpp |   8 +-
 .../bindings/cpp/include/proton/session.hpp     |  30 +-
 proton-c/bindings/cpp/include/proton/task.hpp   |   6 +-
 .../bindings/cpp/include/proton/terminus.hpp    |   8 +-
 .../bindings/cpp/include/proton/transport.hpp   |   8 +-
 proton-c/bindings/cpp/include/proton/url.hpp    |   1 -
 proton-c/bindings/cpp/include/proton/value.hpp  |  21 +-
 proton-c/bindings/cpp/src/acceptor.cpp          |   2 +-
 .../bindings/cpp/src/blocking_connection.cpp    |   2 +-
 .../cpp/src/blocking_connection_impl.cpp        |  28 +-
 .../cpp/src/blocking_connection_impl.hpp        |   2 +-
 proton-c/bindings/cpp/src/blocking_fetcher.cpp  |  17 +-
 proton-c/bindings/cpp/src/blocking_fetcher.hpp  |   4 +-
 proton-c/bindings/cpp/src/blocking_link.cpp     |  41 ++-
 proton-c/bindings/cpp/src/blocking_receiver.cpp |  18 +-
 proton-c/bindings/cpp/src/blocking_sender.cpp   |  26 +-
 proton-c/bindings/cpp/src/connection.cpp        |  45 +--
 proton-c/bindings/cpp/src/connector.cpp         |   9 +-
 proton-c/bindings/cpp/src/connector.hpp         |   2 +-
 proton-c/bindings/cpp/src/container.cpp         |  15 +-
 proton-c/bindings/cpp/src/container_impl.cpp    |  47 ++-
 proton-c/bindings/cpp/src/container_impl.hpp    |  19 +-
 proton-c/bindings/cpp/src/contexts.hpp          |   2 +-
 proton-c/bindings/cpp/src/conversion_test.cpp   |  74 -----
 proton-c/bindings/cpp/src/counted_ptr.cpp       |  32 +++
 proton-c/bindings/cpp/src/data.cpp              |  47 +--
 proton-c/bindings/cpp/src/decoder.cpp           | 286 ++++++++++---------
 proton-c/bindings/cpp/src/delivery.cpp          |  19 +-
 proton-c/bindings/cpp/src/encoder.cpp           |  86 +++---
 proton-c/bindings/cpp/src/endpoint.cpp          |   7 +-
 proton-c/bindings/cpp/src/engine.cpp            |   4 +-
 proton-c/bindings/cpp/src/event.cpp             |  17 +-
 proton-c/bindings/cpp/src/facade.cpp            |  70 -----
 proton-c/bindings/cpp/src/interop_test.cpp      |   4 +-
 proton-c/bindings/cpp/src/link.cpp              |  69 +++--
 proton-c/bindings/cpp/src/message.cpp           |  51 ++--
 proton-c/bindings/cpp/src/messaging_adapter.cpp |   4 +-
 proton-c/bindings/cpp/src/messaging_event.cpp   |  10 +-
 proton-c/bindings/cpp/src/messaging_event.hpp   |  10 +-
 proton-c/bindings/cpp/src/object.cpp            |  33 +++
 proton-c/bindings/cpp/src/proton_event.cpp      |  30 +-
 proton-c/bindings/cpp/src/proton_event.hpp      |  16 +-
 proton-c/bindings/cpp/src/reactor.cpp           |  67 ++++-
 proton-c/bindings/cpp/src/receiver.cpp          |   4 +-
 proton-c/bindings/cpp/src/sender.cpp            |  14 +-
 proton-c/bindings/cpp/src/session.cpp           |  38 +--
 proton-c/bindings/cpp/src/task.cpp              |   2 +-
 proton-c/bindings/cpp/src/terminus.cpp          |  20 +-
 proton-c/bindings/cpp/src/transport.cpp         |   4 +-
 proton-c/bindings/cpp/src/value.cpp             |  22 +-
 tests/tools/apps/cpp/reactor_send.cpp           |   8 +-
 91 files changed, 1205 insertions(+), 1106 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/broker.hpp
----------------------------------------------------------------------
diff --git a/examples/cpp/broker.hpp b/examples/cpp/broker.hpp
index 51dcaa3..32fd5c7 100644
--- a/examples/cpp/broker.hpp
+++ b/examples/cpp/broker.hpp
@@ -43,17 +43,17 @@ class queue {
 
     std::string name() const { return name_; }
 
-    void subscribe(proton::sender &s) {
-        consumers_.push_back(s.ptr());
+    void subscribe(proton::sender s) {
+        consumers_.push_back(s);
     }
 
     // Return true if queue can be deleted.
-    bool unsubscribe(proton::sender &s) {
-        consumers_.remove(s.ptr());
+    bool unsubscribe(proton::sender s) {
+        consumers_.remove(s);
         return (consumers_.size() == 0 && (dynamic_ || messages_.size() == 0));
     }
 
-    void publish(const proton::message &m, proton::receiver *r) {
+    void publish(const proton::message &m, proton::receiver r) {
         messages_.push_back(m);
         dispatch(0);
     }
@@ -69,7 +69,7 @@ class queue {
         bool result = false;
         sender_list::iterator it = consumers_.begin();
         if (!s && count)
-            s = it->get();
+            s = &*it;
 
         while (messages_.size()) {
             if (s->credit()) {
@@ -88,7 +88,7 @@ class queue {
 
   private:
     typedef std::deque<proton::message> message_queue;
-    typedef std::list<proton::counted_ptr<proton::sender> > sender_list;
+    typedef std::list<proton::sender> sender_list;
 
     std::string name_;
     bool dynamic_;
@@ -136,13 +136,13 @@ class broker_handler : public proton::messaging_handler {
     broker_handler(queues& qs) : queues_(qs) {}
 
     void on_link_opening(proton::event &e) {
-        proton::link& lnk = e.link();
-        if (lnk.sender()) {
-            proton::terminus &remote_source(lnk.remote_source());
+        proton::link lnk = e.link();
+        if (!!lnk.sender()) {
+            proton::terminus remote_source(lnk.remote_source());
             queue &q = remote_source.dynamic() ?
                 queues_.dynamic() : queues_.get(remote_source.address());
             lnk.source().address(q.name());
-            q.subscribe(*lnk.sender());
+            q.subscribe(lnk.sender());
             std::cout << "broker outgoing link from " << q.name() << std::endl;
         }
         else {                  // Receiver
@@ -154,16 +154,16 @@ class broker_handler : public proton::messaging_handler {
         }
     }
 
-    void unsubscribe (proton::sender &lnk) {
+    void unsubscribe (proton::sender lnk) {
         std::string address = lnk.source().address();
         if (queues_.get(address).unsubscribe(lnk))
             queues_.erase(address);
     }
 
     void on_link_closing(proton::event &e) {
-        proton::link &lnk = e.link();
-        if (lnk.sender()) 
-            unsubscribe(*lnk.sender());
+        proton::link lnk = e.link();
+        if (!!lnk.sender()) 
+            unsubscribe(lnk.sender());
     }
 
     void on_connection_closing(proton::event &e) {
@@ -174,18 +174,19 @@ class broker_handler : public proton::messaging_handler {
         remove_stale_consumers(e.connection());
     }
 
-    void remove_stale_consumers(proton::connection &connection) {
-        proton::link_range r = connection.find_links(proton::endpoint::REMOTE_ACTIVE);
+    void remove_stale_consumers(proton::connection connection) {
+      proton::link_range r = connection.find_links(proton::endpoint::REMOTE_ACTIVE);
         for (proton::link_iterator l = r.begin(); l != r.end(); ++l) {
-            if (l->sender())
-                unsubscribe(*l->sender());
+            if (!!l->sender())
+                unsubscribe(l->sender());
         }
     }
 
     void on_sendable(proton::event &e) {
-        proton::link& lnk = e.link();
+        proton::link lnk = e.link();
         std::string address = lnk.source().address();
-        queues_.get(address).dispatch(lnk.sender());
+        proton::sender s = lnk.sender();
+        queues_.get(address).dispatch(&s);
     }
 
     void on_message(proton::event &e) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/client.cpp b/examples/cpp/client.cpp
index 05924f6..7e576b1 100644
--- a/examples/cpp/client.cpp
+++ b/examples/cpp/client.cpp
@@ -31,27 +31,27 @@ class client : public proton::messaging_handler {
   private:
     proton::url url;
     std::vector<std::string> requests;
-    proton::counted_ptr<proton::sender> sender;
-    proton::counted_ptr<proton::receiver> receiver;
+    proton::sender sender;
+    proton::receiver receiver;
 
   public:
     client(const proton::url &u, const std::vector<std::string>& r) : url(u), requests(r) {}
 
     void on_start(proton::event &e) {
-        sender = e.container().open_sender(url).ptr();
+        sender = e.container().open_sender(url);
         // Create a receiver with a dynamically chosen unique address.
-        receiver = sender->connection().open_receiver("", true/*dynamic*/).ptr();
+        receiver = sender.connection().open_receiver("", true/*dynamic*/);
     }
 
     void send_request() {
         proton::message req;
         req.body(requests.front());
-        req.reply_to(receiver->remote_source().address());
-        sender->send(req);
+        req.reply_to(receiver.remote_source().address());
+        sender.send(req);
     }
 
     void on_link_opened(proton::event &e) {
-        if (&e.link() == receiver.get())
+        if (e.link() == receiver)
             send_request();
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/direct_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/direct_recv.cpp b/examples/cpp/direct_recv.cpp
index 50ada7c..ad16d26 100644
--- a/examples/cpp/direct_recv.cpp
+++ b/examples/cpp/direct_recv.cpp
@@ -36,13 +36,13 @@ class direct_recv : public proton::messaging_handler {
     proton::url url;
     uint64_t expected;
     uint64_t received;
-    proton::counted_ptr<proton::acceptor> acceptor;
+    proton::acceptor acceptor;
 
   public:
     direct_recv(const std::string &s, int c) : url(s), expected(c), received(0) {}
 
     void on_start(proton::event &e) {
-        acceptor = e.container().listen(url).ptr();
+        acceptor = e.container().listen(url);
         std::cout << "direct_recv listening on " << url << std::endl;
     }
 
@@ -57,7 +57,7 @@ class direct_recv : public proton::messaging_handler {
         if (received == expected) {
             e.receiver().close();
             e.connection().close();
-            if (acceptor) acceptor->close();
+            if (!!acceptor) acceptor.close();
         }
     }
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/direct_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/direct_send.cpp b/examples/cpp/direct_send.cpp
index 13ca510..909ef3f 100644
--- a/examples/cpp/direct_send.cpp
+++ b/examples/cpp/direct_send.cpp
@@ -36,18 +36,18 @@ class simple_send : public proton::messaging_handler {
     int sent;
     int confirmed;
     int total;
-    proton::counted_ptr<proton::acceptor> acceptor;
+    proton::acceptor acceptor;
   public:
 
     simple_send(const std::string &s, int c) : url(s), sent(0), confirmed(0), total(c) {}
 
     void on_start(proton::event &e) {
-        acceptor = e.container().listen(url).ptr();
+        acceptor = e.container().listen(url);
         std::cout << "direct_send listening on " << url << std::endl;
     }
 
     void on_sendable(proton::event &e) {
-        proton::sender& sender = e.sender();
+        proton::sender sender = e.sender();
         while (sender.credit() && sent < total) {
             proton::message msg;
             msg.id(sent + 1);
@@ -64,7 +64,7 @@ class simple_send : public proton::messaging_handler {
         if (confirmed == total) {
             std::cout << "all messages confirmed" << std::endl;
             e.connection().close();
-            acceptor->close();
+            acceptor.close();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/encode_decode.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/encode_decode.cpp b/examples/cpp/encode_decode.cpp
index 1ed8b64..aced54b 100644
--- a/examples/cpp/encode_decode.cpp
+++ b/examples/cpp/encode_decode.cpp
@@ -231,7 +231,7 @@ void print_next(proton::decoder& d) {
 
 // Print a value, for example purposes. Normal code can use operator<<
 void print(proton::value& v) {
-    proton::decoder& d = v.decoder();
+    proton::decoder d = v.decoder();
     d.rewind();
     while (d.more()) {
         print_next(d);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/example_test.py
----------------------------------------------------------------------
diff --git a/examples/cpp/example_test.py b/examples/cpp/example_test.py
index 51b215e..2f8b08c 100644
--- a/examples/cpp/example_test.py
+++ b/examples/cpp/example_test.py
@@ -122,7 +122,7 @@ class ExampleTest(unittest.TestCase):
 
     def test_helloworld_blocking(self):
         b = Broker.get()
-        hw = execute("helloworld_blocking", b.addr, b.addr)
+        hw = execute("helloworld_blocking", b.addr)
         self.assertEqual('"Hello World!"\n', hw)
 
     def test_helloworld_direct(self):
@@ -180,7 +180,7 @@ class ExampleTest(unittest.TestCase):
         finally:
             server.kill()
 
-    def test_request_response(self):
+    def test_request_response_sync(self):
         b = Broker.get()
         server = background("server", "-a", b.addr)
         try:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/helloworld.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld.cpp b/examples/cpp/helloworld.cpp
index d6caa27..b18c151 100644
--- a/examples/cpp/helloworld.cpp
+++ b/examples/cpp/helloworld.cpp
@@ -34,7 +34,7 @@ class hello_world : public proton::messaging_handler {
     hello_world(const proton::url& u) : url(u) {}
 
     void on_start(proton::event &e) {
-        proton::connection& conn = e.container().connect(url);
+        proton::connection conn = e.container().connect(url);
         conn.open_receiver(url.path());
         conn.open_sender(url.path());
     }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/helloworld_blocking.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld_blocking.cpp b/examples/cpp/helloworld_blocking.cpp
index 81a56b9..a67276e 100644
--- a/examples/cpp/helloworld_blocking.cpp
+++ b/examples/cpp/helloworld_blocking.cpp
@@ -24,6 +24,7 @@
 #include "proton/blocking_sender.hpp"
 #include "proton/blocking_receiver.hpp"
 #include "proton/duration.hpp"
+#include "proton/url.hpp"
 
 #include <iostream>
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/helloworld_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld_direct.cpp b/examples/cpp/helloworld_direct.cpp
index d055fde..826b371 100644
--- a/examples/cpp/helloworld_direct.cpp
+++ b/examples/cpp/helloworld_direct.cpp
@@ -23,19 +23,18 @@
 #include "proton/container.hpp"
 #include "proton/messaging_handler.hpp"
 
-//#include "proton/acceptor.hpp"
 #include <iostream>
 
 class hello_world_direct : public proton::messaging_handler {
   private:
     proton::url url;
-    proton::counted_ptr<proton::acceptor> acceptor;
+    proton::acceptor acceptor;
   public:
 
     hello_world_direct(const proton::url& u) : url(u) {}
 
     void on_start(proton::event &e) {
-        acceptor = e.container().listen(url).ptr();
+        acceptor = e.container().listen(url);
         e.container().open_sender(url);
     }
 
@@ -54,7 +53,7 @@ class hello_world_direct : public proton::messaging_handler {
     }
 
     void on_connection_closed(proton::event &e) {
-        acceptor->close();
+        acceptor.close();
     }
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/recurring_timer.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/recurring_timer.cpp b/examples/cpp/recurring_timer.cpp
index 7d4b508..4beaaf6 100644
--- a/examples/cpp/recurring_timer.cpp
+++ b/examples/cpp/recurring_timer.cpp
@@ -46,12 +46,12 @@ class recurring : public proton::messaging_handler {
     int remaining_msecs, tick_ms;
     ticker tick_handler;
     tocker tock_handler;
-    proton::task *cancel_task;
+    proton::task cancel_task;
   public:
 
     recurring(int msecs, int tickms) : remaining_msecs(msecs), tick_ms(tickms), cancel_task(0) {}
 
-    proton::task& ticktock(proton::event &e) {
+    proton::task ticktock(proton::event &e) {
         // Show timer events in separate handlers.
         e.container().schedule(tick_ms, &tick_handler);
         return e.container().schedule(tick_ms * 3, &tock_handler);
@@ -59,13 +59,13 @@ class recurring : public proton::messaging_handler {
 
     void on_start(proton::event &e) {
         // Demonstrate cancel(), we will cancel the first tock on the first recurring::on_timer_task
-        cancel_task = &ticktock(e);
+        cancel_task = ticktock(e);
         e.container().schedule(0);
     }
 
     void on_timer_task(proton::event &e) {
-        if (cancel_task) {
-            cancel_task->cancel();
+        if (!!cancel_task) {
+            cancel_task.cancel();
             cancel_task = 0;
             e.container().schedule(tick_ms * 4);
         } else {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/server.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server.cpp b/examples/cpp/server.cpp
index fd00eb1..fc2b462 100644
--- a/examples/cpp/server.cpp
+++ b/examples/cpp/server.cpp
@@ -32,9 +32,9 @@
 
 class server : public proton::messaging_handler {
   private:
-    typedef std::map<std::string, proton::counted_ptr<proton::sender> > sender_map;
+    typedef std::map<std::string, proton::sender> sender_map;
     proton::url url;
-    proton::counted_ptr<proton::connection> connection;
+    proton::connection connection;
     sender_map senders;
 
   public:
@@ -42,8 +42,8 @@ class server : public proton::messaging_handler {
     server(const std::string &u) : url(u) {}
 
     void on_start(proton::event &e) {
-        connection = e.container().connect(url).ptr();
-        connection->open_receiver(url.path());
+        connection = e.container().connect(url);
+        connection.open_receiver(url.path());
         std::cout << "server connected to " << url << std::endl;
     }
 
@@ -62,8 +62,8 @@ class server : public proton::messaging_handler {
         reply.body(to_upper(e.message().body().get<std::string>()));
         reply.correlation_id(e.message().correlation_id());
         if (!senders[reply_to])
-            senders[reply_to] = connection->open_sender(reply_to).ptr();
-        senders[reply_to]->send(reply);
+            senders[reply_to] = connection.open_sender(reply_to);
+        senders[reply_to].send(reply);
     }
 };
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/server_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server_direct.cpp b/examples/cpp/server_direct.cpp
index 76bb5ad..8bbcefe 100644
--- a/examples/cpp/server_direct.cpp
+++ b/examples/cpp/server_direct.cpp
@@ -34,7 +34,7 @@
 
 class server : public proton::messaging_handler {
   private:
-    typedef std::map<std::string, proton::counted_ptr<proton::sender> > sender_map;
+    typedef std::map<std::string, proton::sender> sender_map;
     proton::url url;
     sender_map senders;
     int address_counter;
@@ -62,10 +62,10 @@ class server : public proton::messaging_handler {
     }
 
     void on_link_opening(proton::event& e) {
-        proton::link& link = e.link();
-        if (link.sender() && link.remote_source().dynamic()) {
+        proton::link link = e.link();
+        if (!!link.sender() && link.remote_source().dynamic()) {
             link.source().address(generate_address());
-            senders[link.source().address()] = link.sender()->ptr();
+            senders[link.source().address()] = link.sender();
         }
     }
 
@@ -76,12 +76,12 @@ class server : public proton::messaging_handler {
         if (it == senders.end()) {
             std::cout << "No link for reply_to: " << reply_to << std::endl;
         } else {
-            proton::counted_ptr<proton::sender> sender = it->second;
+            proton::sender sender = it->second;
             proton::message reply;
             reply.address(reply_to);
             reply.body(to_upper(e.message().body().get<std::string>()));
             reply.correlation_id(e.message().correlation_id());
-            sender->send(reply);
+            sender.send(reply);
         }
     }
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/simple_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_recv.cpp b/examples/cpp/simple_recv.cpp
index bcb28e3..1e0d071 100644
--- a/examples/cpp/simple_recv.cpp
+++ b/examples/cpp/simple_recv.cpp
@@ -35,7 +35,7 @@
 class simple_recv : public proton::messaging_handler {
   private:
     proton::url url;
-    proton::counted_ptr<proton::receiver> receiver;
+    proton::receiver receiver;
     uint64_t expected;
     uint64_t received;
   public:
@@ -43,7 +43,7 @@ class simple_recv : public proton::messaging_handler {
     simple_recv(const std::string &s, int c) : url(s), expected(c), received(0) {}
 
     void on_start(proton::event &e) {
-        receiver = e.container().open_receiver(url).ptr();
+        receiver = e.container().open_receiver(url);
         std::cout << "simple_recv listening on " << url << std::endl;
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/examples/cpp/simple_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_send.cpp b/examples/cpp/simple_send.cpp
index 31e2c73..4d056fc 100644
--- a/examples/cpp/simple_send.cpp
+++ b/examples/cpp/simple_send.cpp
@@ -32,7 +32,7 @@
 class simple_send : public proton::messaging_handler {
   private:
     proton::url url;
-    proton::counted_ptr<proton::sender> sender;
+    proton::sender sender;
     int sent;
     int confirmed;
     int total;
@@ -41,11 +41,11 @@ class simple_send : public proton::messaging_handler {
     simple_send(const std::string &s, int c) : url(s), sent(0), confirmed(0), total(c) {}
 
     void on_start(proton::event &e) {
-        sender = e.container().open_sender(url).ptr();
+        sender = e.container().open_sender(url);
     }
 
     void on_sendable(proton::event &e) {
-        proton::sender& sender = e.sender();
+        proton::sender sender = e.sender();
         while (sender.credit() && sent < total) {
             proton::message msg;
             msg.id(sent + 1);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index 7660961..bf9af46 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -36,6 +36,7 @@ set(qpid-proton-cpp-source
   src/connector.cpp
   src/container.cpp
   src/container_impl.cpp
+  src/counted_ptr.cpp
   src/contexts.cpp
   src/data.cpp
   src/decoder.cpp
@@ -46,13 +47,13 @@ set(qpid-proton-cpp-source
   src/engine.cpp
   src/error.cpp
   src/event.cpp
-  src/facade.cpp
   src/handler.cpp
   src/link.cpp
   src/message.cpp
   src/messaging_adapter.cpp
   src/messaging_event.cpp
   src/messaging_handler.cpp
+  src/object.cpp
   src/proton_bits.cpp
   src/proton_event.cpp
   src/proton_handler.cpp
@@ -163,5 +164,4 @@ endmacro(add_cpp_test)
 
 add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests)
 add_cpp_test(message_test)
-add_cpp_test(conversion_test)
 add_cpp_test(encode_decode_test)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/acceptor.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/acceptor.hpp b/proton-c/bindings/cpp/include/proton/acceptor.hpp
index ed7c852..c4fbdde 100644
--- a/proton-c/bindings/cpp/include/proton/acceptor.hpp
+++ b/proton-c/bindings/cpp/include/proton/acceptor.hpp
@@ -24,16 +24,18 @@
 
 #include "proton/reactor.h"
 #include "proton/export.hpp"
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 
 struct pn_connection_t;
 
 namespace proton {
 
 /** acceptor accepts connections. @see container::listen */
-class acceptor : public counted_facade<pn_acceptor_t, acceptor>
+class acceptor : public object<pn_acceptor_t>
 {
   public:
+    acceptor(pn_acceptor_t* a=0) : object(a) {}
+
     /** close the acceptor */
     PN_CPP_EXTERN void close();
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
index 87e9b2e..bcdf0e7 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
@@ -22,7 +22,6 @@
  *
  */
 
-#include "proton/pn_unique_ptr.hpp"
 #include "proton/export.hpp"
 #include "proton/duration.hpp"
 #include "proton/pn_unique_ptr.hpp"
@@ -43,7 +42,7 @@ class blocking_connection
     PN_CPP_EXTERN ~blocking_connection();
     PN_CPP_EXTERN void close();
     PN_CPP_EXTERN duration timeout() const;
-    PN_CPP_EXTERN class connection& connection() const;
+    PN_CPP_EXTERN class connection connection() const;
 
   private:
     blocking_connection(const blocking_connection&);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/blocking_link.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/blocking_link.hpp b/proton-c/bindings/cpp/include/proton/blocking_link.hpp
index 6913654..2b0a089 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_link.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_link.hpp
@@ -24,6 +24,7 @@
 #include "proton/export.hpp"
 #include "proton/counted_ptr.hpp"
 #include "proton/duration.hpp"
+#include "proton/link.hpp"
 
 #include <string>
 
@@ -40,12 +41,12 @@ class blocking_link
 
   protected:
     blocking_link(blocking_connection&);
-    void open(link&);
+    void open(link);
     void check_closed();
     void wait_for_closed();
 
     blocking_connection& connection_;
-    counted_ptr<link> link_;
+    link link_;
 
   private:
     blocking_link(const blocking_link&);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/blocking_receiver.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/blocking_receiver.hpp b/proton-c/bindings/cpp/include/proton/blocking_receiver.hpp
index 3bd657d..4d3b9fc 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_receiver.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_receiver.hpp
@@ -52,7 +52,7 @@ class blocking_receiver : public blocking_link
     PN_CPP_EXTERN void settle(delivery::state state);
     PN_CPP_EXTERN void flow(int count);
 
-    PN_CPP_EXTERN class receiver& receiver();
+    PN_CPP_EXTERN class receiver receiver();
   private:
     pn_unique_ptr<blocking_fetcher> fetcher_;
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/blocking_sender.hpp b/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
index b7c2697..a544e75 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_sender.hpp
@@ -39,10 +39,10 @@ class blocking_sender : public blocking_link
     PN_CPP_EXTERN blocking_sender(class blocking_connection &c, const std::string &address);
     PN_CPP_EXTERN ~blocking_sender();
 
-    PN_CPP_EXTERN delivery& send(const message &msg);
-    PN_CPP_EXTERN delivery& send(const message &msg, duration timeout);
+    PN_CPP_EXTERN delivery send(const message &msg);
+    PN_CPP_EXTERN delivery send(const message &msg, duration timeout);
 
-    PN_CPP_EXTERN class sender& sender() const;
+    PN_CPP_EXTERN class sender sender() const;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/connection.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection.hpp b/proton-c/bindings/cpp/include/proton/connection.hpp
index 68d46a3..e38148b 100644
--- a/proton-c/bindings/cpp/include/proton/connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection.hpp
@@ -23,7 +23,9 @@
  */
 #include "proton/export.hpp"
 #include "proton/endpoint.hpp"
-#include "proton/container.hpp"
+#include "proton/link.hpp"
+#include "proton/object.hpp"
+#include "proton/session.hpp"
 #include "proton/types.h"
 #include <string>
 
@@ -31,13 +33,18 @@ struct pn_connection_t;
 
 namespace proton {
 
+class connection_context;
 class handler;
 class engine;
 
 /** connection to a remote AMQP peer. */
-class connection : public counted_facade<pn_connection_t, connection, endpoint>
+class connection : public object<pn_connection_t>, endpoint
 {
   public:
+    connection(pn_connection_t* c=0) : object(c) {}
+
+    /// Get the connection context object from the connection
+    PN_CPP_EXTERN connection_context& context() const;
 
     /// Get the event_loop, can be a container or an engine.
     PN_CPP_EXTERN class event_loop &event_loop() const;
@@ -51,10 +58,16 @@ class connection : public counted_facade<pn_connection_t, connection, endpoint>
     /// Return the AMQP host name for the connection.
     PN_CPP_EXTERN std::string host() const;
 
+    /// Set the AMQP host name for the connection
+    PN_CPP_EXTERN void host(const std::string& h);
+
     /// Return the container-ID for the connection. All connections have a container_id,
     /// even if they don't have a container event_loop.
     PN_CPP_EXTERN std::string container_id() const;
 
+    // Set the container-ID for the connection
+    PN_CPP_EXTERN void container_id(const std::string& id);
+
     /** Initiate local open, not complete till messaging_handler::on_connection_opened()
      * or proton_handler::on_connection_remote_open()
      */
@@ -65,17 +78,21 @@ class connection : public counted_facade<pn_connection_t, connection, endpoint>
      */
     PN_CPP_EXTERN void close();
 
+    /** Release link and session resources of this connection
+     */
+    PN_CPP_EXTERN void release();
+
     /** Create a new session */
-    PN_CPP_EXTERN class session& open_session();
+    PN_CPP_EXTERN session open_session();
 
     /** Default session is created on first call and re-used for the lifetime of the connection */
-    PN_CPP_EXTERN class session& default_session();
+    PN_CPP_EXTERN session default_session();
 
     /** Create a sender on default_session() with target=addr and optional handler h */
-    PN_CPP_EXTERN sender& open_sender(const std::string &addr, handler *h=0);
+    PN_CPP_EXTERN sender open_sender(const std::string &addr, handler *h=0);
 
     /** Create a receiver on default_session() with target=addr and optional handler h */
-    PN_CPP_EXTERN receiver& open_receiver(const std::string &addr, bool dynamic=false, handler *h=0);
+    PN_CPP_EXTERN receiver open_receiver(const std::string &addr, bool dynamic=false, handler *h=0);
 
     /** Return links on this connection matching the state mask. */
     PN_CPP_EXTERN link_range find_links(endpoint::state mask) const;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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 de91505..984d37a 100644
--- a/proton-c/bindings/cpp/include/proton/container.hpp
+++ b/proton-c/bindings/cpp/include/proton/container.hpp
@@ -59,28 +59,28 @@ class container : public event_loop {
     PN_CPP_EXTERN ~container();
 
     /** Locally open a connection @see connection::open  */
-    PN_CPP_EXTERN connection& connect(const proton::url&, handler *h=0);
+    PN_CPP_EXTERN connection connect(const proton::url&, handler *h=0);
 
     /** Open a connection to url and create a receiver with source=url.path() */
-    PN_CPP_EXTERN acceptor& listen(const proton::url &);
+    PN_CPP_EXTERN acceptor listen(const proton::url &);
 
     /** Run the event loop, return when all connections and acceptors are closed. */
     PN_CPP_EXTERN void run();
 
     /** Open a connection to url and create a sender with target=url.path() */
-    PN_CPP_EXTERN sender& open_sender(const proton::url &);
+    PN_CPP_EXTERN sender open_sender(const proton::url &);
 
     /** Create a receiver on connection with source=url.path() */
-    PN_CPP_EXTERN receiver& open_receiver(const url &);
+    PN_CPP_EXTERN receiver open_receiver(const url &);
 
     /// Identifier for the container
     PN_CPP_EXTERN std::string id() const;
 
     /// The reactor associated with this container.
-    PN_CPP_EXTERN class reactor& reactor() const;
+    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, handler *h = 0);
 
   private:
     pn_unique_ptr<container_impl> impl_;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/counted_ptr.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/counted_ptr.hpp b/proton-c/bindings/cpp/include/proton/counted_ptr.hpp
index 7023bd7..0865e4a 100644
--- a/proton-c/bindings/cpp/include/proton/counted_ptr.hpp
+++ b/proton-c/bindings/cpp/include/proton/counted_ptr.hpp
@@ -78,7 +78,7 @@ template <class T> class counted_ptr : public proton::comparable<counted_ptr<T>
     T* get() const { return ptr_; }
     T* operator->() const { return ptr_; }
     T& operator*() const { return *ptr_; }
-    operator bool() const { return ptr_; }
+    operator bool() const { return !!ptr_; }
     bool operator!() const { return !ptr_; }
 
     template <class U> operator counted_ptr<U>() const { return counted_ptr<U>(get()); }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/data.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/data.hpp b/proton-c/bindings/cpp/include/proton/data.hpp
index 752765e..9ac0e82 100644
--- a/proton-c/bindings/cpp/include/proton/data.hpp
+++ b/proton-c/bindings/cpp/include/proton/data.hpp
@@ -22,7 +22,7 @@
 #include "proton/decoder.hpp"
 #include "proton/encoder.hpp"
 #include "proton/export.hpp"
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 #include "proton/pn_unique_ptr.hpp"
 
 #include <iosfwd>
@@ -37,14 +37,17 @@ class data;
  * Holds a sequence of AMQP values, allows inserting and extracting via encoder() and decoder().
  * Cannot be directly instantiated, use `value`
  */
-class data : public facade<pn_data_t, data, comparable<data> > {
+class data : public object<pn_data_t> {
   public:
-    PN_CPP_EXTERN static pn_unique_ptr<data> create();
+    data(pn_data_t* d) : object(d) {}
+    data(owned_object<pn_data_t> d) : object(d) {}
+
+    PN_CPP_EXTERN static owned_object<pn_data_t> create();
 
     PN_CPP_EXTERN data& operator=(const data&);
 
     template<class T> data& operator=(const T &t) {
-        clear(); encoder() << t; decoder().rewind(); return *this;
+        clear(); encoder() << t; return *this;
     }
 
     /** Clear the data. */
@@ -54,10 +57,26 @@ class data : public facade<pn_data_t, data, comparable<data> > {
     PN_CPP_EXTERN bool empty() const;
 
     /** Encoder to encode into this value */
-    PN_CPP_EXTERN class encoder& encoder();
+    PN_CPP_EXTERN class encoder encoder();
 
     /** Decoder to decode from this value */
-    PN_CPP_EXTERN class decoder& decoder();
+    PN_CPP_EXTERN class decoder decoder();
+
+    /** Return the data cursor position */
+    PN_CPP_EXTERN uintptr_t point() const;
+
+    /** Restore the cursor position to a previously saved position */
+    PN_CPP_EXTERN void restore(uintptr_t h);
+
+    PN_CPP_EXTERN void narrow();
+
+    PN_CPP_EXTERN void widen();
+
+    PN_CPP_EXTERN int append(data src);
+
+    PN_CPP_EXTERN int appendn(data src, int limit);
+
+    PN_CPP_EXTERN bool next() const;
 
     /** Rewind and return the type of the first value*/
     PN_CPP_EXTERN type_id type() const;
@@ -70,13 +89,11 @@ class data : public facade<pn_data_t, data, comparable<data> > {
     PN_CPP_EXTERN bool operator==(const data& x) const;
     PN_CPP_EXTERN bool operator<(const data& x) const;
 
-    PN_CPP_EXTERN void operator delete(void *);
-
     /** Human readable representation of data. */
   friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const data&);
-
+  friend class value;
   private:
-    class decoder& decoder() const { return const_cast<data*>(this)->decoder(); }
+    class decoder decoder() const { return const_cast<data*>(this)->decoder(); }
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/decoder.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/decoder.hpp b/proton-c/bindings/cpp/include/proton/decoder.hpp
index 3da078c..8f487bc 100644
--- a/proton-c/bindings/cpp/include/proton/decoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/decoder.hpp
@@ -22,8 +22,7 @@
 #include "proton/error.hpp"
 #include "proton/type_traits.hpp"
 #include "proton/types.hpp"
-#include "proton/facade.hpp"
-
+#include "proton/object.hpp"
 #include <iosfwd>
 
 #ifndef PN_NO_CONTAINER_CONVERT
@@ -45,6 +44,7 @@ struct pn_data_t;
 
 namespace proton {
 
+class data;
 class message_id;
 
 /** Raised by decoder operations on error.*/
@@ -148,8 +148,10 @@ Finally you can extract an AMQP LIST with mixed type elements into a container o
 
 You can also extract container values element-by-element, see decoder::operator>>(decoder&, start&)
 */
-class decoder : public facade<pn_data_t, decoder> {
+class decoder : public object<pn_data_t> {
   public:
+    decoder(pn_data_t* d) : object(d) {}
+
     /** Copy AMQP data from a byte buffer into the decoder. */
     PN_CPP_EXTERN decoder(const char* buffer, size_t size);
 
@@ -179,48 +181,39 @@ class decoder : public facade<pn_data_t, decoder> {
     /** Back up by one value */
     PN_CPP_EXTERN void backup();
 
-    PN_CPP_EXTERN class data& data();
+    PN_CPP_EXTERN class data data();
 
     /** @name Extract simple types
      * Overloads to extract simple types.
      * @throw error if the decoder is empty or the current value has an incompatible type.
      * @{
      */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_null);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_boolean&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_ubyte&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_byte&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_ushort&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_short&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_uint&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_int&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_char&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_ulong&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_long&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_timestamp&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_float&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_double&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_decimal32&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_decimal64&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_decimal128&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, amqp_uuid&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, std::string&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, message_id&);
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, value&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_null);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_boolean&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_ubyte&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_byte&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_ushort&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_short&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_uint&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_int&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_char&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_ulong&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_long&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_timestamp&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_float&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_double&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_decimal32&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_decimal64&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_decimal128&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_uuid&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, std::string&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, message_id&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, value&);
     ///@}
 
     /** Extract and return a value of type T. */
     template <class T> T extract() { T value; *this >> value; return value; }
 
-    /** Call decoder::start() in constructor, decoder::finish in destructor().
-     *
-     */
-    struct scope : public start {
-        decoder& decoder_;
-        scope(decoder& d) : decoder_(d) { d >> *this; }
-        ~scope() { decoder_ >> finish(); }
-    };
-
     /** start extracting a container value, one of array, list, map, described.
      * The basic pattern is:
      *
@@ -247,19 +240,19 @@ class decoder : public facade<pn_data_t, decoder> {
      *
      *@throw decoder::error if the current value is not a container type.
      */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, start&);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, start&);
 
     /** Finish extracting a container value. */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, finish);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, finish);
 
     /** Skip a value */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, struct skip);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, struct skip);
 
     /** Throw an exception if decoder.type() != assert_type.type */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, assert_type);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, assert_type);
 
     /** Rewind to the beginning */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, struct rewind);
+    PN_CPP_EXTERN friend decoder operator>>(decoder, struct rewind);
 
   private:
     PN_CPP_EXTERN void check_type(type_id);
@@ -267,11 +260,19 @@ class decoder : public facade<pn_data_t, decoder> {
   friend class encoder;
 };
 
+/** Call decoder::start() in constructor, decoder::finish in destructor().
+ *
+ */
+struct scope : public start {
+    decoder decoder_;
+    scope(decoder d) : decoder_(d) { decoder_ >> *this; }
+    ~scope() { decoder_ >> finish(); }
+};
 
 // operator >> for integer types that are not covered by the standard overrides.
 template <class T>
-typename enable_if<is_unknown_integer<T>::value, decoder&>::type
-operator>>(decoder& d, T& i)  {
+typename enable_if<is_unknown_integer<T>::value, decoder>::type
+operator>>(decoder d, T& i)  {
     typename integer_type<sizeof(T), is_signed<T>::value>::type v;
     d >> v;                     // Extract as a known integer type
     i = v;
@@ -336,8 +337,8 @@ template <class T> pairs_ref<T> to_pairs(T& v) { return pairs_ref<T>(v); }
  * the elements types are convertible to T. A MAP is extracted as [key1, value1,
  * key2, value2...]
  */
-template <class T> decoder& operator>>(decoder& d, sequence_ref<T> ref)  {
-    decoder::scope s(d);
+template <class T> decoder operator>>(decoder d, sequence_ref<T> ref)  {
+    scope s(d);
     if (s.is_described) d >> skip();
     T& v = ref.value;
     v.clear();
@@ -347,11 +348,11 @@ template <class T> decoder& operator>>(decoder& d, sequence_ref<T> ref)  {
     return d;
 }
 
-PN_CPP_EXTERN void assert_map_scope(const decoder::scope& s);
+PN_CPP_EXTERN void assert_map_scope(const scope& s);
 
 /** Extract an AMQP MAP to a C++ map */
-template <class T> decoder& operator>>(decoder& d, map_ref<T> ref)  {
-    decoder::scope s(d);
+template <class T> decoder operator>>(decoder d, map_ref<T> ref)  {
+    scope s(d);
     assert_map_scope(s);
     T& m = ref.value;
     m.clear();
@@ -365,8 +366,8 @@ template <class T> decoder& operator>>(decoder& d, map_ref<T> ref)  {
 }
 
 /** Extract an AMQP MAP to a C++ container of std::pair, preserving order. */
-template <class T> decoder& operator>>(decoder& d, pairs_ref<T> ref)  {
-    decoder::scope s(d);
+template <class T> decoder operator>>(decoder d, pairs_ref<T> ref)  {
+    scope s(d);
     assert_map_scope(s);
     T& m = ref.value;
     m.clear();
@@ -380,25 +381,24 @@ template <class T> decoder& operator>>(decoder& d, pairs_ref<T> ref)  {
 #ifndef PN_NO_CONTAINER_CONVERT
 
 // Decode to sequence.
-template <class T, class A> decoder& operator>>(decoder &d, std::vector<T, A>& v) { return d >> to_sequence(v); }
-template <class T, class A> decoder& operator>>(decoder &d, std::deque<T, A>& v) { return d >> to_sequence(v); }
-template <class T, class A> decoder& operator>>(decoder &d, std::list<T, A>& v) { return d >> to_sequence(v); }
+template <class T, class A> decoder operator>>(decoder d, std::vector<T, A>& v) { return d >> to_sequence(v); }
+template <class T, class A> decoder operator>>(decoder d, std::deque<T, A>& v) { return d >> to_sequence(v); }
+template <class T, class A> decoder operator>>(decoder d, std::list<T, A>& v) { return d >> to_sequence(v); }
 
 // Decode to map.
-template <class K, class T, class C, class A> decoder& operator>>(decoder &d, std::map<K, T, C, A>& v) { return d >> to_map(v); }
+template <class K, class T, class C, class A> decoder operator>>(decoder d, std::map<K, T, C, A>& v) { return d >> to_map(v); }
 
 #if PN_HAS_CPP11
 
 // Decode to sequence.
-template <class T, class A> decoder& operator>>(decoder &d, std::forward_list<T, A>& v) { return d >> to_sequence(v); }
-template <class T, std::size_t N> decoder& operator>>(decoder &d, std::array<T, N>& v) { return d >> to_sequence(v); }
+template <class T, class A> decoder operator>>(decoder d, std::forward_list<T, A>& v) { return d >> to_sequence(v); }
+template <class T, std::size_t N> decoder operator>>(decoder d, std::array<T, N>& v) { return d >> to_sequence(v); }
 
 // Decode to map.
-template <class K, class T, class C, class A> decoder& operator>>(decoder &d, std::unordered_map<K, T, C, A>& v) { return d >> to_map(v); }
+template <class K, class T, class C, class A> decoder operator>>(decoder d, std::unordered_map<K, T, C, A>& v) { return d >> to_map(v); }
 
 #endif // PN_HAS_CPP11
 #endif // PN_NO_CONTAINER_CONVERT
 
 }
-
 #endif // DECODER_H

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/delivery.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/delivery.hpp b/proton-c/bindings/cpp/include/proton/delivery.hpp
index 35c3b59..da62082 100644
--- a/proton-c/bindings/cpp/include/proton/delivery.hpp
+++ b/proton-c/bindings/cpp/include/proton/delivery.hpp
@@ -1,3 +1,4 @@
+
 #ifndef PROTON_CPP_DELIVERY_H
 #define PROTON_CPP_DELIVERY_H
 
@@ -22,7 +23,7 @@
  *
  */
 #include "proton/export.hpp"
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 
 #include "proton/delivery.h"
 #include "proton/disposition.h"
@@ -30,8 +31,10 @@
 namespace proton {
 
 /** delivery status of a message */
-class delivery : public counted_facade<pn_delivery_t, delivery> {
+class delivery : public object<pn_delivery_t> {
   public:
+    delivery(pn_delivery_t* d=0) : object(d) {}
+
     /** Delivery state of a message */
     enum state {
         NONE = 0, ///< Unknown state
@@ -108,6 +111,11 @@ class delivery : public counted_facade<pn_delivery_t, delivery> {
      * Get the remote disposition state for a delivery.
      */
     PN_CPP_EXTERN state remote_state() const;
+
+    /**
+     * Get the size of the current delivery
+     */
+    PN_CPP_EXTERN size_t pending() const;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/encoder.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/encoder.hpp b/proton-c/bindings/cpp/include/proton/encoder.hpp
index c10ad10..a28ea26 100644
--- a/proton-c/bindings/cpp/include/proton/encoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/encoder.hpp
@@ -22,7 +22,7 @@
 #include "proton/error.hpp"
 #include "proton/types.hpp"
 #include "proton/type_traits.hpp"
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 #include <iosfwd>
 
 #ifndef PN_NO_CONTAINER_CONVERT
@@ -44,6 +44,7 @@ struct pn_data_t;
 
 namespace proton {
 
+class data;
 class message_id;
 
 /** Raised by encoder operations on error */
@@ -88,8 +89,10 @@ struct encode_error : public error { PN_CPP_EXTERN explicit encode_error(const s
  *
  * You can also insert containers element-by-element, see operator<<(encoder&, const start&)
  */
-class encoder : public facade<pn_data_t, encoder> {
+class encoder : public object<pn_data_t> {
   public:
+    encoder(pn_data_t* e) : object(e) {}
+
     /**
      * Encode the current values into buffer and update size to reflect the number of bytes encoded.
      *
@@ -109,34 +112,34 @@ class encoder : public facade<pn_data_t, encoder> {
     /** Encode the current values into a std::string. Clears the encoder. */
     PN_CPP_EXTERN std::string encode();
 
-    PN_CPP_EXTERN class data& data();
+    PN_CPP_EXTERN class data data();
 
     /** @name Insert simple types.
      *@{
      */
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_null);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_boolean);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_ubyte);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_byte);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_ushort);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_short);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_uint);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_int);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_char);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_ulong);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_long);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_timestamp);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_float);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_double);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_decimal32);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_decimal64);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_decimal128);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_uuid);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_string);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_symbol);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, amqp_binary);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, const message_id&);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, const value&);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_null);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_boolean);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_ubyte);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_byte);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_ushort);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_short);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_uint);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_int);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_char);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_ulong);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_long);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_timestamp);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_float);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_double);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_decimal32);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_decimal64);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_decimal128);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_uuid);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_string);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_symbol);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_binary);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, const message_id&);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, const value&);
     ///@}
 
     /**
@@ -149,38 +152,38 @@ class encoder : public facade<pn_data_t, encoder> {
      *
      *      enc << start::list() << amqp_int(1) << amqp_symbol("two") << 3.0 << finish();
      */
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, const start&);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, const start&);
 
     /** Finish a container type. See operator<<(encoder&, const start&) */
-  friend PN_CPP_EXTERN encoder& operator<<(encoder& e, finish);
+  friend PN_CPP_EXTERN encoder operator<<(encoder e, finish);
 
 
     /**@name Insert values returned by the as<type_id> helper.
      *@{
      */
-  template <class T, type_id A> friend PN_CPP_EXTERN encoder& operator<<(encoder&, cref<T, A>);
-  template <class T> friend encoder& operator<<(encoder&, cref<T, ARRAY>);
-  template <class T> friend encoder& operator<<(encoder&, cref<T, LIST>);
-  template <class T> friend encoder& operator<<(encoder&, cref<T, MAP>);
+  template <class T, type_id A> friend PN_CPP_EXTERN encoder operator<<(encoder, cref<T, A>);
+  template <class T> friend encoder operator<<(encoder, cref<T, ARRAY>);
+  template <class T> friend encoder operator<<(encoder, cref<T, LIST>);
+  template <class T> friend encoder operator<<(encoder, cref<T, MAP>);
     // TODO aconway 2015-06-16: described values.
     ///@}
 };
 
 // Need to disambiguate char* conversion to bool and std::string as amqp_string.
-inline encoder& operator<<(encoder& e, char* s) { return e << amqp_string(s); }
-inline encoder& operator<<(encoder& e, const char* s) { return e << amqp_string(s); }
-inline encoder& operator<<(encoder& e, const std::string& s) { return e << amqp_string(s); }
+inline encoder operator<<(encoder e, char* s) { return e << amqp_string(s); }
+inline encoder operator<<(encoder e, const char* s) { return e << amqp_string(s); }
+inline encoder operator<<(encoder e, const std::string& s) { return e << amqp_string(s); }
 
 // operator << for integer types that are not covered by the standard overrides.
 template <class T>
-typename enable_if<is_unknown_integer<T>::value, encoder&>::type operator<<(encoder& e, T i)  {
+typename enable_if<is_unknown_integer<T>::value, encoder>::type operator<<(encoder e, T i)  {
     typename integer_type<sizeof(T), is_signed<T>::value>::type v = i;
     return e << v;              // Insert as a known integer type
 }
 
 // TODO aconway 2015-06-16: described array insertion.
 
-template <class T> encoder& operator<<(encoder& e, cref<T, ARRAY> a) {
+template <class T> encoder operator<<(encoder e, cref<T, ARRAY> a) {
     e << start::array(type_id_of<typename T::value_type>::value);
     for (typename T::const_iterator i = a.value.begin(); i != a.value.end(); ++i)
         e << *i;
@@ -188,7 +191,7 @@ template <class T> encoder& operator<<(encoder& e, cref<T, ARRAY> a) {
     return e;
 }
 
-template <class T> encoder& operator<<(encoder& e, cref<T, LIST> l) {
+template <class T> encoder operator<<(encoder e, cref<T, LIST> l) {
     e << start::list();
     for (typename T::const_iterator i = l.value.begin(); i != l.value.end(); ++i)
         e << *i;
@@ -196,7 +199,7 @@ template <class T> encoder& operator<<(encoder& e, cref<T, LIST> l) {
     return e;
 }
 
-template <class T> encoder& operator<<(encoder& e, cref<T, MAP> m){
+template <class T> encoder operator<<(encoder e, cref<T, MAP> m){
     e << start::map();
     for (typename T::const_iterator i = m.value.begin(); i != m.value.end(); ++i) {
         e << i->first;
@@ -208,30 +211,30 @@ template <class T> encoder& operator<<(encoder& e, cref<T, MAP> m){
 
 #ifndef PN_NO_CONTAINER_CONVERT
 // Encode as ARRAY
-template <class T, class A> encoder& operator<<(encoder &e, const std::vector<T, A>& v) { return e << as<ARRAY>(v); }
-template <class T, class A> encoder& operator<<(encoder &e, const std::deque<T, A>& v) { return e << as<ARRAY>(v); }
-template <class T, class A> encoder& operator<<(encoder &e, const std::list<T, A>& v) { return e << as<ARRAY>(v); }
+template <class T, class A> encoder operator<<(encoder e, const std::vector<T, A>& v) { return e << as<ARRAY>(v); }
+template <class T, class A> encoder operator<<(encoder e, const std::deque<T, A>& v) { return e << as<ARRAY>(v); }
+template <class T, class A> encoder operator<<(encoder e, const std::list<T, A>& v) { return e << as<ARRAY>(v); }
 
 // Encode as LIST
-template <class A> encoder& operator<<(encoder &e, const std::vector<value, A>& v) { return e << as<LIST>(v); }
-template <class A> encoder& operator<<(encoder &e, const std::deque<value, A>& v) { return e << as<LIST>(v); }
-template <class A> encoder& operator<<(encoder &e, const std::list<value, A>& v) { return e << as<LIST>(v); }
+template <class A> encoder operator<<(encoder e, const std::vector<value, A>& v) { return e << as<LIST>(v); }
+template <class A> encoder operator<<(encoder e, const std::deque<value, A>& v) { return e << as<LIST>(v); }
+template <class A> encoder operator<<(encoder e, const std::list<value, A>& v) { return e << as<LIST>(v); }
 
 // Encode as MAP
-template <class K, class T, class C, class A> encoder& operator<<(encoder &e, const std::map<K, T, C, A>& v) { return e << as<MAP>(v); }
+template <class K, class T, class C, class A> encoder operator<<(encoder e, const std::map<K, T, C, A>& v) { return e << as<MAP>(v); }
 
 #if PN_HAS_CPP11
 
 // Encode as ARRAY.
-template <class T, class A> encoder& operator<<(encoder &e, const std::forward_list<T, A>& v) { return e << as<ARRAY>(v); }
-template <class T, std::size_t N> encoder& operator<<(encoder &e, const std::array<T, N>& v) { return e << as<ARRAY>(v); }
+template <class T, class A> encoder operator<<(encoder e, const std::forward_list<T, A>& v) { return e << as<ARRAY>(v); }
+template <class T, std::size_t N> encoder operator<<(encoder e, const std::array<T, N>& v) { return e << as<ARRAY>(v); }
 
 // Encode as LIST.
-template <class A> encoder& operator<<(encoder &e, const std::forward_list<value, A>& v) { return e << as<LIST>(v); }
-template <std::size_t N> encoder& operator<<(encoder &e, const std::array<value, N>& v) { return e << as<LIST>(v); }
+template <class A> encoder operator<<(encoder e, const std::forward_list<value, A>& v) { return e << as<LIST>(v); }
+template <std::size_t N> encoder operator<<(encoder e, const std::array<value, N>& v) { return e << as<LIST>(v); }
 
 // Encode as map.
-template <class K, class T, class C, class A> encoder& operator<<(encoder &e, const std::unordered_map<K, T, C, A>& v) { return e << as<MAP>(v); }
+template <class K, class T, class C, class A> encoder operator<<(encoder e, const std::unordered_map<K, T, C, A>& v) { return e << as<MAP>(v); }
 
 #endif // PN_HAS_CPP11
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/endpoint.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/endpoint.hpp b/proton-c/bindings/cpp/include/proton/endpoint.hpp
index d1cccb5..9e6fa8d 100644
--- a/proton-c/bindings/cpp/include/proton/endpoint.hpp
+++ b/proton-c/bindings/cpp/include/proton/endpoint.hpp
@@ -69,15 +69,15 @@ template <class T> class iter_base {
     typedef T value_type;
 
     T& operator*() const { return *ptr_; }
-    T* operator->() const { return ptr_; }
-    operator bool() const { return ptr_; }
+    const T* operator->() const { return &ptr_; }
+    operator bool() const { return !!ptr_; }
     bool operator !() const { return !ptr_; }
     bool operator==(const iter_base<T>& x) const { return ptr_ == x.ptr_; }
     bool operator!=(const iter_base<T>& x) const { return ptr_ != x.ptr_; }
 
   protected:
-    explicit iter_base(T* p = 0, endpoint::state s = 0) : ptr_(p), state_(s) {}
-    T* ptr_;
+    explicit iter_base(T p = 0, endpoint::state s = 0) : ptr_(p), state_(s) {}
+    T ptr_;
     endpoint::state state_;
 };
 ///@endcond INTERNAL
@@ -94,35 +94,6 @@ template<class I> class range {
     I begin_, end_;
 };
 
-/// An iterator for sessions.
-class session_iterator : public iter_base<session> {
- public:
-    explicit session_iterator(session* p = 0, endpoint::state s = 0) :
-        iter_base<session>(p, s) {}
-    PN_CPP_EXTERN session_iterator operator++();
-    session_iterator operator++(int) { session_iterator x(*this); ++(*this); return x; }
-};
-
-/// A range of sessions.
-typedef range<session_iterator> session_range;
-
-/// An iterator for links.
-class link_iterator : public iter_base<link> {
-  public:
-    explicit link_iterator(link* p = 0, endpoint::state s = 0) :
-        iter_base<link>(p, s), session_(0) {}
-    explicit link_iterator(const link_iterator& i, const session *ssn) :
-        iter_base<link>(i.ptr_, i.state_), session_(ssn) {}
-    PN_CPP_EXTERN link_iterator operator++();
-    link_iterator operator++(int) { link_iterator x(*this); ++(*this); return x; }
-
-  private:
-    const session* session_;
-};
-
-/// A range of links.
-typedef range<link_iterator> link_range;
-
 }
 
 #endif  /*!PROTON_CPP_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/engine.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/engine.hpp b/proton-c/bindings/cpp/include/proton/engine.hpp
index f27033d..340d21b 100644
--- a/proton-c/bindings/cpp/include/proton/engine.hpp
+++ b/proton-c/bindings/cpp/include/proton/engine.hpp
@@ -139,7 +139,7 @@ class engine : public event_loop {
     PN_CPP_EXTERN bool closed() const;
 
     /** The AMQP connection associated with this engine. */
-    PN_CPP_EXTERN class connection&  connection() const;
+    PN_CPP_EXTERN class connection  connection() const;
 
     /** The AMQP container-id associated with this engine. */
     PN_CPP_EXTERN  std::string id() const;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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 ed310f1..f0ba897 100644
--- a/proton-c/bindings/cpp/include/proton/event.hpp
+++ b/proton-c/bindings/cpp/include/proton/event.hpp
@@ -46,24 +46,24 @@ class event {
     virtual PN_CPP_EXTERN std::string name() const = 0;
 
     /// Get the event_loop object, can be a container or an engine.
-    virtual PN_CPP_EXTERN class event_loop &event_loop() const;
+    virtual PN_CPP_EXTERN class event_loop& event_loop() const;
 
     /// Get the container, throw an exception if event_loop is not a container.
-    virtual PN_CPP_EXTERN class container &container() const;
+    virtual PN_CPP_EXTERN class container& container() const;
 
     /// Get the engine, , throw an exception if event_loop is not an engine.
-    virtual PN_CPP_EXTERN class engine &engine() const;
+    virtual PN_CPP_EXTERN class engine& engine() const;
 
     /// Get connection.
-    virtual PN_CPP_EXTERN class connection &connection() const;
+    virtual PN_CPP_EXTERN class connection connection() const;
     /// Get sender @throws error if no sender.
-    virtual PN_CPP_EXTERN class sender& sender() const;
+    virtual PN_CPP_EXTERN class sender sender() const;
     /// Get receiver @throws error if no receiver.
-    virtual PN_CPP_EXTERN class receiver& receiver() const;
+    virtual PN_CPP_EXTERN class receiver receiver() const;
     /// Get link @throws error if no link.
-    virtual PN_CPP_EXTERN class link& link() const;
+    virtual PN_CPP_EXTERN class link link() const;
     /// Get delivery @throws error if no delivery.
-    virtual PN_CPP_EXTERN class delivery& delivery() const;
+    virtual PN_CPP_EXTERN class delivery delivery() const;
     /** Get message @throws error if no message. */
     virtual PN_CPP_EXTERN class message &message() const;
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/event_loop.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/event_loop.hpp b/proton-c/bindings/cpp/include/proton/event_loop.hpp
index e5dff37..fcc83d8 100644
--- a/proton-c/bindings/cpp/include/proton/event_loop.hpp
+++ b/proton-c/bindings/cpp/include/proton/event_loop.hpp
@@ -23,10 +23,12 @@
 
 #include <string>
 
+namespace proton {
+
 /**
  * An event_loop dispatches events to event handlers.  event_loop is an abstract
  * class, concrete subclasses are proton::container and prton::engine.
-*/
+ */
 class event_loop {
   public:
     PN_CPP_EXTERN virtual ~event_loop() {}
@@ -38,4 +40,5 @@ class event_loop {
     // TODO aconway 2015-11-02: injecting application events.
 };
 
+}
 #endif // EVENT_LOOP_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/facade.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/facade.hpp b/proton-c/bindings/cpp/include/proton/facade.hpp
deleted file mode 100644
index 7900ada..0000000
--- a/proton-c/bindings/cpp/include/proton/facade.hpp
+++ /dev/null
@@ -1,145 +0,0 @@
-#ifndef PROTON_CPP_FACADE_H
-#define PROTON_CPP_FACADE_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.
- *
- */
-
-/*! \page c-and-cpp C and memory management.
- *\brief
- *
- * The C++ API is a very thin wrapper over the C API.  The C API consists of a
- * set of `struct` types and associated C functions.  For each there is a a C++
- * `facade` that provides C++ member functions to call the corresponding C
- * functions on the underlying C struct. Facade classes derive from the
- * `proton::facade` template.
- *
- * The facade class occupies no additional memory. The C+ facade pointer points
- * directly to the underlying C++ struct, calling C++ member functions corresponds
- * directly to calling the C function.
- *
- * If you want to mix C and C++ code (which should be done carefully!) you can
- * cast between a facade pointer and a C struct pointer with `proton::pn_cast`
- * and `foo::cast()` where `foo` is some C++ facade class.
- *
- * Deleting a facade object calls the appropriate `pn_foo_free` function or
- * `pn_decref` as appropriate.
- *
- * Some proton structs are reference counted, the facade classes for these
- * derive from the `proton::counted_facade` template. Most proton functions that
- * return facade objects return a reference to an object that is owned by the
- * called object. Such references are only valid in a limited scope (for example
- * in an event handler function.) To keep a reference outside that scope, call
- * the `ptr()` member function. This returns a `proton::counted_ptr`, which you
- * can convert safely to `std::shared_ptr`, `std::unique_ptr`,
- * `boost::shared_ptr`, or `boost::intrusive_ptr`.
- */
-
-/**@file
- * Classes and templates used by object facades.
- */
-
-#include "proton/export.hpp"
-#include "counted_ptr.hpp"
-
-namespace proton {
-
-///@cond INTERNAL
-struct empty_base {};
-///@endcond
-
-/**
- * Base class for C++ facades of proton C struct types.
- *
- * @see \ref c-and-cpp
- */
-template <class P, class T, class Base=empty_base> class facade : public Base {
-  public:
-    /// The underlying C struct type.
-    typedef P pn_type;
-
-    /// Cast the C struct pointer to a C++ facade pointer.
-    static T* cast(P* p) { return reinterpret_cast<T*>(p); }
-
-  private:
-    facade();
-    facade(const facade&);
-    facade& operator=(const facade&);
-    void operator delete(void* p);
-};
-
-/** Cast a facade type to the C struct type.
- * Allow casting away const, the underlying pn structs have not constness.
- */
-template <class T> typename T::pn_type* pn_cast(const T* p) {
-    return reinterpret_cast<typename T::pn_type*>(const_cast<T*>(p));
-}
-
-/** Cast a counted pointer to a facade type to the C struct type.
- * Allow casting away const, the underlying pn structs have not constness.
- */
-template <class T> typename T::pn_type* pn_cast(const counted_ptr<T>& p) {
-    return reinterpret_cast<typename T::pn_type*>(const_cast<T*>(p.get()));
-}
-
-/**
- * Some proton C structs are reference counted. The C++ facade for such structs can be
- * converted to any of the following smart pointers: std::shared_ptr, std::unique_ptr,
- * boost::shared_ptr, boost::intrusive_ptr.
- *
- * unique_ptr takes ownership of a single *reference* not the underlying struct,
- * so it is safe to have multiple unique_ptr to the same facade object or to mix
- * unique_ptr with shared_ptr etc.
- *
- * Deleting a counted_facade subclass actually calls `pn_decref` to remove a reference.
- */
-template <class P, class T, class Base=empty_base>
-class counted_facade : public facade<P, T, Base>
-{
-  public:
-
-    /// Deleting a counted_facade actually calls `pn_decref` to remove a reference.
-    void operator delete(void* p) { decref(p); }
-
-    /** Get a reference-counted pointer to the underlying object.  It can be
-     * converted safely to `std::shared_ptr`, `std::unique_ptr`,
-     * `boost::shared_ptr`, or `boost::intrusive_ptr`.
-     */
-    counted_ptr<T> ptr() {
-        return counted_ptr<T>(static_cast<T*>(this));
-    }
-
-    /** Get a reference-counted pointer to the underlying object.  It can be
-     * converted safely to `std::shared_ptr`, `std::unique_ptr`,
-     * `boost::shared_ptr`, or `boost::intrusive_ptr`.
-     */
-    counted_ptr<const T> ptr() const {
-        return counted_ptr<const T>(static_cast<const T*>(this));
-    }
-
-  private:
-    counted_facade(const counted_facade&);
-    counted_facade& operator=(const counted_facade&);
-
-  template <class U> friend class counted_ptr;
-};
-
-}
-#endif  /*!PROTON_CPP_FACADE_H*/

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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
index 65ff437..70da48b 100644
--- a/proton-c/bindings/cpp/include/proton/handler.hpp
+++ b/proton-c/bindings/cpp/include/proton/handler.hpp
@@ -22,6 +22,7 @@
  *
  */
 #include "proton/export.hpp"
+#include "proton/counted_ptr.hpp"
 #include "proton/event.hpp"
 #include "proton/event.h"
 #include "proton/reactor.h"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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 b4b40e0..d73156e 100644
--- a/proton-c/bindings/cpp/include/proton/link.hpp
+++ b/proton-c/bindings/cpp/include/proton/link.hpp
@@ -26,7 +26,7 @@
 #include "proton/message.hpp"
 #include "proton/terminus.hpp"
 #include "proton/types.h"
-#include "proton/facade.hpp"
+#include "proton/object.hpp"
 
 #include <string>
 
@@ -36,9 +36,11 @@ class sender;
 class receiver;
 
 /** Messages are transferred across a link. Base class for sender, receiver. */
-class link : public counted_facade<pn_link_t, link, endpoint>
+class link : public object<pn_link_t> , public endpoint
 {
   public:
+    link(pn_link_t* l=0) : object(l) {}
+
     /** Locally open the link, not complete till messaging_handler::on_link_opened or
      * proton_handler::link_remote_open
      */
@@ -50,33 +52,36 @@ class link : public counted_facade<pn_link_t, link, endpoint>
     PN_CPP_EXTERN void close();
 
     /** Return sender if this link is a sender, 0 if not. */
-    PN_CPP_EXTERN class sender* sender();
-    PN_CPP_EXTERN const class sender* sender() const;
+    PN_CPP_EXTERN class sender sender();
+    PN_CPP_EXTERN const class sender sender() const;
 
     /** Return receiver if this link is a receiver, 0 if not. */
-    PN_CPP_EXTERN class receiver* receiver();
-    PN_CPP_EXTERN const class receiver* receiver() const;
+    PN_CPP_EXTERN class receiver receiver();
+    PN_CPP_EXTERN const class receiver receiver() const;
 
     /** Credit available on the link */
     PN_CPP_EXTERN int credit() const;
 
+    /** Grant credit to the link */
+    PN_CPP_EXTERN void flow(int credit);
+
     /** Local source of the link. */
-    PN_CPP_EXTERN terminus& source() const;
+    PN_CPP_EXTERN terminus source() const;
     /** Local target of the link. */
-    PN_CPP_EXTERN terminus& target() const;
+    PN_CPP_EXTERN terminus target() const;
     /** Remote source of the link. */
-    PN_CPP_EXTERN terminus& remote_source() const;
+    PN_CPP_EXTERN terminus remote_source() const;
     /** Remote target of the link. */
-    PN_CPP_EXTERN terminus& remote_target() const;
+    PN_CPP_EXTERN terminus remote_target() const;
 
     /** Link name */
     PN_CPP_EXTERN std::string name() const;
 
     /** Connection that owns this link */
-    PN_CPP_EXTERN class connection &connection() const;
+    PN_CPP_EXTERN class connection connection() const;
 
     /** Session that owns this link */
-    PN_CPP_EXTERN class session &session() const;
+    PN_CPP_EXTERN class session session() const;
 
     /** Set a custom handler for this link. */
     PN_CPP_EXTERN void handler(class handler &);
@@ -86,8 +91,33 @@ class link : public counted_facade<pn_link_t, link, endpoint>
 
     /** Get the endpoint state */
     PN_CPP_EXTERN endpoint::state state() const;
+
+    /** Get message data from current delivery on link */
+    PN_CPP_EXTERN ssize_t recv(char* buffer, size_t size);
+
+    /** Advance the link one delivery */
+    PN_CPP_EXTERN bool advance();
+
+    /** Navigate the links in a connection - get next link with state */
+    PN_CPP_EXTERN link next(endpoint::state) const;
+};
+
+/// An iterator for links.
+class link_iterator : public iter_base<link> {
+  public:
+    explicit link_iterator(link p = 0, endpoint::state s = 0) :
+        iter_base<link>(p, s), session_(0) {}
+    explicit link_iterator(const link_iterator& i, const session& ssn) :
+        iter_base<link>(i.ptr_, i.state_), session_(&ssn) {}
+    PN_CPP_EXTERN link_iterator operator++();
+    link_iterator operator++(int) { link_iterator x(*this); ++(*this); return x; }
+
+  private:
+    const session* session_;
 };
 
+/// A range of links.
+typedef range<link_iterator> link_range;
 }
 
 #include "proton/sender.hpp"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/message.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/message.hpp b/proton-c/bindings/cpp/include/proton/message.hpp
index f68873b..0954b49 100644
--- a/proton-c/bindings/cpp/include/proton/message.hpp
+++ b/proton-c/bindings/cpp/include/proton/message.hpp
@@ -24,7 +24,6 @@
 
 #include "proton/data.hpp"
 #include "proton/export.hpp"
-#include "proton/facade.hpp"
 #include "proton/message_id.hpp"
 #include "proton/pn_unique_ptr.hpp"
 #include "proton/value.hpp"
@@ -104,10 +103,10 @@ class message
     PN_CPP_EXTERN void body(const value&);
 
     /** Get the body. Note data can be copied to a proton::value */
-    PN_CPP_EXTERN const data& body() const;
+    PN_CPP_EXTERN const data body() const;
 
     /** Get a reference to the body data, can be modified in-place. */
-    PN_CPP_EXTERN data& body();
+    PN_CPP_EXTERN data body();
 
     /** Set the application properties. Must be a map with string keys or an
      * empty value. You can assign to a proton::value from a standard C++ map
@@ -119,10 +118,10 @@ class message
      * an empty value. You can assign proton::value containing a map to a
      * standard C++ map of std::string to proton::value.
      */
-    PN_CPP_EXTERN const data& properties() const;
+    PN_CPP_EXTERN const data properties() const;
 
     /** Get a reference to the application properties, can be modified in-place.*/
-    PN_CPP_EXTERN data& properties();
+    PN_CPP_EXTERN data properties();
 
     /** Set an individual application property. */
     PN_CPP_EXTERN void property(const std::string &name, const value &);
@@ -143,7 +142,7 @@ class message
     PN_CPP_EXTERN void decode(const std::string &bytes);
 
     /// Decode the message from link corresponding to delivery.
-    PN_CPP_EXTERN void decode(proton::link&, proton::delivery&);
+    PN_CPP_EXTERN void decode(proton::link, proton::delivery);
 
     /**
      * Get the inferred flag for a message.

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/message_id.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/message_id.hpp b/proton-c/bindings/cpp/include/proton/message_id.hpp
index d6ce186..8e0adf1 100644
--- a/proton-c/bindings/cpp/include/proton/message_id.hpp
+++ b/proton-c/bindings/cpp/include/proton/message_id.hpp
@@ -68,13 +68,14 @@ class message_id : public comparable<message_id> {
     bool operator<(const message_id& x) const { return value_ < x.value_; }
 
   friend std::ostream& operator<<(std::ostream&, const message_id&);
-  friend PN_CPP_EXTERN encoder& operator<<(encoder&, const message_id&);
-  friend PN_CPP_EXTERN decoder& operator>>(decoder&, message_id&);
+  friend PN_CPP_EXTERN encoder operator<<(encoder, const message_id&);
+  friend PN_CPP_EXTERN decoder operator>>(decoder, message_id&);
 
   private:
-    message_id(const data& d) : value_(d) {}
+    //message_id(const data d) : value_(d) {}
     value value_;
   friend class message;
+  friend class data;
 };
 
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/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
index 29a26c6..6e4342d 100644
--- a/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
+++ b/proton-c/bindings/cpp/include/proton/messaging_adapter.hpp
@@ -22,7 +22,6 @@
  *
  */
 
-#include "proton/facade.hpp"
 #include "proton/messaging_handler.hpp"
 
 #include "proton/event.h"

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/645fe09e/proton-c/bindings/cpp/include/proton/object.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/object.hpp b/proton-c/bindings/cpp/include/proton/object.hpp
new file mode 100644
index 0000000..118f40d
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/object.hpp
@@ -0,0 +1,113 @@
+#ifndef OBJECT_HPP
+#define OBJECT_HPP
+/*
+ * 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/config.hpp"
+#include "proton/export.hpp"
+
+#include <memory>
+
+namespace proton {
+
+/**
+ * Base class for proton object types
+ *
+ * Automatically perform memory management for pn_object based types.
+ *
+ * Note that for the memory management to work correctly no class
+ * inheriting from this should define any data members of its own.
+ * 
+ * This is ok because the entire purpose of this class is to provide
+ * and manage the underlying pointer to the proton-c object.
+ * 
+ * So any class using this one needs to be merely a thin wrapping of
+ * the proton-c object with no data members of it's own. Anything that internally
+ * needs extra data members and a proton-c object must use an inheritor of
+ * object<> as a data member - it must not inherit and add data members.
+ * 
+ */
+class object_base {
+  public:
+    object_base() : object_(0) {}
+    object_base(void* o) : object_(o) {}
+    object_base(const object_base& o) : object_(o.object_) { incref(); }
+
+    #ifdef PN_HAS_CPP11
+    object_base(object_base&& o) : object_base() { *this = o; }
+    #endif
+
+    ~object_base() { decref(); };
+
+    object_base& operator=(object_base o)
+    { std::swap(object_, o.object_); return *this; }
+
+    bool operator!() const { return !object_; }
+
+  private:
+    PN_CPP_EXTERN void incref() const;
+    PN_CPP_EXTERN void decref() const;
+
+    void* object_;
+
+  template <class T>
+  friend class object;
+  template <class T>
+  friend class owned_object;
+  friend bool operator==(const object_base&, const object_base&);
+};
+
+template <class T>
+class owned_object : public object_base {
+  public:
+    owned_object(T* o) : object_base(o) {};
+
+  protected:
+    T* pn_object() const { return static_cast<T*>(object_); }
+
+  template <class U>
+  friend class object;
+};
+
+template <class T>
+class object : public object_base {
+  public:
+    object(T* o, bool take_own=false) : object_base(o) { if (!take_own) incref(); };
+    object(owned_object<T> o) : object_base(o.object_) { o.object_=0; };
+
+    object& operator=(owned_object<T> o)
+    { object_ = o.object_; o = 0; return *this; }
+
+  protected:
+    static const bool take_ownership = true;
+    T* pn_object() const { return static_cast<T*>(object_); }
+};
+
+inline
+bool operator==(const object_base& o1, const object_base& o2) {
+    return o1.object_==o2.object_;
+}
+
+inline
+bool operator!=(const object_base& o1, const object_base& o2) {
+    return !(o1==o2);
+}
+
+}
+#endif // OBJECT_HPP


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