You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rh...@apache.org on 2014/11/28 14:49:45 UTC

[07/51] [abbrv] qpid-proton git commit: Pulling in changes from proton r1590241

Pulling in changes from proton r1590241

git-svn-id: https://svn.apache.org/repos/asf/qpid/proton/branches/fadams-javascript-binding@1590242 13f79535-47bb-0310-9956-ffa450edef68


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

Branch: refs/heads/master
Commit: 33c895ec6a569aa93def2e42fd7b4bcbb5b49250
Parents: aa766d0
Author: fadams <fa...@unknown>
Authored: Sat Apr 26 15:37:34 2014 +0000
Committer: fadams <fa...@unknown>
Committed: Sat Apr 26 15:37:34 2014 +0000

----------------------------------------------------------------------
 CMakeLists.txt                                  |  81 +--
 README                                          | 297 ++++----
 examples/CMakeLists.txt                         |  22 +
 examples/ProtonConfig.cmake                     |  23 +
 examples/include/pncompat/misc_funcs.inc        |   2 +-
 examples/messenger/c/CMakeLists.txt             |  24 +-
 examples/messenger/c/recv.c                     |  17 +-
 examples/messenger/c/send.c                     |   7 +-
 examples/messenger/ruby/passive_recv.rb         | 140 ++++
 proton-c/CMakeLists.txt                         | 130 ++--
 proton-c/bindings/CMakeLists.txt                |  27 +
 proton-c/bindings/javascript/binding.js         | 140 ++--
 proton-c/bindings/javascript/drain.js           |   6 +-
 proton-c/bindings/javascript/spout.js           |   2 +
 proton-c/bindings/perl/CMakeLists.txt           |  57 +-
 proton-c/bindings/perl/perl.i                   |   4 +-
 proton-c/bindings/php/CMakeLists.txt            |  44 +-
 proton-c/bindings/php/compat.swg                |  50 ++
 proton-c/bindings/php/php.i                     |   3 +
 proton-c/bindings/php/proton.ini.in             |  21 +
 proton-c/bindings/php/proton.php                |   2 +-
 proton-c/bindings/python/CMakeLists.txt         |  35 +-
 proton-c/bindings/python/proton.py              |  16 +-
 proton-c/bindings/ruby/CMakeLists.txt           |  23 +-
 proton-c/bindings/ruby/lib/qpid_proton.rb       |   3 +-
 .../bindings/ruby/lib/qpid_proton/filters.rb    |  67 ++
 .../bindings/ruby/lib/qpid_proton/messenger.rb  |  61 +-
 .../bindings/ruby/lib/qpid_proton/selectable.rb | 126 ++++
 .../ruby/spec/qpid/proton/messenger_spec.rb     |  10 +
 proton-c/include/proton/codec.h                 |   5 -
 proton-c/include/proton/condition.h             |   4 +-
 proton-c/include/proton/connection.h            |   4 +-
 proton-c/include/proton/container.h             |   4 +-
 proton-c/include/proton/delivery.h              |   4 +-
 proton-c/include/proton/disposition.h           |   4 +-
 proton-c/include/proton/event.h                 |  36 +-
 proton-c/include/proton/framing.h               |   4 -
 proton-c/include/proton/io.h                    |   3 -
 proton-c/include/proton/link.h                  |   4 +-
 proton-c/include/proton/message.h               | 684 ++++++++++++++++++-
 proton-c/include/proton/object.h                |   5 -
 proton-c/include/proton/sasl.h                  |   4 +-
 proton-c/include/proton/selectable.h            |   4 +-
 proton-c/include/proton/selector.h              |   4 +-
 proton-c/include/proton/session.h               |   4 +-
 proton-c/include/proton/ssl.h                   |   4 +-
 proton-c/include/proton/terminus.h              |   4 +-
 proton-c/include/proton/transport.h             |   4 +-
 proton-c/include/proton/type_compat.h           |  84 ++-
 proton-c/include/proton/types.h                 |  83 ++-
 proton-c/src/ProtonConfig.cmake.in              |  30 +
 proton-c/src/ProtonConfigVersion.cmake.in       |  30 +
 proton-c/src/engine/engine.c                    |  68 +-
 proton-c/src/engine/event.c                     |  23 +-
 proton-c/src/libqpid-proton.cmake.in            |  29 -
 proton-c/src/messenger/messenger.c              |  15 +-
 proton-c/src/object/object.c                    |  10 +-
 proton-c/src/platform.h                         |   8 +-
 proton-c/src/platform_fmt.h                     |  19 +
 proton-c/src/posix/io.c                         |  18 +-
 proton-c/src/proton.c                           |  21 +-
 proton-c/src/ssl/openssl.c                      |  10 +-
 proton-c/src/tests/CMakeLists.txt               |   6 +-
 proton-c/src/tests/parse-url.c                  |  22 +-
 proton-c/src/transport/transport.c              |  21 +-
 proton-c/src/util.c                             |  54 +-
 proton-j/CMakeLists.txt                         |   4 +
 .../org/apache/qpid/proton/engine/Event.java    |  34 +-
 .../qpid/proton/engine/impl/ConnectionImpl.java |  12 +-
 .../qpid/proton/engine/impl/EndpointImpl.java   |   4 +
 .../qpid/proton/engine/impl/EventImpl.java      |   5 +
 .../qpid/proton/engine/impl/FrameParser.java    |   2 +-
 .../qpid/proton/engine/impl/LinkImpl.java       |   9 +
 .../qpid/proton/engine/impl/SenderImpl.java     |   1 -
 .../qpid/proton/engine/impl/SessionImpl.java    |   9 +
 .../qpid/proton/engine/impl/TransportImpl.java  |  51 +-
 .../qpid/proton/message/impl/MessageImpl.java   |  26 +-
 .../qpid/proton/messenger/impl/Address.java     |  24 +-
 proton-j/src/main/resources/cengine.py          |  20 +-
 .../qpid/proton/messenger/impl/AddressTest.java |  15 +-
 tests/python/proton_tests/common.py             |   8 +
 tests/python/proton_tests/engine.py             |  30 +-
 tests/python/proton_tests/soak.py               |  26 +-
 tests/python/proton_tests/ssl.py                |   7 +-
 tools/cmake/Modules/FindJava.cmake              |   2 +-
 85 files changed, 2338 insertions(+), 731 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c8d0b03..a503467 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -69,26 +69,31 @@ set (SYSCONF_INSTALL_DIR etc CACHE PATH "System read only configuration director
 set (SHARE_INSTALL_DIR share CACHE PATH "Shared read only data directory")
 set (MAN_INSTALL_DIR share/man CACHE PATH "Manpage directory")
 
+mark_as_advanced (INCLUDE_INSTALL_DIR LIB_INSTALL_DIR SYSCONF_INSTALL_DIR SHARE_INSTALL_DIR MAN_INSTALL_DIR)
+
 ## LANGUAGE BINDINGS
-#  If ASK_$LANG is 1 then the language is queried for the directory into which
-#  those language bindings are to be installed. If it is 0 then the bindings
-#  are installed to $CMAKE_INSTALL_PREFIX/bindings/$LANG
-#
-set (BINDINGS_DIR bindings CACHE PATH "Default directory for language bindings")
-set (ASK_PERL 0 CACHE INTEGER "Ask Perl for install directories")
-set (ASK_PHP 0 CACHE INTEGER "Ask PHP for install directories")
-set (ASK_PYTHON 0 CACHE INTEGER "Ask Python for install directories")
-set (ASK_RUBY 0 CACHE INTEGER "Ask Ruby for install directories")
-set (ASK_ALL 0 CACHE INTEGER "If 1 then ask all languages for their directory")
-
-if (ASK_ALL)
-  set (ASK_PERL 1)
-  set (ASK_PHP 1)
-  set (ASK_PYTHON 1)
-  set (ASK_RUBY 1)
-endif (ASK_ALL)
-
-message(STATUS "PYTHON_ARCHLIB_DIR=${PYTHON_ARCHLIB_DIR}")
+
+# Default directory for language bindings not being installed into
+# system specified locations.
+set (BINDINGS_DIR ${LIB_INSTALL_DIR}/proton/bindings)
+
+set (SYSINSTALL_BINDINGS "*UNSPECIFIED*" CACHE BOOL "If SYSINSTALL_BINDINGS is OFF then proton bindings will be installed underneath ${BINDINGS_DIR} and each user will need to modify their interpreter configuration to load the appropriate binding. If SYSINSTALL_BINDINGS is ON, then each language interpreter will be queried for the appropriate directory and proton bindings will be installed and available system wide with no additional per user configuration.")
+
+if (SYSINSTALL_BINDINGS STREQUAL "*UNSPECIFIED*")
+  message(WARNING "SYSINSTALL_BINDINGS is unspecified, defaulting it to OFF. Please note that the default install behaviour of proton has changed. Proton bindings by default will now be installed under ${BINDINGS_DIR} and will no longer be found by system interpreters. This means that every user will be required to manually configure their interpreters to locate the proton bindings. If you wish proton bindings to be installed into the interpreter specified locations as was the default in prior releases, please specify -DSYSINSTALL_BINDINGS=ON")
+  set (SYSINSTALL_BINDINGS OFF)
+endif ()
+
+set (BINDING_LANGS PERL PHP PYTHON RUBY)
+
+foreach (LANG ${BINDING_LANGS})
+  set (SYSINSTALL_${LANG} OFF CACHE BOOL "Install ${LANG} bindings into interpreter specified location.")
+  if (SYSINSTALL_BINDINGS OR SYSINSTALL_${LANG})
+    set (CHECK_SYSINSTALL_${LANG} ON)
+  else ()
+    set (CHECK_SYSINSTALL_${LANG} OFF)
+  endif ()
+endforeach()
 
 if (WIN32)
   set (EXAMPLES_INSTALL_DIR proton/examples)
@@ -98,32 +103,29 @@ if (UNIX)
   set (EXAMPLES_INSTALL_DIR ${SHARE_INSTALL_DIR}/proton/examples)
 endif (UNIX)
 
-set (JAVA_INSTALL_DIR ${SHARE_INSTALL_DIR}/java CACHE PATH "Installation directory for all JARs except those using JNI")
-set (JNI_INSTALL_DIR ${LIB_INSTALL_DIR}/java CACHE PATH "Installation directory for all JARs utilising JNI")
-set (JNI_SHARED_LIB_INSTALL_DIR ${LIB_INSTALL_DIR} CACHE PATH "Installation directory for shared objects used by JNI JARs")
-
 set (PROTON_SHARE ${SHARE_INSTALL_DIR}/proton-${PN_VERSION})
 # End of variables used during install
 
-set (PROTON_JAR_DEPEND_DIR /usr/share/java/ CACHE PATH
-      "When locating compile-time dependencies, the build system searches this location in addition to the default ones provided by find_jar")
-
 # Pull in local cmake modules
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/tools/cmake/Modules/")
 
-set (java_default ON)
-option(GEN_JAVA "Include java-related artifacts" ${java_default})
-if (GEN_JAVA)
-  find_package( Java )
+if (NOBUILD_JAVA)
+  set (DEFAULT_JAVA OFF)
+else()
+  find_package(Java)
   if (JAVA_FOUND)
-    message(STATUS "Java version: ${Java_VERSION}. javac is at: ${Java_JAVAC_EXECUTABLE}")
-    include(UseJava)
-    include(ProtonUseJava)
-
-    add_subdirectory(proton-j)
+    set (DEFAULT_JAVA ON)
+  else()
+    set (DEFAULT_JAVA OFF)
   endif()
 endif()
 
+option (BUILD_JAVA "Build proton-j." ${DEFAULT_JAVA})
+
+if (BUILD_JAVA)
+  add_subdirectory(proton-j)
+endif()
+
 add_subdirectory(proton-c)
 
 install (FILES LICENSE README TODO
@@ -143,9 +145,10 @@ install (FILES examples/include/pncompat/internal/LICENSE
          DESTINATION ${EXAMPLES_INSTALL_DIR}/messenger/pncompat)
 
 # add relevant CTest support
-find_program (MAVEN_EXECUTABLE mvn DOC "Location of the maven program")
-if (JAVA_FOUND AND MAVEN_EXECUTABLE)
+find_program (MAVEN_EXE mvn DOC "Location of the maven program")
+mark_as_advanced (MAVEN_EXE)
+if (JAVA_FOUND AND MAVEN_EXE)
   add_test (proton-java mvn test --file ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml)
-else (JAVA_FOUND AND MAVEN_EXECUTABLE)
+else (JAVA_FOUND AND MAVEN_EXE)
   message (STATUS "Cannot find both Java and Maven: testing disabled for Proton-J")
-endif (JAVA_FOUND AND MAVEN_EXECUTABLE)
+endif (JAVA_FOUND AND MAVEN_EXE)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/README
----------------------------------------------------------------------
diff --git a/README b/README
index eca7f08..72f824f 100644
--- a/README
+++ b/README
@@ -1,3 +1,6 @@
+Proton Project
+==============
+
 Proton is a library for speaking AMQP, including:
 
   + The AMQP Messenger API, a simple but powerful interface to send and receive
@@ -17,171 +20,204 @@ Proton is designed to scale up and down:
 
 Proton is multi-lingual:
 
-  + Proton-C - a C implementation with lanuage bindings in Python, Php, Perl,
-    Ruby, and Java (via JNI).
+  + Proton-C - a C implementation with language bindings in Python,
+               Php, Perl, and Ruby
   + Proton-J - a pure Java implementation
 
 Please see http://qpid.apache.org/proton for a more info.
 
-==== Build Instructions ====
-
-Proton has two separate build systems reflecting the nature of its
-two implementations.
+Build Instructions
+==================
 
-   + Proton-C and the language bindings use CMake.
-   + Proton-J uses Maven.
+Proton comes with two separate build systems. The CMake build system
+builds the entire codebase including the C implementation, all the
+bindings of the C implementation, and the pure Java implementation.
 
-The two build systems are independent of one and other, that is, Proton-C
-may be built independently of Proton-J, and vice-versa.
+The maven build system builds only the Java portions of the code.
+Developers wishing to work across multiple languages should become
+familiar with the cmake build system as this will build and run all
+available tests and code whereas the maven build system only runs Java
+tests.
 
-=== Proton-C ===
+CMake (Linux)
+-------------
 
-== Build Instructions (Linux) ==
+The following prerequisites are required to do a full build. If you do
+not wish to build a given language binding you can omit the devel
+package for that language:
 
-The following prerequesuites are required to do a full build. If you do not
-wish to build a given language binding you can omit the package for that
-language:
+    # required dependencies
+    yum install gcc cmake libuuid-devel
 
-  # required dependencies
-  yum install gcc cmake libuuid-devel
+    # dependencies needed for ssl support
+    yum install openssl-devel
 
-  # dependencies needed for ssl support
-  yum install openssl-devel
+    # dependencies needed for bindings
+    yum install swig python-devel ruby-devel php-devel perl-devel
 
-  # dependencies needed for bindings
-  yum install swig python-devel ruby-devel php-devel perl-devel \
-              java-1.6.0-openjdk
+    # dependencies needed for java (note that any non-ancient jvm will
+    # work, 1.8.0 is just what is current for fedora 20)
+    yum install java-1.8.0-openjdk-devel
 
-  # dependencies needed for python docs
-  yum install epydoc
+    # dependencies needed for python docs
+    yum install epydoc
 
 From the directory where you found this README file:
 
-  mkdir build
-  cd build
-
-  # Set the install prefix. You may need to adjust depending on your
-  # system.
-  cmake -DCMAKE_INSTALL_PREFIX=/usr ..
+    mkdir build
+    cd build
 
-  # Omit the docs target if you do not wish to build or install
-  # documentation.
-  make all docs
+    # Set the install prefix. You may need to adjust depending on your
+    # system.
+    cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DSYSINSTALL_BINDINGS=ON
 
-  # Note that this step will require root privileges.
-  make install
+    # Omit the docs target if you do not wish to build or install
+    # documentation.
+    make all docs
 
-Note that all installed files are stored in the install_manifest.txt
-file.
+    # Note that this step will require root privileges.
+    make install
 
-NOTE: The CMAKE_INSTALL_PREFIX does not affect the location for where the language
-bindings (Ruby, Perl, PHP, Ruby) are installed. For those elements, the location is
-determined by the language itself; i.e., each one is interrogated for the proper
-location for extensions.
+When make install completes, all installed files are listed in the
+install_manifest.txt file. The contents of this file may be used to
+uninstall.
 
-NOTE: If you want to constrain where the Proton code is installed, you have to use
-the DESTDIR argument to make:
+Note: When SYSINSTALL_BINDINGS is enabled (ON), the
+CMAKE_INSTALL_PREFIX does not affect the location for where the
+language bindings (Python, Perl, PHP, Ruby) are installed. For those
+elements, the location is determined by the language interpreter
+itself; i.e., each interpreter is queried for the proper location for
+extensions. If you want to constrain where the Proton code is
+installed, set SYSINSTALL_BINDINGS to OFF. This will install all
+bindings to a common location under ${CMAKE_INSTALL_PREFIX}. When
+installed like this, each user will need to manually configure their
+interpreters with the respective binding location.
 
-  make install DESTDIR=[location]
+Installing Language Bindings
+----------------------------
 
-This will install all components (including the language bindings) in locations
-relative to the specified location. So, for example, if the Perl language bindings
-would normally install to /usr/lib/perl5/vendor_perl/ then, if you use:
+Most dynamic languages provide a way for asking where to install
+libraries in order to place them in a default search path.
 
-  make install DESTDIR=/opt
+When SYSINSTALL_BINDINGS is disabled (OFF), Proton installs all
+dynamic language bindings into a central, default location:
 
-the bindings would install to /opt/usr/lib/perl5/vendor_perl/ instead.
+    BINDINGS=${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/proton/bindings
 
-NOTE: The paths in libqpid-proton.pc are not updated if, when installing, DESTDIR
-is used. The contents of that file are based on the values provided when the
-CMake environment was created.
+In order to use these bindings, you'll need to configure your
+interpreter to load the bindings from the appropriate directory:
 
-For more on the use of DESTDIR, see the following:
+ * Perl   - Add ${BINDINGS}/perl to PERL5LIB
+ * PHP    - Set the PHPRC environment variable to point to
+            ${BINDINGS}/php/proton.ini
+ * Python - Add ${BINDINGS}/python to PYTHONPATH
+ * Ruby   - Add ${BINDINGS}/ruby to RUBYLIB
 
-http://www.gnu.org/prep/standards/html_node/DESTDIR.html
+You can configure the build to install a specific binding to the
+location specified by the system interpreter with the
+SYSINSTALL_[LANGUAGE] options, where [LANGUAGE] is one of JAVA, PERL,
+PHP, PYTHON, or RUBY.:
 
-== Disable Building The Language Bindings ==
+    cmake .. -DSYSINSTALL_PHP=ON
 
-To disable any language bindings, you can disable them individually with:
+Disabling Language Bindings
+---------------------------
 
-  cmake -DBUILD_[LANGUAGE]=OFF .
+To disable any given language bindings, you can use the
+BUILD_[LANGUAGE] option where [LANGUAGE] is one of JAVA, PERL, PHP,
+PYTHON or RUBY, e.g.:
 
-where [LANGUAGE] is one of JAVA, PERL, PHP, PYTHON or RUBY. To disable building all
-language bindings then include a separate argument for each.
+    cmake .. -DBUILD_PHP=OFF
 
-== Build Instructions (Windows) ==
+CMake (Windows)
+---------------
 
-This describes how to build the Proton library on Windows using Microsoft
-Visual C++.
+This describes how to build the Proton library on Windows using
+Microsoft Visual C++.
 
-The Proton build uses the cmake tool to generate the Visual Studio project
-files.  These project files can then be loaded into Visual Studio and used to
-build the Proton library.
+The Proton build uses the cmake tool to generate the Visual Studio
+project files. These project files can then be loaded into Visual
+Studio and used to build the Proton library.
 
-These instructions assume use of a command shell.  If you use the Visual
-Studio supplied Command Prompt, cmake is even more likely to guess the
-intended compiler.
+These instructions assume use of a command shell. If you use the
+Visual Studio supplied Command Prompt, cmake is even more likely to
+guess the intended compiler.
 
 The following packages must be installed:
 
-    Visual Studio 2005 or newer (regular or C++ Express)
-    Python (www.python.org)
-    Cmake (www.cmake.org)
+  - Visual Studio 2005 or newer (regular or C++ Express)
+  - Python (www.python.org)
+  - Cmake (www.cmake.org)
+
+The following packages are optionally required in order to run the
+python or java driven test suites:
+
+  - swig (www.swig.org)
 
-Optional: to run the python or java driven test suites
+Notes:
 
-    swig (www.swig.org)
+  - be sure to install relevant Microsoft Service Packs and updates
+  - python.exe _must_ be in your path
+  - cmake.exe _must_ be in your path
+  - swig.exe optional (but should be in your path for building test
+    modules)
 
-    Notes:
-        - Be sure to install relevant Microsoft Service Packs and updates
-        - python.exe _must_ be in your path
-        - cmake.exe _must_ be in your path
-        - swig.exe optional (but should be in your path for building test modules)
+### Step 1:
 
+Create a 'build' directory - this must be at the same level as the
+'proton-c' directory. For example, from the directory where you found
+this README file:
 
-Step 1: Create a 'build' directory - this must be at the same level as the
-        'proton-c' directory.  Example:
+    > mkdir build
 
-     From the directory where you found this README file:
-     > mkdir build
+### Step 2:
 
-Step 2: cd into the build directory
+  cd into the build directory
 
-     > cd build
+    > cd build
 
-Step 3: Generate the Visual Studio project files using cmake.  The command contains
+### Step 3:
 
-        1) the name of the compiler you are using (if cmake guesses wrongly)
-        2) the path (required) to the _directory_ that contains the top level
-           "CMakeLists.txt" file (the parent directory, in this case).
-     Example:
+Generate the Visual Studio project files using cmake. The command
+contains:
 
-     > cmake ..
+  1. the name of the compiler you are using (if cmake guesses wrongly)
+  2. the path (required) to the _directory_ that contains the top
+     level "CMakeLists.txt" file (the parent directory, in this case).
 
-     If cmake doesn't guess things correctly, useful additional arguments are:
+  Example:
 
-        -G "Visual Studio 10"
-        -DSWIG_EXECUTABLE=C:\swigwin-2.0.7\swig.exe
+    > cmake ..
 
-     Refer to the cmake documentation for more information.
+  If cmake doesn't guess things correctly, useful additional arguments
+  are:
 
-Step 4: Load the ALL_BUILD project into Visual Studio
+    -G "Visual Studio 10"
+    -DSWIG_EXECUTABLE=C:\swigwin-2.0.7\swig.exe
 
-     4a: Run the Microsoft Visual Studio IDE
-     4b: From within the IDE, open the ALL_BUILD project file or proton solution
-         file - it should be in the 'build' directory you created above.
-     4c: select the appropriate configuration.  RelWithDebInfo works best with
-         the included CMake/CTest scripts
+  Refer to the cmake documentation for more information.
 
-Step 5: Build the ALL_BUILD project.
+### Step 4:
 
-Note that if you wish to build debug version of proton for use with swig
-bindings on Windows, you must have the appropriate debug target libraries to
-link against.
+Load the ALL_BUILD project into Visual Studio
 
-=== Proton-J ===
+  a. Run the Microsoft Visual Studio IDE
+  b. From within the IDE, open the ALL_BUILD project file or proton
+     solution file - it should be in the 'build' directory you created
+     above.
+  c. select the appropriate configuration. RelWithDebInfo works best
+     with the included CMake/CTest scripts
 
-== Build Instructions (All platforms) ==
+### Step 5:
+
+Build the ALL_BUILD project.
+
+Note that if you wish to build debug version of proton for use with
+swig bindings on Windows, you must have the appropriate debug target
+libraries to link against.
+
+Maven (All platforms)
+---------------------
 
 The following prerequesuites are required to do a full build.
 
@@ -189,42 +225,35 @@ The following prerequesuites are required to do a full build.
 
 From the directory where you found this README file:
 
-  # To compile and package all Java modules (omitting the tests)
-  mvn -DskipTests package
-
-  # To install the packages in the local Maven repository (usually ~/.m2/repo)
-  mvn -DskipTests install
-
-=== Testing ===
+    # To compile and package all Java modules (omitting the tests)
+    mvn -DskipTests package
 
-To test Proton, run the system tests (located in the tests subdirectory).
-The system tests are applicable to both the Proton-C and Proton-J
-implementations.
+    # To install the packages in the local Maven repository (usually ~/.m2/repo)
+    mvn -DskipTests install
 
-== Test Instructions (Proton-C only) ==
+Testing
+=======
 
-To run the system tests against Proton-C, from your build directory above:
+Additional packages required for testing:
 
-   # to run all the tests, summary mode
-   ctest
+    yum install rubygem-minitest rubygem-rspec rubygem-simplecov
 
-   # to run a single test, full output
-   ctest -V -R proton-c
+On non-RPM based systems, you can install them using:
 
-== Test Instructions (Proton-J and Proton-C) ==
+    gem install minitest rspec simplecov
 
-To run the system tests, execute Maven specifying profile 'proton-j' to
-test Proton-J, and 'proton-jni' to test the Proton-C implementation via the
-JNI bindings.  (To test Proton-C via the JNI Bindings the JNI Binding must have
-been built with Cmake as described above).
+To test Proton, use the cmake build and run 'make test'. Note that
+this will invoke the maven tests as well, so the maven prerequisites
+are required in addition to the cmake prerequisites.
 
-  # To test Proton-J
-  mvn test -P proton-j
+Running Tests
+-------------
 
-  # To test Proton-C via the JNI Bindings
-  mvn test -P proton-jni
+To run the system tests using the CMake build system, cd into your
+build directory and use the following commands:
 
-  # To produce a nicely formated report containing the test results
-  # (in tests/target/site/surefire-report.html)
-  mvn surefire-report:report
+    # to run all the tests, summary mode
+    ctest
 
+    # to run a single test, full output
+    ctest -V -R proton-c

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
new file mode 100644
index 0000000..4f7f948
--- /dev/null
+++ b/examples/CMakeLists.txt
@@ -0,0 +1,22 @@
+#
+# 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.
+#
+
+set (Proton_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+
+add_subdirectory(messenger/c)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/examples/ProtonConfig.cmake
----------------------------------------------------------------------
diff --git a/examples/ProtonConfig.cmake b/examples/ProtonConfig.cmake
new file mode 100644
index 0000000..0269c77
--- /dev/null
+++ b/examples/ProtonConfig.cmake
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+
+set (Proton_VERSION       ${PN_VERSION})
+set (Proton_INCLUDE_DIRS  ${CMAKE_SOURCE_DIR}/proton-c/include)
+set (Proton_LIBRARIES     qpid-proton)
+set (Proton_FOUND True)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/examples/include/pncompat/misc_funcs.inc
----------------------------------------------------------------------
diff --git a/examples/include/pncompat/misc_funcs.inc b/examples/include/pncompat/misc_funcs.inc
index 921d1d3..166cc97 100644
--- a/examples/include/pncompat/misc_funcs.inc
+++ b/examples/include/pncompat/misc_funcs.inc
@@ -47,8 +47,8 @@
 pn_timestamp_t time_now(void)
 {
   FILETIME now;
-  GetSystemTimeAsFileTime(&now);
   ULARGE_INTEGER t;
+  GetSystemTimeAsFileTime(&now);
   t.u.HighPart = now.dwHighDateTime;
   t.u.LowPart = now.dwLowDateTime;
   // Convert to milliseconds and adjust base epoch

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/examples/messenger/c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/messenger/c/CMakeLists.txt b/examples/messenger/c/CMakeLists.txt
index 5d03c79..4f40924 100644
--- a/examples/messenger/c/CMakeLists.txt
+++ b/examples/messenger/c/CMakeLists.txt
@@ -17,28 +17,12 @@
 # under the License.
 #
 
-cmake_minimum_required (VERSION 2.6)
-
-find_path(PROTON_INCLUDE_DIR proton/types.h)
-find_library(PROTON_LIBRARY
-             NAMES qpid-proton)
+find_package(Proton REQUIRED)
 
 add_executable(recv recv.c)
 add_executable(send send.c)
-add_executable(recv-async recv-async.c)
-add_executable(send-async send-async.c)
-
-target_link_libraries(recv qpid-proton)
-target_link_libraries(send qpid-proton)
-target_link_libraries(recv-async qpid-proton)
-target_link_libraries(send-async qpid-proton)
 
-set_target_properties (
-  recv send recv-async send-async
-  PROPERTIES
-  COMPILE_FLAGS "${COMPILE_WARNING_FLAGS} ${COMPILE_LANGUAGE_FLAGS}"
-)
+include_directories(${Proton_INCLUDE_DIRS})
 
-if (BUILD_WITH_CXX)
-  set_source_files_properties (recv.c send.c recv-async.c send-async.c PROPERTIES LANGUAGE CXX)
-endif (BUILD_WITH_CXX)
+target_link_libraries(recv ${Proton_LIBRARIES})
+target_link_libraries(send ${Proton_LIBRARIES})

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/examples/messenger/c/recv.c
----------------------------------------------------------------------
diff --git a/examples/messenger/c/recv.c b/examples/messenger/c/recv.c
index f3d84c2..16e8321 100644
--- a/examples/messenger/c/recv.c
+++ b/examples/messenger/c/recv.c
@@ -57,6 +57,13 @@ int main(int argc, char** argv)
   char* password = NULL;
   char* address = (char *) "amqp://~0.0.0.0";
   int c;
+
+  pn_message_t * message;
+  pn_messenger_t * messenger;
+
+  message = pn_message();
+  messenger = pn_messenger(NULL);
+
   opterr = 0;
 
   while((c = getopt(argc, argv, "hc:k:p:")) != -1)
@@ -97,12 +104,6 @@ int main(int argc, char** argv)
     address = argv[optind];
   }
 
-  pn_message_t * message;
-  pn_messenger_t * messenger;
-
-  message = pn_message();
-  messenger = pn_messenger(NULL);
-
   /* load the various command line options if they're set */
   if(certificate)
   {
@@ -135,15 +136,17 @@ int main(int argc, char** argv)
       pn_messenger_get(messenger, message);
       check(messenger);
 
+      {
       char buffer[1024];
       size_t buffsize = sizeof(buffer);
+      const char* subject = pn_message_get_subject(message);
       pn_data_t *body = pn_message_body(message);
       pn_data_format(body, buffer, &buffsize);
 
       printf("Address: %s\n", pn_message_get_address(message));
-      const char* subject = pn_message_get_subject(message);
       printf("Subject: %s\n", subject ? subject : "(no subject)");
       printf("Content: %s\n", buffer);
+      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/examples/messenger/c/send.c
----------------------------------------------------------------------
diff --git a/examples/messenger/c/send.c b/examples/messenger/c/send.c
index d8460bc..11b47ff 100644
--- a/examples/messenger/c/send.c
+++ b/examples/messenger/c/send.c
@@ -52,9 +52,9 @@ void usage(void)
 int main(int argc, char** argv)
 {
   int c;
-  opterr = 0;
   char * address = (char *) "amqp://0.0.0.0";
   char * msgtext = (char *) "Hello World!";
+  opterr = 0;
 
   while((c = getopt(argc, argv, "ha:b:c:")) != -1)
   {
@@ -84,8 +84,10 @@ int main(int argc, char** argv)
 
   if (optind < argc) msgtext = argv[optind];
 
+  {
   pn_message_t * message;
   pn_messenger_t * messenger;
+  pn_data_t * body;
 
   message = pn_message();
   messenger = pn_messenger(NULL);
@@ -93,7 +95,7 @@ int main(int argc, char** argv)
   pn_messenger_start(messenger);
 
   pn_message_set_address(message, address);
-  pn_data_t *body = pn_message_body(message);
+  body = pn_message_body(message);
   pn_data_put_string(body, pn_bytes(strlen(msgtext), msgtext));
   pn_messenger_put(messenger, message);
   check(messenger);
@@ -103,6 +105,7 @@ int main(int argc, char** argv)
   pn_messenger_stop(messenger);
   pn_messenger_free(messenger);
   pn_message_free(message);
+  }
 
   return 0;
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/examples/messenger/ruby/passive_recv.rb
----------------------------------------------------------------------
diff --git a/examples/messenger/ruby/passive_recv.rb b/examples/messenger/ruby/passive_recv.rb
new file mode 100644
index 0000000..a3625ac
--- /dev/null
+++ b/examples/messenger/ruby/passive_recv.rb
@@ -0,0 +1,140 @@
+#!/usr/bin/env ruby
+#
+# 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.
+
+require 'qpid_proton'
+require 'optparse'
+
+addresses = []
+
+OptionParser.new do |opts|
+  opts.banner = "Usage: recv.rb <addr1> ... <addrn>"
+  opts.parse!
+
+  addresses = ARGV
+end
+
+addresses = ["~0.0.0.0"] if addresses.empty?
+
+messenger = Qpid::Proton::Messenger.new
+messenger.passive = true
+
+begin
+  messenger.start
+rescue ProtonError => error
+  puts "ERROR: #{error.message}"
+  puts error.backtrace.join("\n")
+  exit
+end
+
+addresses.each do |address|
+  begin
+    messenger.subscribe(address)
+  rescue Qpid::Proton::ProtonError => error
+    puts "ERROR: #{error.message}"
+    exit
+  end
+end
+
+msg = Qpid::Proton::Message.new
+
+read_array = []
+write_array = []
+selectables = {}
+
+loop do
+
+  # wait for incoming messages
+  sel = messenger.selectable
+  while !sel.nil?
+    if sel.terminal?
+      selectables.delete(sel.fileno)
+      read_array.delete(sel)
+      write_array.delete(sel)
+      sel.free
+    else
+      sel.capacity
+      sel.pending
+      if !sel.registered?
+        read_array << sel
+        write_array << sel
+        selectables[sel.fileno] = sel
+        sel.registered = true
+      end
+    end
+    sel = messenger.selectable
+  end
+
+  unless selectables.empty?
+    rarray = []; read_array.each {|fd| rarray << fd.to_io }
+    warray = []; write_array.each {|fd| warray << fd.to_io }
+
+    if messenger.deadline > 0.0
+      result = IO.select(rarray, warray, nil, messenger.deadline)
+    else
+      result = IO.select(rarray, warray)
+    end
+
+    unless result.nil? && result.empty?
+      result.flatten.each do |io|
+        sel = selectables[io.fileno]
+
+        sel.writable if sel.pending > 0
+        sel.readable if sel.capacity > 0
+      end
+    end
+
+    begin
+      messenger.receive(10)
+    rescue Qpid::Proton::ProtonError => error
+      puts "ERROR: #{error.message}"
+      exit
+    end
+
+    while messenger.incoming.nonzero?
+      begin
+        messenger.get(msg)
+      rescue Qpid::Proton::Error => error
+        puts "ERROR: #{error.message}"
+        exit
+      end
+
+      puts "Address: #{msg.address}"
+      subject = msg.subject || "(no subject)"
+      puts "Subject: #{subject}"
+      puts "Body: #{msg.body}"
+      puts "Properties: #{msg.properties}"
+      puts "Instructions: #{msg.instructions}"
+      puts "Annotations: #{msg.annotations}"
+
+      if msg.reply_to
+        puts "=== Sending a reply to #{msg.reply_to}"
+        reply = Qpid::Proton::Message.new
+        reply.address = msg.reply_to
+        reply.subject = "RE: #{msg.subject}"
+        reply.content = "Thanks for the message!"
+
+        messenger.put(reply)
+        messenger.send
+      end
+    end
+  end
+end
+
+messenger.stop
+

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt
index f70e9c4..76b082b 100644
--- a/proton-c/CMakeLists.txt
+++ b/proton-c/CMakeLists.txt
@@ -51,6 +51,7 @@ if (OPENSSL_FOUND)
   set(ssl_impl openssl)
 endif(OPENSSL_FOUND)
 set(SSL_IMPL ${ssl_impl} CACHE STRING "Library to use for SSL/TLS support. Valid values: 'none','openssl'")
+mark_as_advanced (SSL_IMPL)
 
 configure_file (
   "${CMAKE_CURRENT_SOURCE_DIR}/include/proton/version.h.in"
@@ -222,6 +223,17 @@ if (MSVC)
 	set(CMAKE_DEBUG_POSTFIX "d")
 endif (MSVC)
 
+macro (pn_absolute_install_dir NAME VALUE PREFIX)
+  if(IS_ABSOLUTE ${VALUE})
+    set(${NAME} "${VALUE}")
+  elseif(IS_ABSOLUTE ${PREFIX})
+    set(${NAME} "${PREFIX}/${VALUE}")
+  else()
+    set(${NAME} "${CMAKE_BINARY_DIR}/${PREFIX}/${VALUE}")
+  endif(IS_ABSOLUTE ${VALUE})
+  get_filename_component(${NAME} ${${NAME}} ABSOLUTE)
+endmacro()
+
 find_package(SWIG)
 if (SWIG_FOUND)
   add_subdirectory(bindings)
@@ -242,7 +254,6 @@ endif (BUILD_JAVASCRIPT)
 
 add_subdirectory(docs/api)
 add_subdirectory(docs/man)
-add_subdirectory(../examples/messenger/c examples/messenger/c)
 add_subdirectory(../tests/tools/apps/c ../tests/tools/apps/c)
 
 set (qpid-proton-platform
@@ -349,12 +360,12 @@ pn_c_files (${qpid-proton-core} ${qpid-proton-platform} src/proton.c src/proton-
 # Install executables and libraries
 install (TARGETS proton proton-dump
   RUNTIME DESTINATION bin
-  ARCHIVE DESTINATION bin
+  ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
   LIBRARY DESTINATION ${LIB_INSTALL_DIR})
 install (TARGETS qpid-proton
   EXPORT  proton
   RUNTIME DESTINATION bin
-  ARCHIVE DESTINATION bin
+  ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
   LIBRARY DESTINATION ${LIB_INSTALL_DIR})
 
 # Install header files
@@ -363,24 +374,12 @@ install (FILES ${headers} DESTINATION ${INCLUDE_INSTALL_DIR}/proton)
 install (FILES  ${CMAKE_CURRENT_BINARY_DIR}/include/proton/version.h
          DESTINATION ${INCLUDE_INSTALL_DIR}/proton)
 
-# Pkg config file
-# make sure the install prefix is absolute
-set(INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
-
-macro (pn_pkgconfig_dir NAME VALUE PREFIX)
-  if(IS_ABSOLUTE ${VALUE})
-    set(${NAME} "${VALUE}")
-  else(IS_ABSOLUTE ${VALUE})
-    set(${NAME} "${PREFIX}/${VALUE}")
-  endif(IS_ABSOLUTE ${VALUE})
-  get_filename_component(${NAME} ${${NAME}} ABSOLUTE)
-endmacro(pn_pkgconfig_dir)
-
-pn_pkgconfig_dir(PREFIX ${INSTALL_PREFIX} ${INSTALL_PREFIX})
-pn_pkgconfig_dir(EXEC_PREFIX ${INSTALL_PREFIX} ${INSTALL_PREFIX})
-pn_pkgconfig_dir(LIBDIR ${LIB_INSTALL_DIR} ${INSTALL_PREFIX})
-pn_pkgconfig_dir(INCLUDEDIR ${INCLUDE_INSTALL_DIR} ${INSTALL_PREFIX})
+pn_absolute_install_dir(PREFIX "." ${CMAKE_INSTALL_PREFIX})
+pn_absolute_install_dir(EXEC_PREFIX "." ${CMAKE_INSTALL_PREFIX})
+pn_absolute_install_dir(LIBDIR ${LIB_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX})
+pn_absolute_install_dir(INCLUDEDIR ${INCLUDE_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX})
 
+# Pkg config file
 configure_file(
   ${CMAKE_CURRENT_SOURCE_DIR}/src/libqpid-proton.pc.in
   ${CMAKE_CURRENT_BINARY_DIR}/libqpid-proton.pc @ONLY)
@@ -388,23 +387,24 @@ install (FILES
   ${CMAKE_CURRENT_BINARY_DIR}/libqpid-proton.pc
   DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
 
-configure_file(
-  ${CMAKE_CURRENT_SOURCE_DIR}/src/libqpid-proton.cmake.in
-  ${CMAKE_CURRENT_BINARY_DIR}/libqpid-proton.cmake @ONLY)
-install (FILES 
-  ${CMAKE_CURRENT_BINARY_DIR}/libqpid-proton.cmake
-  DESTINATION ${LIB_INSTALL_DIR}/proton.cmake)
-
-install (EXPORT proton 
-  FILE proton-config.cmake 
-  DESTINATION ${LIB_INSTALL_DIR}/proton.cmake)
+if (DEFINED CMAKE_IMPORT_LIBRARY_PREFIX)
+set(PROTONLIB ${CMAKE_IMPORT_LIBRARY_PREFIX}qpid-proton${CMAKE_IMPORT_LIBRARY_SUFFIX})
+set(PROTONLIBDEBUG ${CMAKE_IMPORT_LIBRARY_PREFIX}qpid-proton${CMAKE_DEBUG_POSTFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX})
+else ()
+set(PROTONLIB ${CMAKE_SHARED_LIBRARY_PREFIX}qpid-proton${CMAKE_SHARED_LIBRARY_SUFFIX})
+set(PROTONLIBDEBUG ${CMAKE_SHARED_LIBRARY_PREFIX}qpid-proton${CMAKE_DEBUG_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX})
+endif ()
 
-file(WRITE 
-  ${CMAKE_CURRENT_BINARY_DIR}/proton.cmake/proton-config-version.cmake
-  "set(PACKAGE_VERSION ${PN_VERSION})\n")
-install (FILES 
-  ${CMAKE_CURRENT_BINARY_DIR}/proton.cmake/proton-config-version.cmake
-  DESTINATION ${LIB_INSTALL_DIR}/proton.cmake)
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/src/ProtonConfig.cmake.in
+  ${CMAKE_CURRENT_BINARY_DIR}/ProtonConfig.cmake @ONLY)
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/src/ProtonConfigVersion.cmake.in
+  ${CMAKE_CURRENT_BINARY_DIR}/ProtonConfigVersion.cmake @ONLY)
+install (FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/ProtonConfig.cmake
+  ${CMAKE_CURRENT_BINARY_DIR}/ProtonConfigVersion.cmake
+  DESTINATION ${LIB_INSTALL_DIR}/cmake/Proton)
 
 # CTest
 
@@ -441,16 +441,18 @@ endif (CMAKE_SYSTEM_NAME STREQUAL Windows)
 
 set (env_py "${CMAKE_CURRENT_SOURCE_DIR}/env.py" )
 
-find_program(VALGRIND valgrind DOC "Location of the valgrind program")
+find_program(VALGRIND_EXE valgrind DOC "Location of the valgrind program")
 option(ENABLE_VALGRIND "Use valgrind to detect run-time problems" ON)
 if (ENABLE_VALGRIND)
-  if (VALGRIND STREQUAL VALGRIND-NOTFOUND)
+  if (NOT VALGRIND_EXE)
     message(STATUS "Can't locate the valgrind command; no run-time error detection")
-  else (VALGRIND STREQUAL VALGRIND-NOTFOUND)
-    set (VALGRIND_ENV "VALGRIND=${VALGRIND}")
-  endif (VALGRIND STREQUAL VALGRIND-NOTFOUND)
+  else ()
+    set (VALGRIND_ENV "VALGRIND=${VALGRIND_EXE}")
+  endif ()
 endif (ENABLE_VALGRIND)
 
+mark_as_advanced (VALGRIND_EXE)
+
 # c tests:
 
 add_subdirectory(src/tests)
@@ -472,8 +474,8 @@ add_test (python-test ${PYTHON_EXECUTABLE} ${env_py}
          ${PYTHON_EXECUTABLE} "${py_root}/proton-test")
 set_tests_properties(python-test PROPERTIES PASS_REGULAR_EXPRESSION "Totals: .* 0 failed")
 
-find_program(ruby_exe "ruby")
-if (ruby_exe)
+find_program(RUBY_EXE "ruby")
+if (RUBY_EXE)
   set (rb_root "${pn_test_root}/ruby")
   set (rb_src "${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby")
   set (rb_lib "${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby/lib")
@@ -483,20 +485,30 @@ if (ruby_exe)
   set (rb_rubylib "${rb_root}:${rb_src}:${rb_bin}:${rb_bld}:${rb_lib}")
 
   # ruby unit tests:  tests/ruby/proton-test
-  add_test (ruby-unit-test ${PYTHON_EXECUTABLE} ${env_py} "PATH=${rb_path}" "RUBYLIB=${rb_rubylib}"
-    "${rb_root}/proton-test")
-
-  # ruby spec tests
-  find_program(rspec_exe rspec)
-  if (rspec_exe)
-    add_test (NAME ruby-spec-test
-              WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby
-              COMMAND ${PYTHON_EXECUTABLE} ${env_py} "PATH=${rb_path}" "RUBYLIB=${rb_rubylib}"
-                      ${rspec_exe})
-
-  else(rspec_exe)
-    message (STATUS "Cannot find rspec, skipping rspec tests")
-  endif(rspec_exe)
-else (ruby_exe)
+  # only enable the tests if the Ruby gem dependencies were found
+  if (DEFAULT_RUBY_TESTING)
+    add_test (ruby-unit-test ${PYTHON_EXECUTABLE} ${env_py} "PATH=${rb_path}" "RUBYLIB=${rb_rubylib}"
+      "${rb_root}/proton-test")
+
+    # ruby spec tests
+    find_program(RSPEC_EXE rspec)
+    if (RSPEC_EXE)
+      add_test (NAME ruby-spec-test
+                WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby
+                COMMAND ${PYTHON_EXECUTABLE} ${env_py} "PATH=${rb_path}" "RUBYLIB=${rb_rubylib}"
+                        ${RSPEC_EXE})
+
+    else(RSPEC_EXE)
+      message (STATUS "Cannot find rspec, skipping rspec tests")
+    endif(RSPEC_EXE)
+  else (DEFAULT_RUBY_TESTING)
+    message(STATUS "Skipping Ruby tests: missing dependencies")
+  endif (DEFAULT_RUBY_TESTING)
+else (RUBY_EXE)
   message (STATUS "Cannot find ruby, skipping ruby tests")
-endif (ruby_exe)
+endif (RUBY_EXE)
+
+mark_as_advanced (RUBY_EXE RSPEC_EXE)
+
+# build examples to make sure they still work
+add_subdirectory(../examples ../examples)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/CMakeLists.txt b/proton-c/bindings/CMakeLists.txt
index 56bbd71..70cc552 100644
--- a/proton-c/bindings/CMakeLists.txt
+++ b/proton-c/bindings/CMakeLists.txt
@@ -36,9 +36,34 @@ if (PYTHONLIBS_FOUND)
 endif (PYTHONLIBS_FOUND)
 
 # Prerequisites for Ruby:
+find_program(GEM_EXE "gem")
+macro(CheckRubyGem varname gemname)
+  execute_process(COMMAND ${GEM_EXE} list --local ${gemname}
+    OUTPUT_VARIABLE CHECK_OUTPUT)
+
+  set (${varname} OFF)
+
+  if (CHECK_OUTPUT MATCHES "${gemname}[ ]+\(.*\)")
+    message(STATUS "Found Ruby gem: ${gemname}")
+    set (${varname} ON)
+  else()
+    message(STATUS "Missing Ruby gem dependency: ${gemname}")
+    set (${varname} OFF)
+  endif()
+endmacro()
+
 find_package(Ruby)
 if (RUBY_FOUND)
   set (DEFAULT_RUBY ON)
+
+  CheckRubyGem("HAS_RUBY_GEM_RSPEC"     "rspec")
+  CheckRubyGem("HAS_RUBY_GEM_SIMPLECOV" "simplecov")
+
+  if (HAS_RUBY_GEM_RSPEC AND HAS_RUBY_GEM_SIMPLECOV)
+    set (DEFAULT_RUBY_TESTING ON CACHE INTERNAL "")
+  else()
+    set (DEFAULT_RUBY_TESTING OFF CACHE INTERNAL "")
+  endif (HAS_RUBY_GEM_RSPEC AND HAS_RUBY_GEM_SIMPLECOV)
 endif (RUBY_FOUND)
 
 # Prerequites for PHP:
@@ -47,10 +72,12 @@ endif (RUBY_FOUND)
 find_program(PHP_CONFIG_EXE php-config)
 if (PHP_CONFIG_EXE)
   find_program(PHP_EXE php)
+  mark_as_advanced (PHP_EXE)
   if (PHP_EXE)
     set (DEFAULT_PHP ON)
   endif (PHP_EXE)
 endif (PHP_CONFIG_EXE)
+mark_as_advanced (PHP_CONFIG_EXE)
 
 # Prerequisites for Perl:
 include(FindPerl)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/javascript/binding.js
----------------------------------------------------------------------
diff --git a/proton-c/bindings/javascript/binding.js b/proton-c/bindings/javascript/binding.js
index 41020e6..269ee27 100644
--- a/proton-c/bindings/javascript/binding.js
+++ b/proton-c/bindings/javascript/binding.js
@@ -48,7 +48,6 @@ var Module = {
     'noExitRuntime' : true
 };
 
-
 /*****************************************************************************/
 /*                                                                           */
 /*                                   Status                                  */
@@ -116,7 +115,7 @@ Module['Error'] = {
  * @param {string} name the name of this Messenger instance.
  */
 Module['Messenger'] = function(name) { // Messenger Constructor.
-    /*
+    /**
      * The emscripten idiom below is used in a number of places in the JavaScript
      * bindings to map JavaScript Strings to C style strings. ALLOC_STACK will
      * increase the stack and place the item there. When the stack is next restored
@@ -761,8 +760,6 @@ Subscription.prototype['getAddress'] = function() {
 };
 
 
-
-
 /*****************************************************************************/
 /*                                                                           */
 /*                                  Message                                  */
@@ -1406,38 +1403,7 @@ Data.Long.prototype.toString = function() {
     return this.high + ":" + this.getLowBitsUnsigned();
 };
 
-// ---------------------------- proton.Data.Binary ---------------------------- 
-
-/*
-    function freeBuffer() {
-        if (ptr !== 0) {
-            _free(ptr);
-        }
-    };
-
-    // Public methods
-    _public.destroy = function() {
-        freeBuffer();
-    };
-
-    _public.setSize = function(size) {
-        if (size > asize) {
-            freeBuffer();
-            ptr = _malloc(size); // Get output buffer from emscripten.
-            asize = size;
-        }
-        _public.size = size;
-    };
-
-    _public.getRaw = function() {
-        return ptr;
-    };
-
-    _public.getBuffer = function() {
-        // Get a Uint8Array view on the input buffer.
-        return new Uint8Array(HEAPU8.buffer, ptr, _public.size);
-*/
-
+// ---------------------------- proton.Data.Binary ----------------------------
 /**
  * Create a proton.Data.Binary. This constructor takes one or two parameters,
  * size specifies the size in bytes of the Binary buffer, start is a pointer
@@ -1461,11 +1427,16 @@ Data.Long.prototype.toString = function() {
  * {@link proton.Messenger.get} call then the client must explicitly *copy* the
  * bytes into a new buffer via copyBuffer().
  * @constructor proton.Data.Binary
- * @param {number} size the size of the Binary data buffer.
+ * @param {object} data. If data is a number then it represents the size of the
+ *        Binary data buffer, if it is a string then we copy the string to the
+ *        buffer, if it is an Array or a TypedArray then we copy the data to
+ *        the buffer. N.B. although convenient do bear in mind that every method
+ *        other than constructing with a size followed by a call to getBuffer will
+ *        result in some form of additional data copy.
  * @param {number} start an optional data pointer to the start of the Binary data buffer.
  */
-Data['Binary'] = function(size, start) { // Data.Binary Constructor.
-    /*
+Data['Binary'] = function(data, start) { // Data.Binary Constructor.
+    /**
      * If the start pointer is specified then the underlying binary data is owned
      * by another object, so we set the call to free to be a null function. If
      * the start pointer is not passed then we allocate storage of the specified
@@ -1477,10 +1448,30 @@ Data['Binary'] = function(size, start) { // Data.Binary Constructor.
      * turn take responsibility for calling free once it has taken ownership of
      * the underlying binary data.
      */
+    var size = data;
     if (start) {
         this.free = function() {};
-    } else {
-        start = _malloc(size); // Allocate storage from emscripten heap.
+    } else { // Create Binary from Array, ArrayBuffer or TypedArray
+        if (Data.isArray(data) ||
+            (data instanceof ArrayBuffer) || 
+            (data.buffer && data.buffer instanceof ArrayBuffer)) {
+            data = new Uint8Array(data);
+            size = data.length;
+            start = _malloc(size); // Allocate storage from emscripten heap.
+            Module.HEAPU8.set(data, start);
+        } else if (Data.isString(data)) { // Create Binary from native string
+            data = unescape(encodeURIComponent(data)); // Create a C-like UTF representation.
+            size = data.length;
+            start = _malloc(size); // Allocate storage from emscripten heap.
+            for (var i = 0; i < size; i++) {
+                setValue(start + i, data.charCodeAt(i), 'i8', 1);
+            }
+        } else { // Create unpopulated Binary of specified size.
+            // If the type is not a number by this point then an unrecognised data
+            // type has been passed so we create a zero length Binary.
+            size = Data.isNumber(size) ? size : 0;
+            start = _malloc(size); // Allocate storage from emscripten heap.
+        }
         this.free = function() {_free(start);};
     }
 
@@ -1488,7 +1479,7 @@ Data['Binary'] = function(size, start) { // Data.Binary Constructor.
     this.start = start;
 };
 
-/*
+/**
  * Get a Uint8Array view of the data. N.B. this is just a *view* of the data,
  * which will go out of scope on the next call to {@link proton.Messenger.get}. If
  * a client wants to retain the data then copyBuffer should be used to explicitly
@@ -1500,7 +1491,7 @@ Data['Binary'].prototype['getBuffer'] = function() {
     return new Uint8Array(HEAPU8.buffer, this.start, this.size);
 };
 
-/*
+/**
  * Explicitly create a *copy* of the underlying binary data and present a Uint8Array
  * view of that copy. This method should be used if a client application wishes to
  * retain an interest in the binary data for longer than it wishes to retain an
@@ -1921,8 +1912,6 @@ _Data_['putUUID'] = function(u) {
  * @param {proton.Data.Binary} b a binary value.
  */
 _Data_['putBinary'] = function(b) {
-console.log("putBinary");
-
     var sp = Runtime.stackSave();
     // The implementation here is a bit "quirky" due to some low-level details
     // of the interaction between emscripten and LLVM and the use of pn_bytes.
@@ -1933,8 +1922,7 @@ console.log("putBinary");
     // Here's the quirky bit, pn_bytes actually returns pn_bytes_t *by value* but
     // the low-level code handles this *by pointer* so we first need to allocate
     // 8 bytes storage for {size, start} on the emscripten stack and then we
-    // pass the pointer to that storage as the first parameter to the compiled
-    // pn_bytes.
+    // pass the pointer to that storage as the first parameter to the pn_bytes.
     var bytes = allocate(8, 'i8', ALLOC_STACK);
     _pn_bytes(bytes, b.size, b.start);
 
@@ -1965,18 +1953,16 @@ _Data_['putString'] = function(s) {
     // First create an array from the JavaScript String using the intArrayFromString
     // helper function (from emscripten/src/preamble.js). We use this idiom in a
     // few places but here we create array as a separate var as we need its length.
-    var array = intArrayFromString(s);
+    var array = intArrayFromString(s, true); // The true means don't add NULL.
     // Allocate temporary storage for the array on the emscripten stack.
     var str = allocate(array, 'i8', ALLOC_STACK);
 
     // Here's the quirky bit, pn_bytes actually returns pn_bytes_t *by value* but
     // the low-level code handles this *by pointer* so we first need to allocate
     // 8 bytes storage for {size, start} on the emscripten stack and then we
-    // pass the pointer to that storage as the first parameter to the compiled
-    // pn_bytes. The second parameter is the length of the array - 1 because it
-    // is a NULL terminated C style string at this point.
+    // pass the pointer to that storage as the first parameter to the pn_bytes.
     var bytes = allocate(8, 'i8', ALLOC_STACK);
-    _pn_bytes(bytes, array.length - 1, str);
+    _pn_bytes(bytes, array.length, str);
 
     // The compiled pn_data_put_string takes the pn_bytes_t by reference not value.
     this._check(_pn_data_put_string(this._data, bytes));
@@ -2004,53 +1990,22 @@ _Data_['putSymbol'] = function(s) {
     // First create an array from the JavaScript String using the intArrayFromString
     // helper function (from emscripten/src/preamble.js). We use this idiom in a
     // few places but here we create array as a separate var as we need its length.
-    var array = intArrayFromString(s);
+    var array = intArrayFromString(s, true); // The true means don't add NULL.
     // Allocate temporary storage for the array on the emscripten stack.
     var str = allocate(array, 'i8', ALLOC_STACK);
 
     // Here's the quirky bit, pn_bytes actually returns pn_bytes_t *by value* but
     // the low-level code handles this *by pointer* so we first need to allocate
     // 8 bytes storage for {size, start} on the emscripten stack and then we
-    // pass the pointer to that storage as the first parameter to the compiled
-    // pn_bytes. The second parameter is the length of the array - 1 because it
-    // is a NULL terminated C style string at this point.
+    // pass the pointer to that storage as the first parameter to the pn_bytes.
     var bytes = allocate(8, 'i8', ALLOC_STACK);
-    _pn_bytes(bytes, array.length - 1, str);
+    _pn_bytes(bytes, array.length, str);
 
     // The compiled pn_data_put_symbol takes the pn_bytes_t by reference not value.
     this._check(_pn_data_put_symbol(this._data, bytes));
     Runtime.stackRestore(sp);
 };
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 // TODO getArray and isDescribed
 
 /**
@@ -2267,7 +2222,6 @@ _Data_['getUUID'] = function() {
  * @returns {proton.Data.Binary} value if the current node is a Binary, returns null otherwise.
  */
 _Data_['getBinary'] = function() {
-console.log("getBinary");
     var sp = Runtime.stackSave();
     // The implementation here is a bit "quirky" due to some low-level details
     // of the interaction between emscripten and LLVM and the use of pn_bytes.
@@ -2377,8 +2331,6 @@ _Data_['getSymbol'] = function() {
 // TODO copy, format and dump
 
 
-
-
 /**
  * Serialise a Native JavaScript Object into an AMQP Map.
  * @method putDictionary
@@ -2419,7 +2371,6 @@ _Data_['getDictionary'] = function() {
     }
 };
 
-
 /**
  * Serialise a Native JavaScript Array into an AMQP List.
  * @method putJSArray
@@ -2452,14 +2403,6 @@ _Data_['getJSArray'] = function() {
     }
 };
 
-
-
-
-
-
-
-
-
 /**
  * This method is the entry point for serialising native JavaScript types into
  * AMQP types. In an ideal world there would be a nice clean one to one mapping
@@ -2539,7 +2482,6 @@ console.log(obj + " is Float Type");
 };
 _Data_.putObject = _Data_['putObject'];
 
-
 /**
  * @method getObject
  * @memberof! proton.Data#

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/javascript/drain.js
----------------------------------------------------------------------
diff --git a/proton-c/bindings/javascript/drain.js b/proton-c/bindings/javascript/drain.js
index e93ba2e..9d9c726 100644
--- a/proton-c/bindings/javascript/drain.js
+++ b/proton-c/bindings/javascript/drain.js
@@ -48,12 +48,14 @@ console.log("tracker = " + tracker);
     };
 
     //messenger.setIncomingWindow(1024);
-
+console.log("Break A");
     messenger.setNetworkCallback(_process);
     messenger.start();
-
+console.log("Break B");
     messenger.subscribe(address);
+console.log("Break C");
     messenger.recv(); // Receive as many messages as messenger can buffer.
+console.log("Break D");
 } catch(e) {
     console.log("Caught Exception " + e);
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/javascript/spout.js
----------------------------------------------------------------------
diff --git a/proton-c/bindings/javascript/spout.js b/proton-c/bindings/javascript/spout.js
index 7d3cc58..254b948 100644
--- a/proton-c/bindings/javascript/spout.js
+++ b/proton-c/bindings/javascript/spout.js
@@ -70,6 +70,8 @@ console.log("exiting");
     //message.body = msgtext;
     //message.body = new proton.Data.UUID();
     //message.body = new proton.Data.Symbol("My Symbol");
+    //message.body = new proton.Data.Binary("Monkey Bathпогромзхцвбнм");
+
     message.body = new proton.Data.Binary(4);
     var buffer = message.body.getBuffer();
     buffer[0] = 65;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/perl/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/perl/CMakeLists.txt b/proton-c/bindings/perl/CMakeLists.txt
index 158fdc6..365439b 100644
--- a/proton-c/bindings/perl/CMakeLists.txt
+++ b/proton-c/bindings/perl/CMakeLists.txt
@@ -23,28 +23,24 @@ include_directories("${PERL_INCLUDE_PATH}")
 execute_process(COMMAND perl -MConfig -e "print \$Config{ccflags}"
                 OUTPUT_VARIABLE PERLCFLAGS)
 
-if (ASK_PERL)
+if (CHECK_SYSINSTALL_PERL)
+  execute_process(COMMAND perl -V:installvendorarch
+    OUTPUT_VARIABLE PERL_VENDORARCH_OUTPUT_VARIABLE
+    RESULT_VARIABLE PERL_VENDORARCH_RESULT_VARIABLE)
 
-  execute_process(COMMAND perl -V:installvendorlib
-    OUTPUT_VARIABLE PERL_ARCHLIB_OUTPUT_VARIABLE
-    RESULT_VARIABLE PERL_ARCHLIB_RESULT_VARIABLE)
-  if (NOT PERL_ARCHLIB_RESULT_VARIABLE)
-    string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_ARCHLIB ${PERL_ARCHLIB_OUTPUT_VARIABLE})
-    file(TO_CMAKE_PATH "${PERL_ARCHLIB}" PERL_ARCHLIB_DIR)
-  endif (NOT PERL_ARCHLIB_RESULT_VARIABLE)
+  if (NOT PERL_VENDORARCH_RESULT_VARIABLE)
+    string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_VENDORARCH ${PERL_VENDORARCH_OUTPUT_VARIABLE})
+    file(TO_CMAKE_PATH "${PERL_VENDORARCH}" PERL_VENDORARCH_DIR_DEFAULT)
+  else ()
+    set (PERL_VENDORARCH_DIR_DEFAULT ${PERL_VENDORARCH_RESULT_VARIABLE})
+  endif ()
+else (CHECK_SYSINSTALL_PERL)
+  set (PERL_VENDORARCH_DIR_DEFAULT ${BINDINGS_DIR}/perl)
+endif (CHECK_SYSINSTALL_PERL)
 
-  execute_process(COMMAND perl -V:installsitelib
-    OUTPUT_VARIABLE PERL_SITELIB_OUTPUT_VARIABLE
-    RESULT_VARIABLE PERL_SITELIB_RESULT_VARIABLE)
-  if (NOT PERL_SITELIB_RESULT_VARIABLE)
-    string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_SITELIB ${PERL_SITELIB_OUTPUT_VARIABLE})
-    file(TO_CMAKE_PATH "${PERL_SITELIB}" PERL_SITELIB_DIR)
-  endif (NOT PERL_SITELIB_RESULT_VARIABLE)
-
-else (ASK_PERL)
-  set (PERL_ARCHLIB_DIR ${BINDINGS_DIR}/perl/lib${LIB_SUFFIX} CACHE PATH "Perl platform code")
-  set (PERL_SITELIB_DIR ${BINDINGS_DIR}/perl/ CACHE PATH "Perl code")
-endif (ASK_PERL)
+if (NOT PERL_VENDORARCH_DIR)
+  set (PERL_VENDORARCH_DIR ${PERL_VENDORARCH_DIR_DEFAULT})
+endif()
 
 set (CMAKE_C_FLAGS ${PERLCFLAGS})
 
@@ -53,32 +49,25 @@ swig_link_libraries(cproton_perl ${BINDING_DEPS} ${PERL_LIBRARY})
 
 if ((${CMAKE_MAJOR_VERSION} EQUAL 2) AND (${CMAKE_MINOR_VERSION} LESS 8))
   install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cproton_perl.so
-        DESTINATION ${PERL_ARCHLIB_DIR}
-        COMPONENT ${QPID_COMPONENT_CLIENT}
+        DESTINATION ${PERL_VENDORARCH_DIR}
+        COMPONENT Perl
         )
 else()
   install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcproton_perl.so
         RENAME cproton_perl.so
-        DESTINATION ${PERL_ARCHLIB_DIR}
-        COMPONENT ${QPID_COMPONENT_CLIENT}
+        DESTINATION ${PERL_VENDORARCH_DIR}
+        COMPONENT Perl
         )
 endif ((${CMAKE_MAJOR_VERSION} EQUAL 2) AND (${CMAKE_MINOR_VERSION} LESS 8))
 
-# get the perl vendor library if it's not already defined
-#if (NOT PERL_ARCHLIB)
-#  execute_process(COMMAND ${PERL_EXECUTABLE} "-V:installvendorlib"
-#                  OUTPUT_VARIABLE PERL_ARCHLIB_OUTPUT_VARIABLE
-#                  RESULT_VARIABLE PERL_ARCHLIB_RESULT_VARIABLE)
-#endif (!DEFINED PERL_ARCHLIB)
-
 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cproton_perl.pm
-        DESTINATION ${PERL_ARCHLIB_DIR}
+        DESTINATION ${PERL_VENDORARCH_DIR}
         COMPONENT Perl)
 
 install(FILES lib/qpid_proton.pm
-        DESTINATION ${PERL_SITELIB_DIR}
+        DESTINATION ${PERL_VENDORARCH_DIR}
         COMPONENT Perl)
 
 INSTALL(DIRECTORY lib/qpid
-        DESTINATION ${PERL_SITELIB_DIR}
+        DESTINATION ${PERL_VENDORARCH_DIR}
         COMPONENT Perl)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/perl/perl.i
----------------------------------------------------------------------
diff --git a/proton-c/bindings/perl/perl.i b/proton-c/bindings/perl/perl.i
index 914623b..cc6a4d7 100644
--- a/proton-c/bindings/perl/perl.i
+++ b/proton-c/bindings/perl/perl.i
@@ -137,7 +137,9 @@ typedef int int32_t;
 
 %typemap(in) pn_uuid_t
 {
-  AV* tmpav = SvRV($input);
+  // XXX: I believe there is a typemap or something similar for
+  // typechecking the input. We should probably use it.
+  AV* tmpav = (AV *) SvRV($input);
   int index = 0;
 
   for(index = 0; index < 16; index++)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/php/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/php/CMakeLists.txt b/proton-c/bindings/php/CMakeLists.txt
index 9b6ee2c..762e05b 100644
--- a/proton-c/bindings/php/CMakeLists.txt
+++ b/proton-c/bindings/php/CMakeLists.txt
@@ -39,7 +39,7 @@ set_target_properties(cproton
     PREFIX ""
     LINK_FLAGS "${ALLOW_UNDEFINED}")
 
-if (ASK_PHP)
+if (CHECK_SYSINSTALL_PHP)
   execute_process(COMMAND ${PHP_CONFIG_EXE} --extension-dir
     OUTPUT_VARIABLE PHP_EXT_DIR_DEFAULT
     OUTPUT_STRIP_TRAILING_WHITESPACE)
@@ -65,18 +65,36 @@ if (ASK_PHP)
   if ("${PHP_INI_DIR_DEFAULT}" STREQUAL "")
     set(PHP_INI_DIR_DEFAULT "/etc/php.d")
   endif()
+else (CHECK_SYSINSTALL_PHP)
+  set (PHP_EXT_DIR_DEFAULT ${BINDINGS_DIR}/php)
+  set (PHP_INI_DIR_DEFAULT ${BINDINGS_DIR}/php)
+  set (PHP_INCLUDE_DIR_DEFAULT ${BINDINGS_DIR}/php)
+endif (CHECK_SYSINSTALL_PHP)
 
-  set(PHP_EXT_DIR ${PHP_EXT_DIR_DEFAULT} CACHE PATH "PHP extensions directory.")
-  set(PHP_INI_DIR ${PHP_INI_DIR_DEFAULT} CACHE PATH "Directory scanned for PHP ini files.")
-  set(PHP_INCLUDE_DIR ${PHP_INCLUDE_DIR_DEFAULT} CACHE PATH "PHP include directory.")
+# PHP extensions directory
+if (NOT PHP_EXT_DIR)
+  set (PHP_EXT_DIR ${PHP_EXT_DIR_DEFAULT})
+endif()
+# PHP ini directory
+if (NOT PHP_INI_DIR)
+  set (PHP_INI_DIR ${PHP_INI_DIR_DEFAULT})
+endif()
+# PHP include directory
+if (NOT PHP_INCLUDE_DIR)
+  set (PHP_INCLUDE_DIR ${PHP_INCLUDE_DIR_DEFAULT})
+endif()
 
-else (ASK_PHP)
+if (CHECK_SYSINSTALL_PHP)
+  set (PROTON_INI "extension=cproton.so")
+else ()
+  pn_absolute_install_dir(PHP_INCLUDE_PATH ${PHP_INCLUDE_DIR} ${CMAKE_INSTALL_PREFIX})
+  pn_absolute_install_dir(PHP_EXTENSION_LIB ${PHP_EXT_DIR}/cproton.so ${CMAKE_INSTALL_PREFIX})
+  set (PROTON_INI "include_path=${PHP_INCLUDE_PATH}\nextension=${PHP_EXTENSION_LIB}")
+endif()
 
-  set (PHP_EXT_DIR ${BINDINGS_DIR}/php CACHE PATH "PHP extensions directory")
-  set (PHP_INCLUDE_DIR ${BINDINGS_DIR}/php/include CACHE PATH "PHP include directory")
-  set (PHP_INI_DIR ${BINDINGS_DIR}/php/ini CACHE PATH "PHP ini directory")
-
-endif (ASK_PHP)
+configure_file (${CMAKE_CURRENT_SOURCE_DIR}/proton.ini.in
+                ${CMAKE_CURRENT_BINARY_DIR}/proton.ini
+                @ONLY)
 
 install(TARGETS cproton
         DESTINATION ${PHP_EXT_DIR}
@@ -89,7 +107,7 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/proton.php
         COMPONENT PHP)
 
 if (NOT ${PHP_INI_DIR} STREQUAL "")
-  install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cproton.ini
-          DESTINATION ${PHP_INI_DIR}
-          COMPONENT PHP)
+  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/proton.ini
+    DESTINATION ${PHP_INI_DIR}
+    COMPONENT PHP)
 endif ()

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/php/compat.swg
----------------------------------------------------------------------
diff --git a/proton-c/bindings/php/compat.swg b/proton-c/bindings/php/compat.swg
new file mode 100644
index 0000000..d7ffce0
--- /dev/null
+++ b/proton-c/bindings/php/compat.swg
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+%define CONVERT_LONG_LONG_IN(lvar,t,invar)
+  switch ((*(invar))->type) {
+      case IS_DOUBLE:
+          lvar = (t) (*(invar))->value.dval;
+          break;
+      case IS_STRING: {
+          char * endptr;
+          errno = 0;
+          lvar = (t) strtoll((*(invar))->value.str.val, &endptr, 10);
+          if (*endptr && !errno) break;
+          /* FALL THRU */
+      }
+      default:
+          convert_to_long_ex(invar);
+          lvar = (t) (*(invar))->value.lval;
+  }
+%enddef
+
+%pass_by_val(long long, CONVERT_LONG_LONG_IN);
+
+%typemap(out) long long
+%{
+  if ((long long)LONG_MIN <= $1 && $1 <= (long long)LONG_MAX) {
+    return_value->value.lval = (long)($1);
+    return_value->type = IS_LONG;
+  } else {
+    char temp[256];
+    sprintf(temp, "%lld", (long long)$1);
+    ZVAL_STRING(return_value, temp, 1);
+  }
+%}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/php/php.i
----------------------------------------------------------------------
diff --git a/proton-c/bindings/php/php.i b/proton-c/bindings/php/php.i
index b31014d..7cf4f5f 100644
--- a/proton-c/bindings/php/php.i
+++ b/proton-c/bindings/php/php.i
@@ -22,6 +22,9 @@
 // provided by SWIG development libraries
 %include php.swg
 
+#if SWIG_VERSION < 0x020000
+%include compat.swg
+#endif
 
 %header %{
 /* Include the headers needed by the code in this wrapper file */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/php/proton.ini.in
----------------------------------------------------------------------
diff --git a/proton-c/bindings/php/proton.ini.in b/proton-c/bindings/php/proton.ini.in
new file mode 100644
index 0000000..51a774e
--- /dev/null
+++ b/proton-c/bindings/php/proton.ini.in
@@ -0,0 +1,21 @@
+;;
+; 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.
+;;
+
+; Enable cproton extension module
+@PROTON_INI@

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/php/proton.php
----------------------------------------------------------------------
diff --git a/proton-c/bindings/php/proton.php b/proton-c/bindings/php/proton.php
index 30c6675..4c3e4ef 100644
--- a/proton-c/bindings/php/proton.php
+++ b/proton-c/bindings/php/proton.php
@@ -280,7 +280,7 @@ class Message {
     $body = new Data(pn_message_body($this->impl));
 
     if ($inst->next())
-      $this->instructions = $inst.get_object();
+      $this->instructions = $inst->get_object();
     else
       $this->instructions = null;
     if ($ann->next())

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/python/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/CMakeLists.txt b/proton-c/bindings/python/CMakeLists.txt
index b63b6fd..7853e18 100644
--- a/proton-c/bindings/python/CMakeLists.txt
+++ b/proton-c/bindings/python/CMakeLists.txt
@@ -30,19 +30,18 @@ set_target_properties(_cproton
 
 find_package(PythonInterp REQUIRED)
 
-if (ASK_PYTHON)
+if (CHECK_SYSINSTALL_PYTHON)
+  execute_process(COMMAND ${PYTHON_EXECUTABLE}
+    -c "from distutils.sysconfig import get_python_lib; print get_python_lib(True)"
+    OUTPUT_VARIABLE PYTHON_SITEARCH_PACKAGES_DEFAULT
+    OUTPUT_STRIP_TRAILING_WHITESPACE)
+else ()
+  set (PYTHON_SITEARCH_PACKAGES_DEFAULT ${BINDINGS_DIR}/python)
+endif ()
 
-  if (NOT PYTHON_SITEARCH_PACKAGES)
-    execute_process(COMMAND ${PYTHON_EXECUTABLE}
-      -c "from distutils.sysconfig import get_python_lib; print get_python_lib(True)"
-      OUTPUT_VARIABLE PYTHON_ARCHLIB_DIR
-      OUTPUT_STRIP_TRAILING_WHITESPACE)
-  else (NOT PYTHON_SITEARCH_PACKAGES)
-    set (PYTHON_ARCHLIB_DIR "${PYTHON_SITEARCH_PACKAGES}")
-  endif ()
-else (ASK_PYTHON)
-  set (PYTHON_ARCHLIB_DIR ${BINDINGS_DIR}/python/lib${LIB_SUFFIX} CACHE PATH "Python platform code")
-endif (ASK_PYTHON)
+if (NOT PYTHON_SITEARCH_PACKAGES)
+  set (PYTHON_SITEARCH_PACKAGES ${PYTHON_SITEARCH_PACKAGES_DEFAULT})
+endif()
 
 install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m py_compile cproton.py
                               WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")
@@ -54,10 +53,12 @@ install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -O -m py_compile prot
                               WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})")
 
 find_program(EPYDOC_EXE epydoc)
+mark_as_advanced (EPYDOC_EXE)
 if (EPYDOC_EXE)
-   add_custom_target(docs-py COMMAND ${EPYDOC_EXE} -v --no-private --html
-                     -o ${CMAKE_CURRENT_BINARY_DIR}/html
-                     ${CMAKE_CURRENT_SOURCE_DIR}/proton.py)
+   add_custom_target(docs-py COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../env.py --
+     PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_CURRENT_SOURCE_DIR}
+     ${EPYDOC_EXE} -v --no-private --html -o ${CMAKE_CURRENT_BINARY_DIR}/html
+     ${CMAKE_CURRENT_SOURCE_DIR}/proton.py)
    add_dependencies(docs docs-py)
    install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html/"
            DESTINATION "${PROTON_SHARE}/docs/api-py"
@@ -71,8 +72,8 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cproton.py
               ${CMAKE_CURRENT_SOURCE_DIR}/proton.py
               ${CMAKE_CURRENT_SOURCE_DIR}/proton.pyc
               ${CMAKE_CURRENT_SOURCE_DIR}/proton.pyo
-        DESTINATION ${PYTHON_ARCHLIB_DIR}
+        DESTINATION ${PYTHON_SITEARCH_PACKAGES}
         COMPONENT Python)
 install(TARGETS _cproton
-        DESTINATION ${PYTHON_ARCHLIB_DIR}
+        DESTINATION ${PYTHON_SITEARCH_PACKAGES}
         COMPONENT Python)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/python/proton.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton.py b/proton-c/bindings/python/proton.py
index c85a5b2..12da599 100644
--- a/proton-c/bindings/python/proton.py
+++ b/proton-c/bindings/python/proton.py
@@ -3277,6 +3277,7 @@ class Collector:
     else:
       tp = None
     return Event(type=pn_event_type(event),
+                 category=pn_event_category(event),
                  connection=Connection._wrap_connection(pn_event_connection(event)),
                  session=Session._wrap_session(pn_event_session(event)),
                  link=Link._wrap_link(pn_event_link(event)),
@@ -3291,15 +3292,22 @@ class Collector:
 
 class Event:
 
-  CONNECTION_STATE = PN_CONNECTION_STATE
-  SESSION_STATE = PN_SESSION_STATE
-  LINK_STATE = PN_LINK_STATE
+  CATEGORY_PROTOCOL = PN_EVENT_CATEGORY_PROTOCOL
+
+  CONNECTION_LOCAL_STATE = PN_CONNECTION_LOCAL_STATE
+  CONNECTION_REMOTE_STATE = PN_CONNECTION_REMOTE_STATE
+  SESSION_LOCAL_STATE = PN_SESSION_LOCAL_STATE
+  SESSION_REMOTE_STATE = PN_SESSION_REMOTE_STATE
+  LINK_LOCAL_STATE = PN_LINK_LOCAL_STATE
+  LINK_REMOTE_STATE = PN_LINK_REMOTE_STATE
   LINK_FLOW = PN_LINK_FLOW
   DELIVERY = PN_DELIVERY
   TRANSPORT = PN_TRANSPORT
 
-  def __init__(self, type, connection, session, link, delivery, transport):
+  def __init__(self, type, category,
+               connection, session, link, delivery, transport):
     self.type = type
+    self.category = category
     self.connection = connection
     self.session = session
     self.link = link

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/ruby/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/CMakeLists.txt b/proton-c/bindings/ruby/CMakeLists.txt
index 5768907..9336abf 100644
--- a/proton-c/bindings/ruby/CMakeLists.txt
+++ b/proton-c/bindings/ruby/CMakeLists.txt
@@ -17,6 +17,10 @@
 # under the License.
 #
 
+if (NOT DEFAULT_RUBY_TESTING)
+  message(FATAL_ERROR "Ruby bindings cannot be tested while missing dependencies")
+endif (NOT DEFAULT_RUBY_TESTING)
+
 include_directories (${RUBY_INCLUDE_PATH})
 swig_add_module(cproton-ruby ruby ruby.i)
 swig_link_libraries(cproton-ruby ${BINDING_DEPS} ${RUBY_LIBRARY})
@@ -26,8 +30,7 @@ set_target_properties(cproton-ruby
     OUTPUT_NAME "cproton"
     LINK_FLAGS "${CATCH_UNDEFINED}" )
 
-if (ASK_RUBY)
-
+if (CHECK_SYSINSTALL_RUBY)
   execute_process(COMMAND ${RUBY_EXECUTABLE}
     -r rbconfig -e "print RbConfig::CONFIG['vendorarchdir'] || ''"
     RESULT_VARIABLE RESULT_RUBY_ARCHLIB_DIR
@@ -38,18 +41,16 @@ if (ASK_RUBY)
       -r rbconfig -e "print RbConfig::CONFIG['archdir'] || ''"
       RESULT_VARIABLE RESULT_RUBY_ARCHLIB_DIR
       OUTPUT_VARIABLE OUTPUT_RUBY_ARCHLIB_DIR)
-
   endif()
 
-  set(RUBY_ARCHLIB_DIR "${OUTPUT_RUBY_ARCHLIB_DIR}")
-
-else (ASK_RUBY)
-
-  set (RUBY_SITELIB_DIR ${BINDINGS_DIR}/ruby CACHE PATH "Ruby portable code")
-  set (RUBY_ARCHLIB_DIR ${BINDINGS_DIR}/ruby/lib${LIB_SUFFIX} CACHE PATH "Ruby platform code")
-
-endif (ASK_RUBY)
+  set(RUBY_ARCHLIB_DIR_DEFAULT "${OUTPUT_RUBY_ARCHLIB_DIR}")
+else (CHECK_SYSINSTALL_RUBY)
+  set (RUBY_ARCHLIB_DIR_DEFAULT ${BINDINGS_DIR}/ruby)
+endif (CHECK_SYSINSTALL_RUBY)
 
+if (NOT RUBY_ARCHLIB_DIR)
+  set (RUBY_ARCHLIB_DIR ${RUBY_ARCHLIB_DIR_DEFAULT})
+endif()
 
 install(TARGETS cproton-ruby
         DESTINATION ${RUBY_ARCHLIB_DIR}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/ruby/lib/qpid_proton.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton.rb b/proton-c/bindings/ruby/lib/qpid_proton.rb
index 41904b1..cf044f6 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton.rb
@@ -26,11 +26,12 @@ require "qpid_proton/array"
 require "qpid_proton/hash"
 require "qpid_proton/exceptions"
 require "qpid_proton/exception_handling"
+require "qpid_proton/filters"
 require "qpid_proton/message_format"
 require "qpid_proton/data"
 require "qpid_proton/message"
 require "qpid_proton/subscription"
 require "qpid_proton/tracker_status"
 require "qpid_proton/tracker"
+require "qpid_proton/selectable"
 require "qpid_proton/messenger"
-

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/ruby/lib/qpid_proton/filters.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton/filters.rb b/proton-c/bindings/ruby/lib/qpid_proton/filters.rb
new file mode 100644
index 0000000..46c9bf7
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/qpid_proton/filters.rb
@@ -0,0 +1,67 @@
+#
+# 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.
+#
+
+module Qpid
+
+  module Proton
+
+    module Filters
+
+      def self.included(base)
+        base.class_eval do
+          extend ClassMethods
+        end
+      end
+
+      module ClassMethods
+
+        def method_added(method_name)
+          @@hooked_methods ||= []
+          return if @@hooked_methods.include?(method_name)
+          @@hooked_methods << method_name
+          hooks = @@before_hooks[method_name]
+          return if hooks.nil?
+          orig_method = instance_method(method_name)
+          define_method(method_name) do |*args, &block|
+            hooks = @@before_hooks[method_name]
+            hooks.each do |hook|
+              method(hook).call
+            end
+
+            orig_method.bind(self).call(*args, &block)
+          end
+        end
+
+        def call_before(before_method, *methods)
+          @@before_hooks ||= {}
+          methods.each do |method|
+            hooks = @@before_hooks[method] || []
+            raise "Repeat filter: #{before_method}" if hooks.include? before_method
+            hooks << before_method
+            @@before_hooks[method] = hooks
+          end
+        end
+
+      end
+
+    end
+
+  end
+
+end

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/ruby/lib/qpid_proton/messenger.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton/messenger.rb b/proton-c/bindings/ruby/lib/qpid_proton/messenger.rb
index b16c8e7..dfc5717 100644
--- a/proton-c/bindings/ruby/lib/qpid_proton/messenger.rb
+++ b/proton-c/bindings/ruby/lib/qpid_proton/messenger.rb
@@ -36,19 +36,19 @@ module Qpid
     #
     # The Messenger class works in conjuction with the Message class. The
     # Message class is a mutable holder of message content.
-    # 
-    # The put method copies its Message to the outgoing queue, and may 
+    #
+    # The put method copies its Message to the outgoing queue, and may
     # send queued messages if it can do so without blocking.  The send
     # method blocks until it has sent the requested number of messages,
     # or until a timeout interrupts the attempt.
-    # 
+    #
     # Similarly, the recv method receives messages into the incoming
     # queue, and may block as it attempts to receive the requested number
     # of messages,  or until timeout is reached. It may receive fewer
     # than the requested number.  The get method pops the
     # eldest Message off the incoming queue and copies it into the Message
     # object that you supply.  It will not block.
-    # 
+    #
     # The blocking attribute allows you to turn off blocking behavior entirely,
     # in which case send and recv will do whatever they can without
     # blocking, and then return.  You can then look at the number
@@ -70,6 +70,7 @@ module Qpid
       #
       def initialize(name = nil)
         @impl = Cproton.pn_messenger(name)
+        @selectables = {}
         ObjectSpace.define_finalizer(self, self.class.finalize!(@impl))
       end
 
@@ -121,20 +122,45 @@ module Qpid
         Cproton.pn_messenger_get_timeout(@impl)
       end
 
-      # Blocking Attribute
+      # Returns true if blocking mode is enabled.
       #
       # Enable or disable blocking behavior during message sending
       # and receiving.  This affects every blocking call, with the
       # exception of work().  Currently, the affected calls are
       # send, recv, and stop.
-      def blocking
-        Cproton.pn_mesenger_is_blocking(@impl)
+      def blocking?
+        Cproton.pn_messenger_is_blocking(@impl)
       end
 
+      # Sets the blocking mode.
       def blocking=(blocking)
         Cproton.pn_messenger_set_blocking(@impl, blocking)
       end
 
+      # Returns true if passive mode is enabled.
+      #
+      def passive?
+        Cproton.pn_messenger_is_passive(@impl)
+      end
+
+      # Turns passive mode on or off.
+      #
+      # When set to passive mode, Messenger will not attempt to perform I/O
+      # operations internally. In this mode it is necesssary to use the
+      # Selectable type to drive any I/O needed to perform requestioned
+      # actions.
+      #
+      # In this mode Messenger will never block.
+      #
+      def passive=(mode)
+        Cproton.pn_messenger_set_passive(@impl, mode)
+      end
+
+      def deadline
+        tstamp = Cproton.pn_messenger_deadline(@impl)
+        return tstamp / 1000.0 unless tstamp.nil?
+      end
+
       # Reports whether an error occurred.
       #
       def error?
@@ -456,6 +482,22 @@ module Qpid
         check_for_error(Cproton.pn_messenger_rewrite(@impl, pattern, address))
       end
 
+      def selectable
+        impl = Cproton.pn_messenger_selectable(@impl)
+
+        # if we don't have any selectables, then return
+        return nil if impl.nil?
+
+        fd = Cproton.pn_selectable_fd(impl)
+
+        selectable = @selectables[fd]
+        if selectable.nil?
+          selectable = Selectable.new(self, impl)
+          @selectables[fd] = selectable
+        end
+        return selectable
+      end
+
       # Returns a +Tracker+ for the message most recently sent via the put
       # method.
       #
@@ -600,6 +642,11 @@ module Qpid
         Cproton.pn_messenger_get_outgoing_window(@impl)
       end
 
+      # Unregisters a selectable object.
+      def unregister_selectable(fileno) # :nodoc:
+        @selectables.delete(fileno)
+      end
+
       private
 
       def valid_tracker?(tracker)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/33c895ec/proton-c/bindings/ruby/lib/qpid_proton/selectable.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/lib/qpid_proton/selectable.rb b/proton-c/bindings/ruby/lib/qpid_proton/selectable.rb
new file mode 100644
index 0000000..34a030f
--- /dev/null
+++ b/proton-c/bindings/ruby/lib/qpid_proton/selectable.rb
@@ -0,0 +1,126 @@
+#
+# 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.
+#
+
+module Qpid
+
+  module Proton
+
+    # Selectable enables accessing the underlying file descriptors
+    # for Messenger.
+    class Selectable
+
+      include Qpid::Proton::Filters
+
+      call_before :check_is_initialized,
+      :fileno, :capacity, :pending, :deadline,
+      :readable, :writable, :expired,
+      :registered=, :registered?
+
+      def initialize(messenger, impl) # :nodoc:
+        @messenger = messenger
+        @impl = impl
+        @io = nil
+        @freed = false
+      end
+
+      # Returns the underlying file descriptor.
+      #
+      # This can be used in conjunction with the IO class.
+      #
+      def fileno
+        Cproton.pn_selectable_fd(@impl)
+      end
+
+      def to_io
+        @io ||= IO.new(fileno)
+      end
+
+      # The number of bytes the selectable is capable of consuming.
+      #
+      def capacity
+        Cproton.pn_selectable_capacity(@impl)
+      end
+
+      # The number of bytes waiting to be written to the file descriptor.
+      #
+      def pending
+        Cproton.pn_selectable_pending(@impl)
+      end
+
+      # The future expiry time at which control will be returned to the
+      # selectable.
+      #
+      def deadline
+        tstamp = Cproton.pn_selectable_deadline(@impl)
+        tstamp.nil? ? nil : tstamp / 1000
+      end
+
+      def readable
+        Cproton.pn_selectable_readable(@impl)
+      end
+
+      def writable
+        Cproton.pn_selectable_writable(@impl)
+      end
+
+      def expired?
+        Cproton.pn_selectable_expired(@impl)
+      end
+
+      def registered=(registered)
+        Cproton.pn_selectable_set_registered(@impl, registered)
+      end
+
+      def registered?
+        Cproton.pn_selectable_is_registered(@impl)
+      end
+
+      def terminal?
+        return true if @impl.nil?
+        Cproton.pn_selectable_is_terminal(@impl)
+      end
+
+      def to_s
+        "fileno=#{self.fileno} registered=#{self.registered?} terminal=#{self.terminal?}"
+      end
+
+      def free
+        return if @freed
+        @freed = true
+        @messenger.unregister_selectable(fileno)
+        @io.close unless @io.nil?
+        Cproton.pn_selectable_free(@impl)
+        @impl = nil
+      end
+
+      def freed? # :nodoc:
+        @freed
+      end
+
+      private
+
+      def check_is_initialized
+        raise RuntimeError.new("selectable freed") if @impl.nil?
+      end
+
+    end
+
+  end
+
+end


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