Author: rhs
Date: Wed Aug 21 13:53:25 2013
New Revision: 1516161

URL: http://svn.apache.org/r1516161
Log:
Added simple smoke tests for the bindings. Encountered numerous issues
along the way and fixed as appropriate, including:
  - added tracker return values for ruby put/get
  - fixed ruby accept/reject to omit the tracker arg
  - fixed a deprecation warning in the perl binding
  - added disposition calls for php (PROTON-365)
  - added incoming/outgoing window properties for php
  - fixed put of messages without an address (PROTON-368)
  - added C level inspection method for messages to allow consistent
    printing of messages across bindings

Added:
    qpid/proton/trunk/tests/smoke/
    qpid/proton/trunk/tests/smoke/recv.php   (with props)
    qpid/proton/trunk/tests/smoke/recv.pl   (with props)
    qpid/proton/trunk/tests/smoke/recv.py   (with props)
    qpid/proton/trunk/tests/smoke/recv.rb   (with props)
    qpid/proton/trunk/tests/smoke/send.php   (with props)
    qpid/proton/trunk/tests/smoke/send.pl   (with props)
    qpid/proton/trunk/tests/smoke/send.py   (with props)
    qpid/proton/trunk/tests/smoke/send.rb   (with props)
Modified:
    qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton.pm
    qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton/Message.pm
    qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton/Messenger.pm
    qpid/proton/trunk/proton-c/bindings/php/proton.php
    qpid/proton/trunk/proton-c/bindings/python/proton.py
    qpid/proton/trunk/proton-c/bindings/ruby/lib/qpid_proton/message.rb
    qpid/proton/trunk/proton-c/bindings/ruby/lib/qpid_proton/messenger.rb
    qpid/proton/trunk/proton-c/bindings/ruby/ruby.i
    qpid/proton/trunk/proton-c/include/proton/cproton.i
    qpid/proton/trunk/proton-c/include/proton/object.h
    qpid/proton/trunk/proton-c/src/codec/codec.c
    qpid/proton/trunk/proton-c/src/message/message.c
    qpid/proton/trunk/proton-c/src/messenger/messenger.c
    qpid/proton/trunk/proton-c/src/messenger/transform.c
    qpid/proton/trunk/proton-c/src/object/object.c
    qpid/proton/trunk/proton-c/src/tests/object.c

Modified: qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton.pm
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton.pm?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton.pm (original)
+++ qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton.pm Wed Aug 21 
13:53:25 2013
@@ -65,7 +65,7 @@ sub get_map_from {
         $data->next;
         $type = $data->get_type;
         my $value = $type->get($data);
-        %{$result}->{$key} = $value;
+        $result{$key} = $value;
     }
     $data->exit;
 

Modified: qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton/Message.pm
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton/Message.pm?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton/Message.pm 
(original)
+++ qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton/Message.pm Wed Aug 
21 13:53:25 2013
@@ -35,6 +35,16 @@ sub new {
     return $self;
 }
 
+use overload fallback => 1,
+    '""' => sub {
+        my ($self) = @_;
+        my $tmp = cproton_perl::pn_string("");
+        cproton_perl::pn_inspect($self->{_impl}, $tmp);
+        my $result = cproton_perl::pn_string_get($tmp);
+        cproton_perl::pn_free($tmp);
+        return $result;
+};
+
 sub DESTROY {
     my ($self) = @_;
     my $impl = $self->{_impl};

Modified: qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton/Messenger.pm
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton/Messenger.pm?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton/Messenger.pm 
(original)
+++ qpid/proton/trunk/proton-c/bindings/perl/lib/qpid/proton/Messenger.pm Wed 
Aug 21 13:53:25 2013
@@ -164,7 +164,9 @@ sub put {
 
 sub send {
     my ($self) = @_;
-    cproton_perl::pn_messenger_send($self->{_impl}, $_[1]);
+    my $n = $_[1];
+    $n = -1 if !defined $n;
+    cproton_perl::pn_messenger_send($self->{_impl}, $n);
 }
 
 sub get {
@@ -177,7 +179,9 @@ sub get {
 
 sub receive {
     my ($self) = @_;
-    cproton_perl::pn_messenger_recv($self->{_impl}, $_[1]);
+    my $n = $_[1];
+    $n = -1 if !defined $n;
+    cproton_perl::pn_messenger_recv($self->{_impl}, $n);
 }
 
 sub outgoing {
@@ -190,4 +194,32 @@ sub incoming {
     return cproton_perl::pn_messenger_incoming($self->{_impl});
 }
 
+sub accept {
+    my ($self) = @_;
+    my $tracker = $_[1];
+    my $flags = 0;
+    if (!defined $tracker) {
+        $tracker = cproton_perl::pn_messenger_incoming_tracker($self->{_impl});
+        $flags = $cproton_perl::PN_CUMULATIVE;
+    }
+    return cproton_perl::pn_messenger_accept($self->{_impl}, $tracker, $flags);
+}
+
+sub reject {
+    my ($self) = @_;
+    my $tracker = $_[1];
+    my $flags = 0;
+    if (!defined $tracker) {
+        $tracker = cproton_perl::pn_messenger_incoming_tracker($self->{_impl});
+        $flags = $cproton_perl::PN_CUMULATIVE;
+    }
+    return cproton_perl::pn_messenger_reject($self->{_impl}, $tracker, $flags);
+}
+
+sub status {
+    my ($self) = @_;
+    my $tracker = $_[1];
+    return cproton_perl::pn_messenger_status($self->{_impl}, $tracker);
+}
+
 1;

Modified: qpid/proton/trunk/proton-c/bindings/php/proton.php
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/php/proton.php?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/php/proton.php (original)
+++ qpid/proton/trunk/proton-c/bindings/php/proton.php Wed Aug 21 13:53:25 2013
@@ -102,6 +102,12 @@ class Messenger
     case "timeout":
       $this->_check(pn_messenger_set_timeout($this->impl, $value));
       break;
+    case "outgoing_window":
+      $this->_check(pn_messenger_set_outgoing_window($this->impl, $value));
+      break;
+    case "incoming_window":
+      $this->_check(pn_messenger_set_incoming_window($this->impl, $value));
+      break;
     default:
       throw new Exception("unknown property: " . $name);
     }
@@ -122,9 +128,14 @@ class Messenger
     $this->_check(pn_messenger_subscribe($this->impl, $source));
   }
 
+  public function outgoing_tracker() {
+    return pn_messenger_outgoing_tracker($this->impl);
+  }
+
   public function put($message) {
     $message->_pre_encode();
     $this->_check(pn_messenger_put($this->impl, $message->impl));
+    return $this->outgoing_tracker();
   }
 
   public function send($n = -1) {
@@ -135,9 +146,34 @@ class Messenger
     $this->_check(pn_messenger_recv($this->impl, $n));
   }
 
+  public function incoming_tracker() {
+    return pn_messenger_incoming_tracker($this->impl);
+  }
+
   public function get($message) {
     $this->_check(pn_messenger_get($this->impl, $message->impl));
     $message->_post_decode();
+    return $this->incoming_tracker();
+  }
+
+  public function accept($tracker = null) {
+    if ($tracker == null) {
+      $tracker = $this->incoming_tracker();
+      $flag = PN_CUMULATIVE;
+    } else {
+      $flag = 0;
+    }
+    $this->_check(pn_messenger_accept($this->impl, $tracker, $flag));
+  }
+
+  public function reject($tracker = null) {
+    if ($tracker == null) {
+      $tracker = $this->incoming_tracker();
+      $flag = PN_CUMULATIVE;
+    } else {
+      $flag = 0;
+    }
+    $this->_check(pn_messenger_reject($this->impl, $tracker, $flag));
   }
 
   public function route($pattern, $address) {
@@ -152,6 +188,10 @@ class Messenger
     return pn_messenger_incoming($this->impl);
   }
 
+  public function status($tracker) {
+    return pn_messenger_status($this->impl, $tracker);
+  }
+
 }
 
 class Message {
@@ -181,6 +221,14 @@ class Message {
     pn_message_free($this->impl);
   }
 
+  public function __tostring() {
+    $tmp = pn_string("");
+    pn_inspect($this->impl, $tmp);
+    $result = pn_string_get($tmp);
+    pn_free($tmp);
+    return $result;
+  }
+
   private function _check($value) {
     if ($value < 0) {
       $exc = code2exc($value);

Modified: qpid/proton/trunk/proton-c/bindings/python/proton.py
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/python/proton.py?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/python/proton.py (original)
+++ qpid/proton/trunk/proton-c/bindings/python/proton.py Wed Aug 21 13:53:25 
2013
@@ -889,6 +889,25 @@ The format of the message.
         self._check(err)
         return data
 
+  def __repr2__(self):
+    props = []
+    for attr in ("inferred", "address", "reply_to", "durable", "ttl",
+                 "priority", "first_acquirer", "delivery_count", "id",
+                 "correlation_id", "user_id", "group_id", "group_sequence",
+                 "reply_to_group_id", "instructions", "annotations",
+                 "properties", "body"):
+      value = getattr(self, attr)
+      if value: props.append("%s=%r" % (attr, value))
+    return "Message(%s)" % ", ".join(props)
+
+  def __repr__(self):
+    tmp = pn_string(None)
+    err = pn_inspect(self._msg, tmp)
+    result = pn_string_get(tmp)
+    pn_free(tmp)
+    self._check(err)
+    return result
+
 class DataException(ProtonException):
   """
   The DataException class is the root of the Data exception hierarchy.

Modified: qpid/proton/trunk/proton-c/bindings/ruby/lib/qpid_proton/message.rb
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/ruby/lib/qpid_proton/message.rb?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/ruby/lib/qpid_proton/message.rb 
(original)
+++ qpid/proton/trunk/proton-c/bindings/ruby/lib/qpid_proton/message.rb Wed Aug 
21 13:53:25 2013
@@ -114,6 +114,14 @@ module Qpid
         @body = nil
       end
 
+      def to_s
+        tmp = Cproton.pn_string("")
+        Cproton.pn_inspect(@impl, tmp)
+        result = Cproton.pn_string_get(tmp)
+        Cproton.pn_free(tmp)
+        return result
+      end
+
       # Invoked by garbage collection to clean up resources used
       # by the underlying message implementation.
       def self.finalize!(impl) # :nodoc:

Modified: qpid/proton/trunk/proton-c/bindings/ruby/lib/qpid_proton/messenger.rb
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/ruby/lib/qpid_proton/messenger.rb?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/ruby/lib/qpid_proton/messenger.rb 
(original)
+++ qpid/proton/trunk/proton-c/bindings/ruby/lib/qpid_proton/messenger.rb Wed 
Aug 21 13:53:25 2013
@@ -199,6 +199,7 @@ module Qpid
         # encode the message first
         message.pre_encode
         check_for_error(Cproton.pn_messenger_put(@impl, message.impl))
+        return outgoing_tracker
       end
 
       # Sends all outgoing messages, blocking until the outgoing queue
@@ -218,10 +219,15 @@ module Qpid
       # * msg - the (optional) +Message+ instance to be used
       #
       def get(msg = nil)
-        msg = Qpid::Proton::Message.new if msg.nil?
-        check_for_error(Cproton.pn_messenger_get(@impl, msg.impl))
+        msg_impl = nil
+        if msg.nil? then
+          msg_impl = nil
+        else
+          msg_impl = msg.impl
+        end
+        check_for_error(Cproton.pn_messenger_get(@impl, msg_impl))
         msg.post_decode unless msg.nil?
-        return msg
+        return incoming_tracker
       end
 
       # Receives up to the specified number of messages, blocking until at 
least
@@ -287,9 +293,14 @@ module Qpid
       # * tracker - the tracker
       # * flag - the flag
       #
-      def accept(tracker, flag)
-        raise TypeError.new("invalid tracker: #{tracker}") unless 
valid_tracker?(tracker)
-        raise TypeError.new("invalid flag: #{flag}") unless 
Qpid::Proton::Tracker.valid_flag?(flag)
+      def accept(tracker = nil)
+        raise TypeError.new("invalid tracker: #{tracker}") unless tracker.nil? 
or valid_tracker?(tracker)
+        if tracker.nil? then
+          tracker = self.incoming_tracker
+          flag = Cproton::PN_CUMULATIVE
+        else
+          flag = 0
+        end
         check_for_error(Cproton.pn_messenger_accept(@impl, tracker.impl, flag))
       end
 
@@ -300,8 +311,14 @@ module Qpid
       # * tracker - the tracker
       # * flag - the flag
       #
-      def reject(tracker, flag)
-        raise TypeError.new("invalid tracker: #{tracker}") unless 
valid_tracker?(tracker)
+      def reject(tracker)
+        raise TypeError.new("invalid tracker: #{tracker}") unless tracker.nil? 
or valid_tracker?(tracker)
+        if tracker.nil? then
+          tracker = self.incoming_tracker
+          flag = Cproton::PN_CUMULATIVE
+        else
+          flag = 0
+        end
         check_for_error(Cproton.pn_messenger_reject(@impl, tracker.impl, flag))
       end
 

Modified: qpid/proton/trunk/proton-c/bindings/ruby/ruby.i
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/bindings/ruby/ruby.i?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/bindings/ruby/ruby.i (original)
+++ qpid/proton/trunk/proton-c/bindings/ruby/ruby.i Wed Aug 21 13:53:25 2013
@@ -236,16 +236,6 @@
     }
 }
 
-%typemap (in) void *
-{
-  $1 = (void *) $input;
-}
-
-%typemap (out) void *
-{
-  $result = (VALUE) $1;
-}
-
 int pn_message_load(pn_message_t *msg, char *STRING, size_t LENGTH);
 %ignore pn_message_load;
 

Modified: qpid/proton/trunk/proton-c/include/proton/cproton.i
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/cproton.i?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/cproton.i (original)
+++ qpid/proton/trunk/proton-c/include/proton/cproton.i Wed Aug 21 13:53:25 2013
@@ -28,11 +28,17 @@ typedef unsigned long long int uint64_t;
 typedef long long int int64_t;
 
 /* Parse these interface header files to generate APIs for script languages */
+
 %include "proton/import_export.h"
 %include "proton/types.h"
+%ignore pn_string_vformat;
+%ignore pn_string_vaddf;
+%include "proton/object.h"
+
 %ignore pn_error_format;
 %ignore pn_error_vformat;
 
+
 /* checks that ensure only allowed values are supplied or returned */
 %aggregate_check(int, check_error,
                  PN_EOS, PN_ERR, PN_OVERFLOW, PN_UNDERFLOW,

Modified: qpid/proton/trunk/proton-c/include/proton/object.h
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/object.h?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/object.h (original)
+++ qpid/proton/trunk/proton-c/include/proton/object.h Wed Aug 21 13:53:25 2013
@@ -23,6 +23,7 @@
  */
 
 #include <proton/types.h>
+#include <stdarg.h>
 #ifndef __cplusplus
 #include <stdbool.h>
 #include <stdint.h>
@@ -36,10 +37,19 @@
 extern "C" {
 #endif
 
+typedef uintptr_t pn_handle_t;
+typedef intptr_t pn_shandle_t;
+
+typedef struct pn_list_t pn_list_t;
+typedef struct pn_map_t pn_map_t;
+typedef struct pn_hash_t pn_hash_t;
+typedef struct pn_string_t pn_string_t;
+
 typedef struct {
   void (*finalize)(void *);
   uintptr_t (*hashcode)(void *);
   intptr_t (*compare)(void *, void *);
+  int (*inspect)(void *, pn_string_t *);
 } pn_class_t;
 
 PN_EXTERN void *pn_new(size_t size, pn_class_t *clazz);
@@ -51,11 +61,10 @@ PN_EXTERN pn_class_t *pn_class(void *obj
 PN_EXTERN uintptr_t pn_hashcode(void *object);
 PN_EXTERN intptr_t pn_compare(void *a, void *b);
 PN_EXTERN bool pn_equals(void *a, void *b);
+PN_EXTERN int pn_inspect(void *object, pn_string_t *dst);
 
 #define PN_REFCOUNT (0x1)
 
-typedef struct pn_list_t pn_list_t;
-
 PN_EXTERN pn_list_t *pn_list(size_t capacity, int options);
 PN_EXTERN size_t pn_list_size(pn_list_t *list);
 PN_EXTERN void *pn_list_get(pn_list_t *list, int index);
@@ -65,11 +74,6 @@ PN_EXTERN ssize_t pn_list_index(pn_list_
 PN_EXTERN bool pn_list_remove(pn_list_t *list, void *value);
 PN_EXTERN void pn_list_del(pn_list_t *list, int index, int n);
 
-typedef uintptr_t pn_handle_t;
-typedef intptr_t pn_shandle_t;
-
-typedef struct pn_map_t pn_map_t;
-
 #define PN_REFCOUNT_KEY (0x2)
 #define PN_REFCOUNT_VALUE (0x4)
 
@@ -83,8 +87,6 @@ PN_EXTERN pn_handle_t pn_map_next(pn_map
 PN_EXTERN void *pn_map_key(pn_map_t *map, pn_handle_t entry);
 PN_EXTERN void *pn_map_value(pn_map_t *map, pn_handle_t entry);
 
-typedef struct pn_hash_t pn_hash_t;
-
 PN_EXTERN pn_hash_t *pn_hash(size_t capacity, float load_factor, int options);
 PN_EXTERN size_t pn_hash_size(pn_hash_t *hash);
 PN_EXTERN int pn_hash_put(pn_hash_t *hash, uintptr_t key, void *value);
@@ -95,8 +97,6 @@ PN_EXTERN pn_handle_t pn_hash_next(pn_ha
 PN_EXTERN uintptr_t pn_hash_key(pn_hash_t *hash, pn_handle_t entry);
 PN_EXTERN void *pn_hash_value(pn_hash_t *hash, pn_handle_t entry);
 
-typedef struct pn_string_t pn_string_t;
-
 PN_EXTERN pn_string_t *pn_string(const char *bytes);
 PN_EXTERN pn_string_t *pn_stringn(const char *bytes, size_t n);
 PN_EXTERN const char *pn_string_get(pn_string_t *string);
@@ -110,6 +110,14 @@ PN_EXTERN int pn_string_format(pn_string
   __attribute__ ((format (printf, 2, 3)))
 #endif
     ;
+PN_EXTERN int pn_string_vformat(pn_string_t *string, const char *format, 
va_list ap);
+PN_EXTERN int pn_string_addf(pn_string_t *string, const char *format, ...)
+#ifdef __GNUC__
+  __attribute__ ((format (printf, 2, 3)))
+#endif
+    ;
+PN_EXTERN int pn_string_vaddf(pn_string_t *string, const char *format, va_list 
ap);
+PN_EXTERN int pn_string_grow(pn_string_t *string, size_t capacity);
 PN_EXTERN char *pn_string_buffer(pn_string_t *string);
 PN_EXTERN size_t pn_string_capacity(pn_string_t *string);
 PN_EXTERN int pn_string_resize(pn_string_t *string, size_t size);

Modified: qpid/proton/trunk/proton-c/src/codec/codec.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/codec/codec.c?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/codec/codec.c (original)
+++ qpid/proton/trunk/proton-c/src/codec/codec.c Wed Aug 21 13:53:25 2013
@@ -1042,9 +1042,27 @@ static void pn_data_finalize(void *objec
   free(data->iatoms);
 }
 
+static int pn_data_inspect(void *obj, pn_string_t *dst)
+{
+  pn_data_t *data = (pn_data_t *) obj;
+  while (true) {
+    char *bytes = pn_string_buffer(dst) + pn_string_size(dst);
+    size_t size = pn_string_capacity(dst) - pn_string_size(dst);
+    int err = pn_data_format(data, bytes, &size);
+    if (err == PN_OVERFLOW) {
+      err = pn_string_grow(dst, pn_string_capacity(dst)*2);
+      if (err) return err;
+    } else if (err) {
+      return err;
+    } else {
+      return pn_string_resize(dst, pn_string_size(dst) + size);
+    }
+  }
+}
+
 pn_data_t *pn_data(size_t capacity)
 {
-  static pn_class_t clazz = {pn_data_finalize};
+  static pn_class_t clazz = {pn_data_finalize, NULL, NULL, pn_data_inspect};
   pn_data_t *data = (pn_data_t *) pn_new(sizeof(pn_data_t), &clazz);
   data->capacity = capacity;
   data->size = 0;

Modified: qpid/proton/trunk/proton-c/src/message/message.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/message/message.c?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/message/message.c (original)
+++ qpid/proton/trunk/proton-c/src/message/message.c Wed Aug 21 13:53:25 2013
@@ -30,6 +30,7 @@
 #include <assert.h>
 #include "protocol.h"
 #include "../util.h"
+#include "../platform_fmt.h"
 
 ssize_t pn_message_data(char *dst, size_t available, const char *src, size_t 
size)
 {
@@ -79,9 +80,242 @@ struct pn_message_t {
   pn_error_t *error;
 };
 
+void pn_message_finalize(void *obj)
+{
+  pn_message_t *msg = (pn_message_t *) obj;
+  pn_free(msg->user_id);
+  pn_free(msg->address);
+  pn_free(msg->subject);
+  pn_free(msg->reply_to);
+  pn_free(msg->content_type);
+  pn_free(msg->content_encoding);
+  pn_free(msg->group_id);
+  pn_free(msg->reply_to_group_id);
+  pn_data_free(msg->id);
+  pn_data_free(msg->correlation_id);
+  pn_data_free(msg->data);
+  pn_data_free(msg->instructions);
+  pn_data_free(msg->annotations);
+  pn_data_free(msg->properties);
+  pn_data_free(msg->body);
+  pn_parser_free(msg->parser);
+  pn_error_free(msg->error);
+}
+
+int pn_message_inspect(void *obj, pn_string_t *dst)
+{
+  pn_message_t *msg = (pn_message_t *) obj;
+  int err = pn_string_addf(dst, "Message{");
+  if (err) return err;
+
+  bool comma = false;
+
+  if (pn_string_get(msg->address)) {
+    err = pn_string_addf(dst, "address=");
+    if (err) return err;
+    err = pn_inspect(msg->address, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (msg->durable) {
+    err = pn_string_addf(dst, "durable=%i, ", msg->durable);
+    if (err) return err;
+    comma = true;
+  }
+
+  if (msg->priority != PN_DEFAULT_PRIORITY) {
+    err = pn_string_addf(dst, "priority=%i, ", msg->priority);
+    if (err) return err;
+    comma = true;
+  }
+
+  if (msg->ttl) {
+    err = pn_string_addf(dst, "ttl=%" PRIu32 ", ", msg->ttl);
+    if (err) return err;
+    comma = true;
+  }
+
+  if (msg->first_acquirer) {
+    err = pn_string_addf(dst, "first_acquirer=%i, ", msg->first_acquirer);
+    if (err) return err;
+    comma = true;
+  }
+
+  if (msg->delivery_count) {
+    err = pn_string_addf(dst, "delivery_count=%" PRIu32 ", ", 
msg->delivery_count);
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_data_size(msg->id)) {
+    err = pn_string_addf(dst, "id=");
+    if (err) return err;
+    err = pn_inspect(msg->id, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_string_get(msg->user_id)) {
+    err = pn_string_addf(dst, "user_id=");
+    if (err) return err;
+    err = pn_inspect(msg->user_id, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_string_get(msg->subject)) {
+    err = pn_string_addf(dst, "subject=");
+    if (err) return err;
+    err = pn_inspect(msg->subject, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_string_get(msg->reply_to)) {
+    err = pn_string_addf(dst, "reply_to=");
+    if (err) return err;
+    err = pn_inspect(msg->reply_to, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_data_size(msg->correlation_id)) {
+    err = pn_string_addf(dst, "correlation_id=");
+    if (err) return err;
+    err = pn_inspect(msg->correlation_id, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_string_get(msg->content_type)) {
+    err = pn_string_addf(dst, "content_type=");
+    if (err) return err;
+    err = pn_inspect(msg->content_type, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_string_get(msg->content_encoding)) {
+    err = pn_string_addf(dst, "content_encoding=");
+    if (err) return err;
+    err = pn_inspect(msg->content_encoding, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (msg->expiry_time) {
+    err = pn_string_addf(dst, "expiry_time=%" PRIi64 ", ", msg->expiry_time);
+    if (err) return err;
+    comma = true;
+  }
+
+  if (msg->creation_time) {
+    err = pn_string_addf(dst, "creation_time=%" PRIi64 ", ", 
msg->creation_time);
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_string_get(msg->group_id)) {
+    err = pn_string_addf(dst, "group_id=");
+    if (err) return err;
+    err = pn_inspect(msg->group_id, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (msg->group_sequence) {
+    err = pn_string_addf(dst, "group_sequence=%" PRIi32 ", ", 
msg->group_sequence);
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_string_get(msg->reply_to_group_id)) {
+    err = pn_string_addf(dst, "reply_to_group_id=");
+    if (err) return err;
+    err = pn_inspect(msg->reply_to_group_id, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (msg->inferred) {
+    err = pn_string_addf(dst, "inferred=%i, ", msg->inferred);
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_data_size(msg->instructions)) {
+    err = pn_string_addf(dst, "instructions=");
+    if (err) return err;
+    err = pn_inspect(msg->instructions, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_data_size(msg->annotations)) {
+    err = pn_string_addf(dst, "annotations=");
+    if (err) return err;
+    err = pn_inspect(msg->annotations, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_data_size(msg->properties)) {
+    err = pn_string_addf(dst, "properties=");
+    if (err) return err;
+    err = pn_inspect(msg->properties, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (pn_data_size(msg->body)) {
+    err = pn_string_addf(dst, "body=");
+    if (err) return err;
+    err = pn_inspect(msg->body, dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ", ");
+    if (err) return err;
+    comma = true;
+  }
+
+  if (comma) {
+    int err = pn_string_resize(dst, pn_string_size(dst) - 2);
+    if (err) return err;
+  }
+
+  return pn_string_addf(dst, "}");
+}
+
 pn_message_t *pn_message()
 {
-  pn_message_t *msg = (pn_message_t *) malloc(sizeof(pn_message_t));
+  static pn_class_t clazz = {pn_message_finalize, NULL, NULL, 
pn_message_inspect};
+  pn_message_t *msg = (pn_message_t *) pn_new(sizeof(pn_message_t), &clazz);
   msg->durable = false;
   msg->priority = PN_DEFAULT_PRIORITY;
   msg->ttl = 0;
@@ -116,26 +350,7 @@ pn_message_t *pn_message()
 
 void pn_message_free(pn_message_t *msg)
 {
-  if (msg) {
-    pn_free(msg->user_id);
-    pn_free(msg->address);
-    pn_free(msg->subject);
-    pn_free(msg->reply_to);
-    pn_free(msg->content_type);
-    pn_free(msg->content_encoding);
-    pn_free(msg->group_id);
-    pn_free(msg->reply_to_group_id);
-    pn_data_free(msg->id);
-    pn_data_free(msg->correlation_id);
-    pn_data_free(msg->data);
-    pn_data_free(msg->instructions);
-    pn_data_free(msg->annotations);
-    pn_data_free(msg->properties);
-    pn_data_free(msg->body);
-    pn_parser_free(msg->parser);
-    pn_error_free(msg->error);
-    free(msg);
-  }
+  pn_free(msg);
 }
 
 void pn_message_clear(pn_message_t *msg)

Modified: qpid/proton/trunk/proton-c/src/messenger/messenger.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/messenger/messenger.c?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/messenger/messenger.c (original)
+++ qpid/proton/trunk/proton-c/src/messenger/messenger.c Wed Aug 21 13:53:25 
2013
@@ -802,7 +802,7 @@ static int pni_route(pn_messenger_t *mes
 pn_connection_t *pn_messenger_resolve(pn_messenger_t *messenger, const char 
*address, char **name)
 {
   char domain[1024];
-  if (sizeof(domain) < strlen(address) + 1) {
+  if (address && sizeof(domain) < strlen(address) + 1) {
     pn_error_format(messenger->error, PN_ERR,
                     "address exceeded maximum length: %s", address);
     return NULL;

Modified: qpid/proton/trunk/proton-c/src/messenger/transform.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/messenger/transform.c?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/messenger/transform.c (original)
+++ qpid/proton/trunk/proton-c/src/messenger/transform.c Wed Aug 21 13:53:25 
2013
@@ -134,6 +134,7 @@ static bool pni_match_r(pn_matcher_t *ma
 
 static bool pni_match(pn_matcher_t *matcher, const char *pattern, const char 
*text)
 {
+  text = text ? text : "";
   matcher->groups = 0;
   if (pni_match_r(matcher, pattern, text, 1, 0)) {
     matcher->group[0].start = text;

Modified: qpid/proton/trunk/proton-c/src/object/object.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/object/object.c?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/object/object.c (original)
+++ qpid/proton/trunk/proton-c/src/object/object.c Wed Aug 21 13:53:25 2013
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#include <ctype.h>
 
 typedef struct {
   pn_class_t *clazz;
@@ -126,6 +127,26 @@ bool pn_equals(void *a, void *b)
   return !pn_compare(a, b);
 }
 
+int pn_inspect(void *object, pn_string_t *dst)
+{
+  if (!pn_string_get(dst)) {
+    pn_string_set(dst, "");
+  }
+
+  if (object) {
+    pni_head_t *head = pni_head(object);
+    if (head->clazz) {
+      pn_class_t *clazz = head->clazz;
+      if (clazz->inspect) {
+        return clazz->inspect(object, dst);
+      }
+    }
+    return pn_string_addf(dst, "object<%p>", object);
+  } else {
+    return pn_string_addf(dst, "(null)");
+  }
+}
+
 struct pn_list_t {
   size_t capacity;
   size_t size;
@@ -330,7 +351,7 @@ static void pni_map_allocate(pn_map_t *m
 
 pn_map_t *pn_map(size_t capacity, float load_factor, int options)
 {
-  static pn_class_t clazz = {pn_map_finalize, pn_map_hashcode};
+  static pn_class_t clazz = {pn_map_finalize, pn_map_hashcode, NULL};
 
   pn_map_t *map = (pn_map_t *) pn_new(sizeof(pn_map_t), &clazz);
   map->capacity = capacity ? capacity : 16;
@@ -626,13 +647,36 @@ static intptr_t pn_string_compare(void *
   }
 }
 
+static int pn_string_inspect(void *obj, pn_string_t *dst)
+{
+  pn_string_t *str = (pn_string_t *) obj;
+  if (str->size == PNI_NULL_SIZE) {
+    return pn_string_addf(dst, "null");
+  }
+
+  int err = pn_string_addf(dst, "\"");
+
+  for (int i = 0; i < str->size; i++) {
+    uint8_t c = str->bytes[i];
+    if (isprint(c)) {
+      err = pn_string_addf(dst, "%c", c);
+      if (err) return err;
+    } else {
+      err = pn_string_addf(dst, "\\x%.2x", c);
+      if (err) return err;
+    }
+  }
+
+  return pn_string_addf(dst, "\"");
+}
+
 pn_string_t *pn_string(const char *bytes)
 {
   return pn_stringn(bytes, bytes ? strlen(bytes) : 0);
 }
 
 static pn_class_t clazz = {pn_string_finalize, pn_string_hashcode,
-                           pn_string_compare};
+                           pn_string_compare, pn_string_inspect};
 
 pn_string_t *pn_stringn(const char *bytes, size_t n)
 {
@@ -669,7 +713,7 @@ int pn_string_set(pn_string_t *string, c
   return pn_string_setn(string, bytes, bytes ? strlen(bytes) : 0);
 }
 
-static int pn_string_grow(pn_string_t *string, size_t capacity)
+int pn_string_grow(pn_string_t *string, size_t capacity)
 {
   bool grow = false;
   while (string->capacity < (capacity*sizeof(char) + 1)) {
@@ -726,16 +770,46 @@ int pn_string_format(pn_string_t *string
 {
   va_list ap;
 
+  va_start(ap, format);
+  int err = pn_string_vformat(string, format, ap);
+  va_end(ap);
+  return err;
+}
+
+int pn_string_vformat(pn_string_t *string, const char *format, va_list ap)
+{
+  pn_string_set(string, "");
+  return pn_string_vaddf(string, format, ap);
+}
+
+int pn_string_addf(pn_string_t *string, const char *format, ...)
+{
+  va_list ap;
+
+  va_start(ap, format);
+  int err = pn_string_vaddf(string, format, ap);
+  va_end(ap);
+  return err;
+}
+
+int pn_string_vaddf(pn_string_t *string, const char *format, va_list ap)
+{
+  va_list copy;
+
+  if (string->size == PNI_NULL_SIZE) {
+    return PN_ERR;
+  }
+
   while (true) {
-    va_start(ap, format);
-    int err = vsnprintf(string->bytes, string->capacity, format, ap);
-    va_end(ap);
+    va_copy(copy, ap);
+    int err = vsnprintf(string->bytes + string->size, string->capacity - 
string->size, format, copy);
+    va_end(copy);
     if (err < 0) {
       return err;
-    } else if ((size_t) err >= string->capacity) {
-      pn_string_grow(string, err);
+    } else if ((size_t) err >= string->capacity - string->size) {
+      pn_string_grow(string, string->size + err);
     } else {
-      string->size = err;
+      string->size += err;
       return 0;
     }
   }

Modified: qpid/proton/trunk/proton-c/src/tests/object.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/tests/object.c?rev=1516161&r1=1516160&r2=1516161&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/tests/object.c (original)
+++ qpid/proton/trunk/proton-c/src/tests/object.c Wed Aug 21 13:53:25 2013
@@ -579,6 +579,18 @@ static void test_string_format()
   pn_free(str);
 }
 
+static void test_string_addf()
+{
+  pn_string_t *str = pn_string("hello ");
+  assert(str);
+  int err = pn_string_addf(str, "%s", "this is a string that should be long "
+                           "enough to force growth but just in case we'll "
+                           "tack this other really long string on for the "
+                           "heck of it");
+  assert(err == 0);
+  pn_free(str);
+}
+
 static void test_map_iteration(int n)
 {
   pn_list_t *pairs = pn_list(2*n, PN_REFCOUNT);
@@ -658,6 +670,7 @@ int main(int argc, char **argv)
   test_stringn("this has an embedded \000 in it", 28);
 
   test_string_format();
+  test_string_addf();
 
   test_build_list();
   test_build_map();

Added: qpid/proton/trunk/tests/smoke/recv.php
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/smoke/recv.php?rev=1516161&view=auto
==============================================================================
--- qpid/proton/trunk/tests/smoke/recv.php (added)
+++ qpid/proton/trunk/tests/smoke/recv.php Wed Aug 21 13:53:25 2013
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+<?php
+
+include("proton.php");
+
+$messenger = new Messenger();
+$messenger->incoming_window = 10;
+$message = new Message();
+
+$address = $argv[1];
+if (!$address) {
+  $address = "~0.0.0.0";
+}
+$messenger->subscribe($address);
+
+$messenger->start();
+
+while (true) {
+  $messenger->recv();
+  $messenger->get($message);
+  print "Got: $message\n";
+  $messenger->accept();
+}
+
+$messenger->stop();
+
+?>
\ No newline at end of file

Propchange: qpid/proton/trunk/tests/smoke/recv.php
------------------------------------------------------------------------------
    svn:executable = *

Added: qpid/proton/trunk/tests/smoke/recv.pl
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/smoke/recv.pl?rev=1516161&view=auto
==============================================================================
--- qpid/proton/trunk/tests/smoke/recv.pl (added)
+++ qpid/proton/trunk/tests/smoke/recv.pl Wed Aug 21 13:53:25 2013
@@ -0,0 +1,23 @@
+#!/usr/bin/env perl
+require 'qpid_proton.pm';
+
+my $messenger = qpid::proton::Messenger->new();
+$messenger->set_incoming_window(1);
+my $message = qpid::proton::Message->new();
+
+my $address = $ARGV[0];
+$address = "~0.0.0.0" if !defined $address;
+$messenger->subscribe($address);
+
+$messenger->start();
+
+while (true) {
+    my $err = $messenger->receive();
+    # XXX: no exceptions!
+    die $messenger->get_error() if $err < 0;
+    $messenger->get($message);
+    print "Got: $message\n";
+    $messenger->accept();
+}
+
+$messenger->stop();

Propchange: qpid/proton/trunk/tests/smoke/recv.pl
------------------------------------------------------------------------------
    svn:executable = *

Added: qpid/proton/trunk/tests/smoke/recv.py
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/smoke/recv.py?rev=1516161&view=auto
==============================================================================
--- qpid/proton/trunk/tests/smoke/recv.py (added)
+++ qpid/proton/trunk/tests/smoke/recv.py Wed Aug 21 13:53:25 2013
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+import sys
+from proton import *
+
+messenger = Messenger()
+messenger.incoming_window = 1
+message = Message()
+
+address = "~0.0.0.0"
+if len(sys.argv) > 1:
+  address = sys.argv[1]
+messenger.subscribe(address)
+
+messenger.start()
+
+while True:
+  messenger.recv()
+  messenger.get(message)
+  print "Got: %s" % message
+  messenger.accept()
+
+messenger.stop()

Propchange: qpid/proton/trunk/tests/smoke/recv.py
------------------------------------------------------------------------------
    svn:executable = *

Added: qpid/proton/trunk/tests/smoke/recv.rb
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/smoke/recv.rb?rev=1516161&view=auto
==============================================================================
--- qpid/proton/trunk/tests/smoke/recv.rb (added)
+++ qpid/proton/trunk/tests/smoke/recv.rb Wed Aug 21 13:53:25 2013
@@ -0,0 +1,24 @@
+#!/usr/bin/env ruby
+
+require 'qpid_proton.rb'
+
+messenger = Qpid::Proton::Messenger.new()
+messenger.incoming_window = 1
+message = Qpid::Proton::Message.new()
+
+address = ARGV[0]
+if not address then
+  address = "~0.0.0.0"
+end
+messenger.subscribe(address)
+
+messenger.start()
+
+while (true) do
+  messenger.receive()
+  messenger.get(message)
+  print "Got: #{message}\n"
+  messenger.accept()
+end
+
+messenger.stop()

Propchange: qpid/proton/trunk/tests/smoke/recv.rb
------------------------------------------------------------------------------
    svn:executable = *

Added: qpid/proton/trunk/tests/smoke/send.php
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/smoke/send.php?rev=1516161&view=auto
==============================================================================
--- qpid/proton/trunk/tests/smoke/send.php (added)
+++ qpid/proton/trunk/tests/smoke/send.php Wed Aug 21 13:53:25 2013
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+<?php
+
+include("proton.php");
+
+$messenger = new Messenger();
+$messenger->outgoing_window = 10;
+$message = new Message();
+
+$address = $argv[1];
+if (!$address) {
+  $address = "0.0.0.0";
+}
+
+$message->address = $address;
+$message->properties = Array("binding" => "php",
+                             "version" => phpversion());
+$message->body = "Hello World!";
+
+$messenger->start();
+$tracker = $messenger->put($message);
+print "Put: $message\n";
+$messenger->send();
+print "Status: " . $messenger->status($tracker) . "\n";
+$messenger->stop();
+
+?>
\ No newline at end of file

Propchange: qpid/proton/trunk/tests/smoke/send.php
------------------------------------------------------------------------------
    svn:executable = *

Added: qpid/proton/trunk/tests/smoke/send.pl
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/smoke/send.pl?rev=1516161&view=auto
==============================================================================
--- qpid/proton/trunk/tests/smoke/send.pl (added)
+++ qpid/proton/trunk/tests/smoke/send.pl Wed Aug 21 13:53:25 2013
@@ -0,0 +1,17 @@
+#!/usr/bin/env perl
+require 'qpid_proton.pm';
+my $messenger = qpid::proton::Messenger->new();
+$messenger->set_outgoing_window(10);
+my $message = qpid::proton::Message->new();
+
+my $address = $ARGV[0];
+$address = "0.0.0.0" if !defined $address;
+$message->set_address($address);
+# how do we set properties and body?
+
+$messenger->start();
+my $tracker = $messenger->put($message);
+print "Put: $message\n";
+$messenger->send();
+print "Status: ", $messenger->status($tracker), "\n";
+$messenger->stop();

Propchange: qpid/proton/trunk/tests/smoke/send.pl
------------------------------------------------------------------------------
    svn:executable = *

Added: qpid/proton/trunk/tests/smoke/send.py
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/smoke/send.py?rev=1516161&view=auto
==============================================================================
--- qpid/proton/trunk/tests/smoke/send.py (added)
+++ qpid/proton/trunk/tests/smoke/send.py Wed Aug 21 13:53:25 2013
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+import sys
+from proton import *
+
+messenger = Messenger()
+messenger.outgoing_window = 10
+message = Message()
+
+address = "0.0.0.0"
+if len(sys.argv) > 1:
+  address = sys.argv[1]
+
+message.address = address
+message.properties = {u"binding": u"python",
+                      u"version": sys.version}
+message.body = u"Hello World!"
+
+messenger.start()
+tracker = messenger.put(message)
+print "Put: %s" % message
+messenger.send()
+print "Status: %s" % messenger.status(tracker)
+messenger.stop()

Propchange: qpid/proton/trunk/tests/smoke/send.py
------------------------------------------------------------------------------
    svn:executable = *

Added: qpid/proton/trunk/tests/smoke/send.rb
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/tests/smoke/send.rb?rev=1516161&view=auto
==============================================================================
--- qpid/proton/trunk/tests/smoke/send.rb (added)
+++ qpid/proton/trunk/tests/smoke/send.rb Wed Aug 21 13:53:25 2013
@@ -0,0 +1,24 @@
+#!/usr/bin/env ruby
+
+require 'qpid_proton.rb'
+
+messenger = Qpid::Proton::Messenger.new()
+messenger.outgoing_window = 10
+message = Qpid::Proton::Message.new()
+
+address = ARGV[0]
+if not address then
+  address = "0.0.0.0"
+end
+
+message.address = address
+message.properties = {"binding" => "ruby",
+  "version" => "#{RUBY_VERSION} #{RUBY_PLATFORM}"}
+message.body = "Hello World!"
+
+messenger.start()
+tracker = messenger.put(message)
+print "Put: #{message}\n"
+messenger.send()
+print "Status: ", messenger.status(tracker), "\n"
+messenger.stop()

Propchange: qpid/proton/trunk/tests/smoke/send.rb
------------------------------------------------------------------------------
    svn:executable = *



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to