initial contribution of etch ruby binding from cisco.

git-svn-id: https://svn.apache.org/repos/asf/incubator/etch/branches/ruby@768343 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/binding-ruby/src/main/ruby/idl/Test.etch b/binding-ruby/src/main/ruby/idl/Test.etch
new file mode 100644
index 0000000..c72d9bd
--- /dev/null
+++ b/binding-ruby/src/main/ruby/idl/Test.etch
@@ -0,0 +1,33 @@
+module etch.bindings.ruby.test
+@Direction(Both) 
+@Timeout(4000)
+service Test
+{
+	const int FOO = 23
+	
+	enum E1 ( A, B, C )
+	void nothing()
+	
+	struct S1( int x, int y, int z )
+	struct S2( S1 a, S1 b, E1 c )
+	
+	int incr( int x )
+	int sum( int[] x )
+	int trans( E1 e, int x )
+	double dist( S1 a, S1 b )
+	int[] fill( int n, int x )
+	
+	exception Excp1( string msg, int code )
+	void blow( string msg, int code ) throws Excp1
+	
+	@Unchecked(true)
+	exception Excp3()
+	@Unchecked(false)
+	exception Excp4()
+	int beets( E1 e ) throws Excp3, Excp4
+	
+	exception X( int g, int h, int i )
+	exception Y( int g, int h, int i )
+	int add( int x, int y ) throws X
+	int sub( int x, int y ) throws X, Y
+}
diff --git a/binding-ruby/src/main/ruby/idl/test/fake_test.rb b/binding-ruby/src/main/ruby/idl/test/fake_test.rb
new file mode 100644
index 0000000..333804a
--- /dev/null
+++ b/binding-ruby/src/main/ruby/idl/test/fake_test.rb
@@ -0,0 +1,66 @@
+require 'etch/bindings/ruby/idl/test/Test'
+
+# silly implementation of test used for testing
+class FakeTest
+  include Test
+  
+  def beets( e )
+    
+    if ( e == nil )
+      return nil
+    end
+    
+    case ( e )
+      when Test::E1::A then return 5
+      when Test::E1::B then raise Test::Excp3.new
+      when Test::E1::C then raise Test::Excp4.new
+      else return nil
+    end
+  end
+  
+  def blow( msg, code )
+    raise Test::Excp1.new( msg, code )
+  end
+  
+  def dist( a, b )
+    c = Test::S1.new( a.x - b.x, a.y - b.y, a.z - b.z )
+    return Math.sqrt( c.x * c.x + c.y * c.y + c.z * c.z )
+  end
+  
+  def incr( x )
+    return ( x+1 )
+  end
+  
+  def nothing()
+    # nothing
+  end
+  
+  def sub( x, y )
+    return ( x - y )
+  end
+  
+  def sum( x )
+    sumVar = 0 
+    x.each { |value| sumVar += value }
+    return sumVar
+  end
+  
+  def trans( e, x )
+    case ( e )
+      when Test::E1::A then return ( x/2 )
+      when Test::E1::B then return ( x*2 )
+      when Test::E1::C then return ( x+7 )
+    end
+  end
+  
+  def fill( n, x )
+    y = Array.new( n )
+    for i in 0...n
+      y[i] = x
+    end
+    return y
+  end
+
+  
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/idl/test/test_remote_test_server.rb b/binding-ruby/src/main/ruby/idl/test/test_remote_test_server.rb
new file mode 100644
index 0000000..dd491e6
--- /dev/null
+++ b/binding-ruby/src/main/ruby/idl/test/test_remote_test_server.rb
@@ -0,0 +1,382 @@
+require 'test/unit'
+require 'etch/bindings/ruby/support/delivery_service'
+require 'etch/bindings/ruby/idl/test/RemoteTest'
+require 'etch/bindings/ruby/idl/test/ValueFactoryTest'
+
+class TestRemoteTestServer < Test::Unit::TestCase
+  
+  attr :svc, true
+  attr :test, true
+  
+  def setup
+    @svc = MyDeliveryService.new
+    @test = RemoteTest.new( svc )
+  end
+  
+  def test_method_nothing
+    @test.nothing()  
+    check( :VOIDCALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_nothing, 
+            Array.new, Array.new, ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_nothing, 
+            4000 )
+  end
+  
+  def test_method_incr1
+    @svc.xresult = 2
+    assert_equal( 2, @test.incr( 1 ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_incr, 
+            Array[ ValueFactoryTest::MF_x ], Array[ 1 ], 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_incr, 
+            4000 )
+  end
+  
+  def test_method_incr2
+    @svc.xresult = 3
+    assert_equal( 3, @test.incr( 2 ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_incr, 
+            Array[ ValueFactoryTest::MF_x ], Array[ 2 ], 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_incr, 
+            4000 )
+  end
+  
+  def test_method_incr3
+    @svc.xresult = -1
+    assert_equal( -1, @test.incr( -2 ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_incr, 
+            Array[ ValueFactoryTest::MF_x ], Array[ -2 ], 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_incr, 
+            4000 )
+  end
+  
+  def test_method_sub1
+    @svc.xresult = 5
+    assert_equal( 5, @test.sub( 7, 2 ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_sub, 
+            Array[ ValueFactoryTest::MF_x, ValueFactoryTest::MF_y ], 
+            Array[ 7, 2 ], 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_sub, 
+            4000 )
+  end
+  
+  def test_method_sub2
+    @svc.xresult = 8
+    assert_equal( 8, @test.sub( 23, 15 ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_sub, 
+            Array[ ValueFactoryTest::MF_x, ValueFactoryTest::MF_y ], 
+            Array[ 23, 15 ], 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_sub, 
+            4000 )
+  end
+  
+  def test_method_sub3
+    @svc.xresult = -5
+    assert_equal( -5, @test.sub( 2, 7 ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_sub, 
+            Array[ ValueFactoryTest::MF_x, ValueFactoryTest::MF_y ], 
+            Array[ 2, 7 ], 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_sub, 
+            4000 )
+  end
+  
+  def test_method_sum
+    @svc.xresult = 24
+    args = Array[ 1, 2, 3, 7, 11 ]
+    assert_equal( 24, @test.sum( args ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_sum, 
+            Array[ ValueFactoryTest::MF_x ], 
+            Array[ args ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_sum, 
+            4000 )
+  end
+  
+  def test_method_trans1
+    @svc.xresult = 2
+    assert_equal( 2, @test.trans( Test::E1::A, 5 ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_trans, 
+            Array[ ValueFactoryTest::MF_e, ValueFactoryTest::MF_x ], 
+            Array[ Test::E1::A, 5 ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_trans, 
+            4000 )
+  end
+  
+  def test_method_trans2
+    @svc.xresult = 10
+    assert_equal( 10, @test.trans( Test::E1::B, 5 ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_trans, 
+            Array[ ValueFactoryTest::MF_e, ValueFactoryTest::MF_x ], 
+            Array[ Test::E1::B, 5 ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_trans, 
+            4000 )
+  end
+  
+  
+  def test_method_trans3
+    @svc.xresult = 12
+    assert_equal( 12, @test.trans( Test::E1::C, 5 ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_trans, 
+            Array[ ValueFactoryTest::MF_e, ValueFactoryTest::MF_x ], 
+            Array[ Test::E1::C, 5 ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_trans, 
+            4000 )
+  end
+  
+  def test_method_dist1
+    @svc.xresult = Math.sqrt( 3 )
+    arg1 = Test::S1.new( 1, 1, 1 )
+    arg2 = Test::S1.new( 0, 0, 0 )
+    assert_equal( Math.sqrt( 3 ), @test.dist( arg1, arg2 ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_dist, 
+            Array[ ValueFactoryTest::MF_a, ValueFactoryTest::MF_b ], 
+            Array[ arg1, arg2 ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_dist, 
+            4000 )
+  end
+  
+  def test_method_dist2
+    @svc.xresult = Math.sqrt( 35 )
+    arg1 = Test::S1.new( 1, 2, 3 )
+    arg2 = Test::S1.new( 6, 5, 4 )
+    assert_equal( Math.sqrt( 35 ), @test.dist( arg1, arg2 ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_dist, 
+            Array[ ValueFactoryTest::MF_a, ValueFactoryTest::MF_b ], 
+            Array[ arg1, arg2 ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_dist, 
+            4000 )
+  end
+  
+  def test_method_dist3
+    @svc.xresult = Math.sqrt( 56 )
+    arg1 = Test::S1.new( 1, 2, 3 )
+    arg2 = Test::S1.new( -1, -2, -3 )
+    assert_equal( Math.sqrt( 56 ), @test.dist( arg1, arg2 ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_dist, 
+            Array[ ValueFactoryTest::MF_a, ValueFactoryTest::MF_b ], 
+            Array[ arg1, arg2 ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_dist, 
+            4000 )
+  end
+  
+  def test_method_fill1
+    @svc.xresult = Array.new
+    x = @test.fill( 0, 1 )
+    assert_equal( 0, x.length )
+    
+    x.each { |value| assert_equal( 1, value ) }
+    
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_fill, 
+            Array[ ValueFactoryTest::MF_n, ValueFactoryTest::MF_x ], 
+            Array[ 0, 1 ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_fill, 
+            4000 )
+  end
+  
+  def test_method_fill2
+    @svc.xresult = Array[ 2 ]
+    x = @test.fill( 1, 2 )
+    assert_equal( 1, x.length )
+    x.each { |value| assert_equal( 2, value ) }
+    
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_fill, 
+            Array[ ValueFactoryTest::MF_n, ValueFactoryTest::MF_x ], 
+            Array[ 1, 2 ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_fill, 
+            4000 )
+  end
+  
+  def test_method_fill3
+    @svc.xresult = Array[ 3, 3 ] 
+    x = @test.fill( 2, 3 )
+    assert_equal( 2, x.length )
+    x.each { |value| assert_equal( 3, value ) }
+    
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_fill, 
+            Array[ ValueFactoryTest::MF_n, ValueFactoryTest::MF_x ], 
+            Array[ 2, 3 ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_fill, 
+            4000 )
+  end
+  
+  def test_method_blow1
+    begin
+      @svc.xresult = Test::Excp1.new( "foo", 2 )
+      @test.blow( "foo", 2 )
+      flunk( "did not throw ! " )
+    rescue Test::Excp1 => e
+      assert_equal( "foo", e.msg )
+      assert_equal( 2, e.code )
+    end
+    check( :VOIDCALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_blow, 
+            Array[ ValueFactoryTest::MF_msg, ValueFactoryTest::MF_code ], 
+            Array[ "foo", 2 ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_blow, 
+            4000 )
+  end
+  
+  def test_method_blow2
+    begin
+      @svc.xresult = Test::Excp1.new( "bar", 3 )
+      @test.blow( "bar", 3 )
+      flunk( "did not throw ! " )
+    rescue Test::Excp1 => e
+      assert_equal( "bar", e.msg )
+      assert_equal( 3, e.code )
+    end
+    check( :VOIDCALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_blow, 
+            Array[ ValueFactoryTest::MF_msg, ValueFactoryTest::MF_code ], 
+            Array[ "bar", 3 ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_blow, 
+            4000 )
+  end
+  
+  def test_method_beets1
+    @svc.xresult = 5
+    assert_equal( 5, @test.beets( Test::E1::A ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_beets, 
+            Array[ ValueFactoryTest::MF_e ], 
+            Array[ Test::E1::A ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_beets, 
+            4000 )
+  end
+  
+  def test_method_beets2
+    
+    begin
+      
+      @svc.xresult = Test::Excp3.new
+      @test.beets( Test::E1::B )
+      flunk( "beets did not throw" )
+    
+    rescue Test::Excp3 => e
+      assert( true )
+    end
+    
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_beets, 
+            Array[ ValueFactoryTest::MF_e ], 
+            Array[ Test::E1::B ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_beets, 
+            4000 )
+  end
+  
+  def test_method_beets3
+    
+    begin
+      
+      @svc.xresult = Test::Excp4.new
+      @test.beets( Test::E1::C )
+      flunk( "beets did not throw" )
+    
+    rescue Test::Excp4 => e
+      assert( true )
+    end
+    
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_beets, 
+            Array[ ValueFactoryTest::MF_e ], 
+            Array[ Test::E1::C ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_beets, 
+            4000 )
+  end
+  
+  def test_method_beets4
+    
+    @svc.xresult = nil
+    assert_nil( @test.beets( nil ) )
+    check( :CALL, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_beets, 
+            Array[ ValueFactoryTest::MF_e ], 
+            Array[ nil ] , 
+            ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_beets, 
+            4000 )
+  end
+  
+  
+  
+  def check( what, type, fields, objects, resultType, timeout )
+    assert_same( what, @svc.what )
+    assert_same( type, @svc.xmsg.getType() )
+    
+    n = fields.length
+    assert_equal( n, objects.length )
+    assert_equal( n, @svc.xmsg.size )
+    
+    for i in 0...n 
+      f = fields[i]
+      assert_equal( objects[i], @svc.xmsg[f] )
+    end
+    
+    assert_same( resultType, @svc.xresponseType )
+    assert_same( ValueFactoryTest::MF_result, @svc.xresponseField )
+    assert_equal( timeout, @svc.xtimeout )
+  end
+  
+  class MyDeliveryService 
+    include DeliveryService
+    include Test::Unit::Assertions
+    
+    attr :what, true 
+    attr :xmsg, true 
+    attr :xresponseType, true 
+    attr :xresponseField, true 
+    attr :xtimeout, true 
+    attr :xresult, true 
+    attr :xmb, true
+    
+    def initialize()
+      @what = EtchEnum.enum2
+    end
+    
+    def clear()
+      
+    end
+    
+    def send( msg )
+      assert_nil( @what )
+      @what = :SEND
+      @xmsg = msg
+    end
+    
+    def begincall( msg )
+    
+      assert_nil( @what )
+      @what = :BEGINCALL
+      @xmsg = msg
+      # TODO: Uncomment this when PlainMailbox is done !
+      # @xmb = PlainMailbox.new( nil, 0, 0, 0, 1)
+      return @xmb
+    end
+    
+    def endvoidcall( mb, responseType, responseField, timeout )
+      
+      assert_same( :BEGINCALL, @what )
+      assert_same( mb, @xmb )
+      @what = :VOIDCALL
+      @xmb = nil
+      @xresponseType = responseType
+      @xresponseField = responseField
+      @xtimeout = timeout
+      if ( @xresult != nil && @xresult.kind_of?( Exception ) )
+        raise @xresult
+      end
+      assert_nil( @xresult )
+    end
+    
+    def endcall( mb, responseType, responseField, timeout )
+
+      assert_same( :BEGINCALL, @what )
+      assert_same( mb, @xmb )
+      @what = :CALL
+      @xmb = nil
+      @xresponseType = responseType
+      @xresponseField = responseField
+      @xtimeout = timeout
+      if ( @xresult.kind_of?( Exception ) )
+        raise @xresult 
+      end
+      return @xresult
+    end
+    
+    def shutdownOutput()
+      assert_nil( @what )
+      what = :SHUTDOWNOUTPUT
+    end
+    
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/idl/test/test_stub_test_server.rb b/binding-ruby/src/main/ruby/idl/test/test_stub_test_server.rb
new file mode 100644
index 0000000..3103475
--- /dev/null
+++ b/binding-ruby/src/main/ruby/idl/test/test_stub_test_server.rb
@@ -0,0 +1,196 @@
+require 'test/unit'
+require 'etch/bindings/ruby/support/delivery_service'
+require 'etch/bindings/ruby/idl/test/RemoteTest'
+require 'etch/bindings/ruby/idl/test/StubTest'
+require 'etch/bindings/ruby/idl/test/ValueFactoryTest'
+require 'etch/bindings/ruby/idl/test/fake_test'
+require 'etch/bindings/ruby/support/message_source'
+require 'etch/bindings/ruby/msg/message'
+
+class TestStubTestServer < Test::Unit::TestCase
+  
+  
+  def setup
+    @test = FakeTest.new
+    @vf = ValueFactoryTest.new
+    @stub = StubTest.new( @test, nil, nil )
+    @src = MyMessageSource.new
+  end
+  
+  def test_method_nothing
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_nothing, @vf )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_nothing )
+    assert_equal( 0, @src.xreply.size )
+  end
+  
+  def test_method_incr1
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_incr, @vf )
+    msg.store( ValueFactoryTest::MF_x, 3 )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_incr )
+    assert_equal( 1, @src.xreply.size )
+    assert_equal( 4, @src.xreply[ ValueFactoryTest::MF_result ] )
+  end
+  
+  def test_method_incr2
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_incr, @vf )
+    # msg.store( ValueFactoryTest::MF_x, 3 )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_incr )
+    assert_equal( 1, @src.xreply.size )
+    o = @src.xreply[ ValueFactoryTest::MF_result ] 
+    assert( o.kind_of?( Exception ) )
+  end
+  
+  def test_method_sub
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_sub, @vf )
+    msg.store( ValueFactoryTest::MF_x, 7 )
+    msg.store( ValueFactoryTest::MF_y, 3 )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_sub )
+    assert_equal( 1, @src.xreply.size )
+    assert_equal( 4, @src.xreply[ ValueFactoryTest::MF_result ] )
+  end
+  
+  def test_method_sum
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_sum, @vf )
+    msg.store( ValueFactoryTest::MF_x, Array[ 1, 2, 3, 7, 11 ] )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_sum )
+    assert_equal( 1, @src.xreply.size )
+    assert_equal( 24, @src.xreply[ ValueFactoryTest::MF_result ] )
+  end
+  
+  def test_method_trans1
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_trans, @vf )
+    msg.store( ValueFactoryTest::MF_e, Test::E1::A )
+    msg.store( ValueFactoryTest::MF_x, 5 )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_trans )
+    assert_equal( 1, @src.xreply.size )
+    assert_equal( 2, @src.xreply[ ValueFactoryTest::MF_result ] )
+  end
+  
+  def test_method_trans2
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_trans, @vf )
+    msg.store( ValueFactoryTest::MF_e, Test::E1::B )
+    msg.store( ValueFactoryTest::MF_x, 5 )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_trans )
+    assert_equal( 1, @src.xreply.size )
+    assert_equal( 10, @src.xreply[ ValueFactoryTest::MF_result ] )
+  end
+  
+  def test_method_trans3
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_trans, @vf )
+    msg.store( ValueFactoryTest::MF_e, Test::E1::C )
+    msg.store( ValueFactoryTest::MF_x, 5 )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_trans )
+    assert_equal( 1, @src.xreply.size )
+    assert_equal( 12, @src.xreply[ ValueFactoryTest::MF_result ] )
+  end
+
+  def test_method_dist1
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_dist, @vf )
+    msg.store( ValueFactoryTest::MF_a, Test::S1.new( 1, 1, 1 ) )
+    msg.store( ValueFactoryTest::MF_b, Test::S1.new( 0, 0, 0 ) )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_dist )
+    assert_equal( 1, @src.xreply.size )
+    assert_equal( Math.sqrt( 3 ), @src.xreply[ ValueFactoryTest::MF_result ] )
+  end
+
+  def test_method_dist2
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_dist, @vf )
+    msg.store( ValueFactoryTest::MF_a, Test::S1.new( 1, 2, 3 ) )
+    msg.store( ValueFactoryTest::MF_b, Test::S1.new( 6, 5, 4 ) )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_dist )
+    assert_equal( 1, @src.xreply.size )
+    assert_equal( Math.sqrt( 35 ), @src.xreply[ ValueFactoryTest::MF_result ] )
+  end
+
+  def test_method_fill
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_fill, @vf )
+    msg.store( ValueFactoryTest::MF_n, 4 )
+    msg.store( ValueFactoryTest::MF_x, 3 )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_fill )
+    assert_equal( 1, @src.xreply.size )
+    x = @src.xreply[ ValueFactoryTest::MF_result ]
+    assert_not_nil( x )
+    assert_equal( 4, x.length )
+    x.each { |value| assert_equal( 3, value ) }
+  end
+
+  def test_method_blow
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_blow, @vf )
+    msg.store( ValueFactoryTest::MF_msg, "foo" )
+    msg.store( ValueFactoryTest::MF_code, 23 )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_blow )
+    assert_equal( 1, @src.xreply.size )
+    e = @src.xreply[ ValueFactoryTest::MF_result ]
+    assert_not_nil( e )
+    assert_equal( "foo", e.msg )
+    assert_equal( 23, e.code )
+  end
+  
+  def test_method_beets1
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_beets, @vf )
+    msg.store( ValueFactoryTest::MF_e, Test::E1::A )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_beets )
+    assert_equal( 1, @src.xreply.size )
+    o = @src.xreply[ ValueFactoryTest::MF_result ]
+    assert_equal( 5, o )
+  end
+  
+  def test_method_beets2
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_beets, @vf )
+    msg.store( ValueFactoryTest::MF_e, Test::E1::B )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_beets )
+    assert_equal( 1, @src.xreply.size )
+    o = @src.xreply[ ValueFactoryTest::MF_result ]
+    assert_equal( Test::Excp3, o.class )
+  end
+  
+  def test_method_beets3
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_beets, @vf )
+    msg.store( ValueFactoryTest::MF_e, Test::E1::C )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_beets )
+    assert_equal( 1, @src.xreply.size )
+    o = @src.xreply[ ValueFactoryTest::MF_result ]
+    assert_equal( Test::Excp4, o.class )
+  end
+  
+  
+  def test_method_beets4
+    msg = Message.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_beets, @vf )
+    msg.store( ValueFactoryTest::MF_e, nil )
+    @stub.message( @src, nil, msg )
+    @src.xreply.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_beets )
+    assert_equal( 1, @src.xreply.size )
+    o = @src.xreply[ ValueFactoryTest::MF_result ]
+    assert_nil( o )
+  end
+  
+  
+
+  class MyMessageSource 
+    include MessageSource
+    include Test::Unit::Assertions
+    
+    attr :xreply, true
+    
+    def message( recipient, msg )
+      assert_nil( recipient)
+      assert_nil( @xreply )
+      @xreply = msg
+    end
+  end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/idl/test/test_test.rb b/binding-ruby/src/main/ruby/idl/test/test_test.rb
new file mode 100644
index 0000000..6798cc3
--- /dev/null
+++ b/binding-ruby/src/main/ruby/idl/test/test_test.rb
@@ -0,0 +1,214 @@
+require 'test/unit'
+require 'etch/bindings/ruby/support/delivery_service'
+require 'etch/bindings/ruby/idl/test/RemoteTest'
+require 'etch/bindings/ruby/idl/test/fake_test'
+require 'etch/bindings/ruby/idl/test/ValueFactoryTest'
+require 'etch/bindings/ruby/msg/type'
+require 'etch/bindings/ruby/msg/field'
+
+class TestTest < Test::Unit::TestCase
+
+  def setup
+    @test = FakeTest.new
+  end
+  
+  def test_enum_E1
+    # see implementation of EtchEnum
+    assert_equal( 3, Test::E1.constants.length )
+    assert_not_nil( Test::E1::A )
+    assert_not_nil( Test::E1::B )
+    assert_not_nil( Test::E1::C )
+  end
+  
+  def test_struct_S1
+    s = Test::S1.new( 1, 2, 3 )
+    assert_equal( 1, s.x )
+    assert_equal( 2, s.y )
+    assert_equal( 3, s.z )
+    
+    s = Test::S1.new( nil, nil, nil )
+    assert_nil( s.x )
+    assert_nil( s.y )
+    assert_nil( s.z )
+    
+    s = Test::S1.new()
+    assert_nil( s.x )
+    assert_nil( s.y )
+    assert_nil( s.z )
+    
+    s.x = 4 
+    s.y = 5 
+    s.z = 6 
+    
+    assert_equal( 4, s.x )
+    assert_equal( 5, s.y )
+    assert_equal( 6, s.z )
+    
+    s.x = nil
+    assert_nil( s.x )
+    
+    s.x = 7
+    assert_equal( 7, s.x )
+  end
+  
+  def test_excp_Excp1
+    e = Test::Excp1.new( "foo", 23 )
+    assert_equal( "foo", e.msg )
+    assert_equal( 23, e.code )
+    
+    e = Test::Excp1.new( nil, nil )
+    assert_nil( e.msg )
+    assert_nil( e.code )
+    
+    e = Test::Excp1.new()
+    assert_nil( e.msg )
+    assert_nil( e.code )
+    
+    e.msg = "bar"
+    e.code = 24
+    assert_equal( "bar", e.msg )
+    assert_equal( 24, e.code )
+  
+    e.msg = nil
+    e.code = nil
+    assert_nil( e.msg )
+    assert_nil( e.code )
+    
+    assert( e.kind_of?( Exception ) )
+
+  end
+  
+  def test_excp_Excp3
+  
+    e = Test::Excp3.new
+    assert( e.kind_of?( Exception ) )
+  end
+  
+  def test_excp_Excp4
+  
+    e = Test::Excp4.new
+    assert( e.kind_of?( Exception ) )
+  end
+  
+  def test_method_nothing
+    @test.nothing
+  end
+  
+  def test_method_incr1
+    assert_equal( 2, @test.incr( 1 ) )
+  end
+  
+  def test_method_incr2
+    assert_equal( 3, @test.incr( 2 ) )
+  end
+  
+  def test_method_incr3
+    assert_equal( -1, @test.incr( -2 ) )
+  end
+  
+  def test_method_sub1
+    assert_equal( 5, @test.sub( 7, 2 ) )
+  end
+  
+  def test_method_sub2
+    assert_equal( 8, @test.sub( 23, 15 ) )
+  end
+  
+  def test_method_sub3
+    assert_equal( -5, @test.sub( 2, 7 ) )
+  end
+  
+  def test_method_sum
+    assert_equal( 24, @test.sum( Array[ 1, 2, 3, 7, 11 ] ) )
+  end
+  
+  def test_method_trans1
+    assert_equal( 2, @test.trans( Test::E1::A, 5 ) )
+  end
+  
+  def test_method_trans2
+    assert_equal( 10, @test.trans( Test::E1::B, 5 ) )
+  end
+  
+  def test_method_trans3
+    assert_equal( 12, @test.trans( Test::E1::C, 5 ) )
+  end
+  
+  def test_method_dist1
+    assert_equal( Math.sqrt( 3 ), @test.dist( Test::S1.new( 1, 1, 1 ), Test::S1.new( 0, 0, 0 ) ) )
+  end
+  
+  def test_method_dist2
+    assert_equal( Math.sqrt( 35 ), @test.dist( Test::S1.new( 1, 2, 3 ), Test::S1.new( 6, 5, 4 ) ) )
+  end
+  
+  def test_method_dist3
+    assert_equal( Math.sqrt( 56 ), @test.dist( Test::S1.new( 1, 2, 3 ), Test::S1.new( -1, -2, -3 ) ) )
+  end
+  
+  def test_method_fill1
+    x = @test.fill( 0, 1 )
+    assert_equal( 0, x.length )
+    x.each { |value| assert_equal( 1, value ) }
+  end
+  
+  def test_method_fill2
+    x = @test.fill( 1, 2 )
+    assert_equal( 1, x.length )
+    x.each { |value| assert_equal( 2, value ) }
+  end
+  
+  def test_method_fill3
+    x = @test.fill( 2, 3 )
+    assert_equal( 2, x.length )
+    x.each { |value| assert_equal( 3, value ) }
+  end
+  
+  def test_method_blow1
+    begin
+      @test.blow( "foo", 2 )
+      flunk( "did not throw" )
+    rescue Test::Excp1 => e
+      assert_equal( "foo", e.msg )
+      assert_equal( 2, e.code )
+    end
+  end
+  
+  def test_method_blow2
+    begin
+      @test.blow( "bar", 3 )
+      flunk( "did not throw" )
+    rescue Test::Excp1 => e
+      assert_equal( "bar", e.msg )
+      assert_equal( 3, e.code )
+    end
+  end
+  
+  def test_method_beets1
+    assert_equal( 5, @test.beets( Test::E1::A ) )
+  end
+  
+  def test_method_beets2
+    begin
+      @test.beets( Test::E1::B )
+      flunk( "did not throw" )
+    rescue Test::Excp3 => e
+      assert( true )
+    end
+  end
+  
+   
+  def test_method_beets3
+    begin
+      @test.beets( Test::E1::C )
+      flunk( "did not throw" )
+    rescue Test::Excp4 => e
+      assert( true )
+    end
+  end
+  
+  def test_method_beets4
+    assert_nil( @test.beets( nil ) )
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/idl/test/test_value_factory_test.rb b/binding-ruby/src/main/ruby/idl/test/test_value_factory_test.rb
new file mode 100644
index 0000000..f145f26
--- /dev/null
+++ b/binding-ruby/src/main/ruby/idl/test/test_value_factory_test.rb
@@ -0,0 +1,253 @@
+require 'test/unit'
+require 'etch/bindings/ruby/support/delivery_service'
+require 'etch/bindings/ruby/idl/test/RemoteTest'
+require 'etch/bindings/ruby/idl/test/ValueFactoryTest'
+require 'etch/bindings/ruby/msg/type'
+require 'etch/bindings/ruby/msg/field'
+
+class TestValueFactoryTest < Test::Unit::TestCase
+
+  
+  def setup
+    @vf = ValueFactoryTest.new  
+  end
+  
+  def test_E1
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_E1 )
+    
+    checkField( ValueFactoryTest::MF_A )
+    checkField( ValueFactoryTest::MF_B )
+    checkField( ValueFactoryTest::MF_C )
+  end
+  
+  def test_E1_export
+    testEnumExport( Test::E1::A, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_E1, 
+                    ValueFactoryTest::MF_A )
+    testEnumExport( Test::E1::B, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_E1, 
+                    ValueFactoryTest::MF_B )
+    testEnumExport( Test::E1::C, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_E1, 
+                    ValueFactoryTest::MF_C )
+  end
+  
+  def test_E1_import
+    testEnumImport( Test::E1::A, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_E1, 
+                    ValueFactoryTest::MF_A )
+    testEnumImport( Test::E1::B, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_E1, 
+                    ValueFactoryTest::MF_B )
+    testEnumImport( Test::E1::C, ValueFactoryTest::MT_etch_bindings_ruby_test_Test_E1, 
+                    ValueFactoryTest::MF_C )                    
+  end
+  
+  def test_S1
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_S1 )
+    
+    checkField( ValueFactoryTest::MF_x )
+    checkField( ValueFactoryTest::MF_y )
+    checkField( ValueFactoryTest::MF_z )  
+  end
+  
+  def test_S1_export
+    sv = @vf.exportCustomValue( Test::S1.new( 19, 23, 29 ) )
+    sv.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_S1 )
+    assert_equal( 3, sv.size )
+    assert_equal( 19, sv[ ValueFactoryTest::MF_x ] )
+    assert_equal( 23, sv[ ValueFactoryTest::MF_y ] )
+    assert_equal( 29, sv[ ValueFactoryTest::MF_z ] )
+  end
+  
+  def test_S1_import
+
+    sv = StructValue.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_S1 )
+    sv.store( ValueFactoryTest::MF_x, 101 )
+    sv.store( ValueFactoryTest::MF_y, 103 )
+    sv.store( ValueFactoryTest::MF_z, 107 )
+    s = @vf.importCustomValue( sv )
+    assert_equal( 101, s.x )
+    assert_equal( 103, s.y )
+    assert_equal( 107, s.z )
+  end
+  
+  def test_S2
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_S2 )
+    
+    checkField( ValueFactoryTest::MF_a )
+    checkField( ValueFactoryTest::MF_b )
+    checkField( ValueFactoryTest::MF_c )  
+  end
+  
+  def test_S2_export
+    
+    a = Test::S1.new( 21, 22, 23 )
+    b = Test::S1.new( 31, 32, 33 )
+    c = Test::E1::A
+    
+    sv = @vf.exportCustomValue( Test::S2.new( a, b, c ) )
+    sv.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_S2 )
+    assert_equal( 3, sv.size )
+    assert_equal( a, sv[ ValueFactoryTest::MF_a ] )
+    assert_equal( b, sv[ ValueFactoryTest::MF_b ] )
+    assert_equal( c, sv[ ValueFactoryTest::MF_c ] )
+  end
+  
+  def test_S2_import
+
+    sv = StructValue.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_S2 )
+    
+    sv.store( ValueFactoryTest::MF_a, Test::S1.new( 21, 22, 23 ) )
+    sv.store( ValueFactoryTest::MF_b, Test::S1.new( 31, 32, 33 ) )
+    sv.store( ValueFactoryTest::MF_c, Test::E1::A )
+    
+    s = @vf.importCustomValue( sv )
+    assert_equal( 21, s.a.x )
+    assert_equal( 22, s.a.y )
+    assert_equal( 23, s.a.z )
+    assert_equal( 31, s.b.x )
+    assert_equal( 32, s.b.y )
+    assert_equal( 33, s.b.z )
+    assert_equal( Test::E1::A, s.c )
+  end 
+  
+  def test_excps
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_Excp1 )
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_Excp3 )
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_Excp4 )
+    
+    checkField( ValueFactoryTest::MF_msg )
+    checkField( ValueFactoryTest::MF_code )
+  end
+  
+  def test_excps_export
+    sv = @vf.exportCustomValue( Test::Excp1.new( "abc", 23 ) )
+    sv.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_Excp1 )
+    assert_equal( 2, sv.size )
+    assert_equal( "abc", sv[ ValueFactoryTest::MF_msg ] )
+    assert_equal( 23, sv[ ValueFactoryTest::MF_code ] )
+    
+    sv = @vf.exportCustomValue( Test::Excp3.new() )
+    sv.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_Excp3 )
+    assert_equal( 0, sv.size )
+    
+    sv = @vf.exportCustomValue( Test::Excp4.new() )
+    sv.checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_Excp4 )
+    assert_equal( 0, sv.size )
+    
+  end
+  
+  def test_expcs_import
+    sv = StructValue.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_Excp1 )
+    sv.store( ValueFactoryTest::MF_msg, "def" )
+    sv.store( ValueFactoryTest::MF_code, 29 )
+    e1 = @vf.importCustomValue( sv )
+    assert_equal( "def", e1.msg )
+    assert_equal( 29, e1.code )
+    e1 = nil 
+    
+    sv = StructValue.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_Excp3 )
+    e3 = @vf.importCustomValue( sv )
+    assert_not_nil( e3 )
+    e3 = nil 
+    
+    sv = StructValue.new( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_Excp4 )
+    e4 = @vf.importCustomValue( sv )
+    assert_not_nil( e4 )
+    e4 = nil 
+  end
+  
+  def test_method_nothing
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_nothing )
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_nothing )
+    checkField( ValueFactoryTest::MF_result )
+  end
+  
+  def test_method_incr
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_incr )
+    checkField( ValueFactoryTest::MF_x ) 
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_incr )
+    checkField( ValueFactoryTest::MF_result )
+  end
+  
+  def test_method_sub
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_sub )
+    checkField( ValueFactoryTest::MF_x ) 
+    checkField( ValueFactoryTest::MF_y )
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_sub )
+    checkField( ValueFactoryTest::MF_result )
+  end
+  
+  def test_method_sum
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_sum )
+    checkField( ValueFactoryTest::MF_x ) 
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_sum )
+    checkField( ValueFactoryTest::MF_result )
+  end
+  
+  def test_method_trans
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_trans )
+    checkField( ValueFactoryTest::MF_e ) 
+    checkField( ValueFactoryTest::MF_y )
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_trans )
+    checkField( ValueFactoryTest::MF_result )
+  end
+  
+  def test_method_dist
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_dist )
+    checkField( ValueFactoryTest::MF_a ) 
+    checkField( ValueFactoryTest::MF_b )
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_dist )
+    checkField( ValueFactoryTest::MF_result )
+  end
+  
+  def test_method_fill
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_fill )
+    checkField( ValueFactoryTest::MF_n ) 
+    checkField( ValueFactoryTest::MF_x )
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_fill )
+    checkField( ValueFactoryTest::MF_result )
+  end
+  
+  def test_method_blow
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_blow )
+    checkField( ValueFactoryTest::MF_msg ) 
+    checkField( ValueFactoryTest::MF_code )
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_blow )
+    checkField( ValueFactoryTest::MF_result )
+  end
+  
+  def test_method_beets
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test_beets )
+    checkField( ValueFactoryTest::MF_e )
+    checkType( ValueFactoryTest::MT_etch_bindings_ruby_test_Test__result_beets )
+    checkField( ValueFactoryTest::MF_result )
+  end
+  
+  
+  
+  #
+  # utility methods
+  # 
+  def checkType( t )
+    assert_not_nil( t )
+    assert_same( Type, t.class )
+    assert_same( t, @vf.getType( t.xid ) )
+  end
+  
+  def checkField( f )
+    assert_not_nil( f )
+    assert_same( Field, f.class )
+    assert_same( f, @vf.getField( f.xid ) )
+  end
+  
+  def testEnumExport( e, t, f )
+    sv = @vf.exportCustomValue( e )
+    sv.checkType( t )
+    assert_equal( 1, sv.size )
+    assert( sv[f] )
+  end
+  
+  def testEnumImport( e, t, f )
+    sv = StructValue.new( t )
+    sv.store( f, true )
+    a = @vf.importCustomValue( sv )
+    assert_same( e, a )
+  end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/msg/array_element.rb b/binding-ruby/src/main/ruby/msg/array_element.rb
new file mode 100644
index 0000000..602b5bd
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/array_element.rb
@@ -0,0 +1,9 @@
+# package 'etch/bindings/ruby/msg'
+
+# Holder for a value from an array element sequence.
+class ArrayElement
+
+  # The array element value (Object)
+  attr :value, true
+  
+end
diff --git a/binding-ruby/src/main/ruby/msg/array_value.rb b/binding-ruby/src/main/ruby/msg/array_value.rb
new file mode 100644
index 0000000..05710b7
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/array_value.rb
@@ -0,0 +1,68 @@
+# package 'etch/bindings/ruby/msg'
+
+class ArrayValue < Array
+	
+  # Adds many values to the array value
+  # param -> values = set of values as varargs
+  
+  def addMany( *values )
+    values.each { |value| self << value }
+  end
+  
+  # Constructs a new array value and adds it to the end of 
+  # this array value.
+  # returns -> newly constructed array value
+  
+  def addArrayValue
+		av = ArrayValue.new
+		self << av
+		return av
+	end
+	
+  # Constructs a new struct value and adds it to the end of 
+  # this array value.
+  # param -> type = the type of the structure
+  # returns -> a newly constructed structvalue
+  
+	def addStructValue( type )
+		sv = StructValue.new( type )
+		self << sv
+		return sv
+	end
+	
+  # Reads an array and all of its values.
+  # param -> tdi = the tagged data input to read from.
+  # return -> an array value read from the tagged data input.
+  
+	def self.read( tdi )
+		array = tdi.startArray
+		array.readValues( tdi )
+		tdi.endArray( array )
+		return array
+	end
+	
+  # Writes an array and all of its values.
+  # param -> tdo the tagged data output to write to.
+  
+	def write( tdo )
+		tdo.startArray( self )
+		writeValues( tdo )
+		tdo.endArray( self )
+	end
+	
+  # Reads the values of the array. Does not clear the array first.
+  # param -> tdi = the tagged data input to read from.
+  
+	def readValues( tdi )
+		ae = ArrayElement.new
+		while tdi.readArrayElement( ae )
+			self << ae.value
+		end
+	end
+	
+  # Writes the values of the array.
+  # param -> tdo = the tagged data output to write to.
+	def writeValues( tdo )
+		each {|value| tdo.writeArrayElement( value )}
+	end
+end
diff --git a/binding-ruby/src/main/ruby/msg/field.rb b/binding-ruby/src/main/ruby/msg/field.rb
new file mode 100644
index 0000000..9ed7e2e
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/field.rb
@@ -0,0 +1,25 @@
+# package 'etch/bindings/ruby/msg'
+require 'etch/bindings/ruby/msg/id_name'
+
+# Field is an IdName which denotes a field of a struct
+# or message (i.e., a key for a value).
+
+class Field < IdName
+  
+  # Constructs the Field.
+  # @param id the id of the field.
+  # @param name the name of the field.
+  
+  def initialize(id, name)
+    super(id, name)
+  end
+  
+  # Constructs the Field, computing the appropriate value
+  # for the id.
+  # @param name the name of the field.
+  
+  # def initialize(name)
+  #  super(name)
+  # end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/msg/id_name.rb b/binding-ruby/src/main/ruby/msg/id_name.rb
new file mode 100644
index 0000000..1c2a1a2
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/id_name.rb
@@ -0,0 +1,80 @@
+# package 'etch/bindings/ruby/msg'
+
+# An IdName is a base class for Field or Type. It is used
+# to bind together a type or field name with the associated id. The id
+# is used for certain operations, such as the key in a Map, comparisons,
+# and binary encoding on the wire, while the name is used for display.
+
+class IdName
+  attr :xid, true
+  attr :name, true
+  
+  # Constructs the IdName.
+  # @param id the id for the name 
+  # @param name the name of the item.
+	def initialize( xid, name )
+    xid = IdName.hashit( name ) if xid.nil?
+		@xid = xid
+		@name = name
+	end
+	
+  # def initialize( name )
+  #  initialize( name, hashit( name ) )
+  # end
+  
+	def to_s
+		return @name
+	end
+	
+	def hash
+		return @xid.hash
+	end
+  
+  def ==(o)
+    
+    # check for nil first
+    if ( o == nil )
+      if ( self.class == NilClass )
+        return true
+      else 
+        return false
+      end
+      return true
+    end
+    
+    # overload == 
+    return @xid == o.xid
+  end
+  
+	def eql?( o )
+  
+    # check for nil first
+    if ( o == nil )
+      if ( self.class == NilClass )
+        return true
+      else 
+        return false
+      end
+      return true
+    end
+    
+		return @xid.eql?( o.xid )
+	end
+	
+  # Computes the hash value of the name to be used as the id when
+  # constructing an IdName.
+  # @param name the name of the type or field.
+  # @return a hash of name in the unicode character encoding which is
+  # very likely to be unique over reasonable name spaces. Collisions
+  # should be very unlikely as they will force the user to change the
+  # name.
+	def self.hashit( name )
+		r = 5381
+		name.each_byte {|c| r = c + (r << 6) + (r << 16) - r }
+		r = r % 4294967296
+        if r > 2147483647 then
+        	r = r - 4294967296
+        end
+		return r
+	end
+end
diff --git a/binding-ruby/src/main/ruby/msg/mailbox.rb b/binding-ruby/src/main/ruby/msg/mailbox.rb
new file mode 100644
index 0000000..3e8035a
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/mailbox.rb
@@ -0,0 +1,27 @@
+# package 'etch/bindings/ruby/msg'
+
+module Mailbox
+	def getMessageId
+		raise "subclasser responsibility"
+	end
+	
+	def deliver( msg )
+		raise "subclasser responsibility"
+	end
+	
+	def deliver( msg, maxDelay )
+		raise "subclasser responsibility"
+	end
+	
+	def read
+		raise "subclasser responsibility"
+	end
+	
+	def read( maxDelay )
+		raise "subclasser responsibility"
+	end
+	
+	def close
+		raise "subclasser responsibility"
+	end
+end
diff --git a/binding-ruby/src/main/ruby/msg/message.rb b/binding-ruby/src/main/ruby/msg/message.rb
new file mode 100644
index 0000000..ba111c7
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/message.rb
@@ -0,0 +1,89 @@
+# package 'etch/bindings/ruby/msg'

+

+require 'etch/bindings/ruby/msg/struct_value'

+

+# A message is modeled as a command and some argments. 

+# The command is an arbitrary integer value, and the 

+# arguments are key / value pairs, where the key is an 

+# arbitrary integer value and the value is any one of the

+# standard java objects, an ArrayValue, a StructValue, 

+# or any type which may be serialized by the ValueFactory.

+

+class Message < StructValue

+  attr :vf

+  

+  # Constructs the Message.

+  # @param vf the value factory

+  # 

+  def initialize( stype, vf )
+    super( stype )

+    @vf = vf
+  end

+  

+  def vf()

+    return @vf

+  end

+  

+  # Reads a Message from the tagged data input.

+  # @param tdi the tagged data input to read from.

+  # @return a Message read from the tagged data input.

+  

+  def self.read( tdi )

+    msg = tdi.startMessage()

+    msg.readKeysAndValues( tdi )

+    tdi.endMessage( msg )

+    return msg

+  end

+  

+  # Writes a message to the tagged data output

+  # @param tdo the tagged data output to write to.

+  # @throws IOException if there is a problem with the tagged data output.

+  

+  def writeMessage( tdo )

+    tdo.startMessage( self )

+    writeKeysAndValues( tdo )

+    tdo.endMessage( self )

+  end

+  

+  # Creates a message which is a reply to the current message.

+  # The current message's value factory is copied to the new

+  # message. The message-id of the current message (if any) is

+  # copied into the in-reply-to field of the new message.

+  # @param rType the type of the reply.

+  # @return a reply message.

+  #

+  def reply( rType ) # return Message

+    rmsg = Message.new( rType, @vf)

+    rmsg.setInReplyTo( getMessageId() )

+    return rmsg

+  end

+  

+  

+  # @return the connection specific unique identifier of this

+  # message, or null if there was no such identifier.

+  def getMessageId()

+    return @vf.getMessageId( self )

+  end

+  

+  # Sets the message-id field of this message.

+  # @param msgid the connection specific unique identifier of this

+  # message. Null if the message has not been sent yet. 

+  # NOTE: the send process overwrites any value the user might set 

+  # here. So don't bother trying to set it.

+  def setMessageId( msgid )

+    vf.setMessageId( self, msgid )

+  end

+  

+  # @return the message-id of the message that this is a response to.

+  # Null if this is an original message or if the original message did

+  # not have a message-id.

+  def getInReplyTo()

+    return vf.getInReplyTo( self )

+  end

+  

+  # Sets the in-reply-to field of this message.

+  # @param msgid the message-id of the message that this is a response to.

+  def setInReplyTo( msgid )

+    vf.setInReplyTo( self, msgid )

+  end
+end

diff --git a/binding-ruby/src/main/ruby/msg/struct_element.rb b/binding-ruby/src/main/ruby/msg/struct_element.rb
new file mode 100644
index 0000000..055fe35
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/struct_element.rb
@@ -0,0 +1,11 @@
+# package 'etch/bindings/ruby/msg'
+
+# Holder for a key / value pair from a struct element sequence.
+class StructElement
+
+  # Description of key (Field).
+	attr :key, true
+  
+  # Description of value (Object).
+  attr :value, true
+end
diff --git a/binding-ruby/src/main/ruby/msg/struct_value.rb b/binding-ruby/src/main/ruby/msg/struct_value.rb
new file mode 100644
index 0000000..2913587
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/struct_value.rb
@@ -0,0 +1,108 @@
+# package 'etch/bindings/ruby/msg'
+
+require 'etch/bindings/ruby/msg/struct_element'
+
+# A typed map of key/value pairs, where the type is a Type,
+# each key is a Field, and each value is of arbitrary type
+# chosen from the basic java types boolean, byte, short, int, long,
+# float, double, String, an array of those, the extended types
+# ArrayValue and StructValue, and specific types supported by
+# ValueFactory.
+ 
+# StructValue is not protected against concurrent access.
+#
+class StructValue < Hash
+	
+  attr :stype
+  
+  def initialize( stype )
+		@stype = stype
+	end
+	
+  def getType()
+    return @stype
+  end
+  
+  # Compares the type of this struct to another type.
+  # @param otherType the type to compare this type to.
+  # @return true if this struct is of the specified type.
+	def stype?( otherStype )
+		return @stype.eql?( otherStype )
+	end
+	
+  # Checks a struct for having the expected type.
+  # @param expectedType the expected type of this struct.
+  # @throws IllegalArgumentException if the type is not as expected.
+  #
+	def checkType( otherStype )
+    if !stype?( otherStype )
+      raise "type mismatch (got #{stype} wanted #{otherStype})" 
+    else
+      return true
+    end
+	end
+	
+  # Constructs a new array value and puts it into this struct value
+  # with the specified key.
+  # @param key the key of the newly constructed array value.
+  # @return a newly constructed array value.
+  #
+	def putArrayValue( key )
+		av = ArrayValue.new
+		store( key, av )
+		return av
+	end
+	
+  # Constructs a new struct value and puts it into this struct value
+  # with the specified key.
+  # @param key the key of the newly constructed struct value.
+  # @param sType the type of the structure.
+  # @return a newly constructed struct value.
+  #
+	def putStructValue( key, type )
+		sv = StructValue.new( type )
+		store( key, sv )
+		return sv
+	end
+	
+  # Reads the struct from the tagged data input.
+  # @param tdi the tagged data input to read from.
+  # @return a struct value read from the tagged data input.
+  # 
+	def self.read( tdi )
+		sv = tdi.startStruct
+		sv.readKeysAndValues( tdi )
+		tdi.endStruct( sv )
+    return sv
+	end
+	
+  # Writes a struct to the tagged data output.
+  # @param tdo the tagged data output to write to.
+  #
+	def writeStruct( tdo )
+		tdo.startStruct( self )
+		writeKeysAndValues( tdo )
+		tdo.endStruct( self )
+	end
+	
+  # Reads the key / value pairs and puts them in the struct.
+  # @param tdi the tagged data input to read from.
+  #
+	def readKeysAndValues( tdi )
+    se = StructElement.new
+		while tdi.readStructElement( se )
+			store( se.key, se.value )
+		end
+	end
+	
+  # Writes the key / value pairs.
+  # @param tdo the tagged data output to write to.
+  #
+	def writeKeysAndValues( tdo )
+		each{ |key, value| tdo.writeStructElement( key, value ) }
+	end
+	
+	def to_s
+		return "#{@stype}: "+to_a.join( ", " )
+	end
+end
diff --git a/binding-ruby/src/main/ruby/msg/tagged_data_input.rb b/binding-ruby/src/main/ruby/msg/tagged_data_input.rb
new file mode 100644
index 0000000..f4031e9
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/tagged_data_input.rb
@@ -0,0 +1,71 @@
+# package 'etch/bindings/ruby/msg'
+
+# A TaggedDataInputStream reads type tagged values from an input stream.
+module TaggedDataInput
+
+  # Starts reading a message from the stream.
+  # @return the message that we are reading. 
+  #
+	def startMessage( ms ) # returns Message
+		raise "subclasser responsibility"
+	end
+	
+  # Ends a message that we are reading.
+  # @param msg the message that has been read.
+  #
+	def endMessage( msg )
+		raise "subclasser responsibility"
+	end
+	
+  # Starts reading a struct from the stream.
+  # @return the struct that we are reading.
+  #
+	def startStruct # returns StructValue
+		raise "subclasser responsibility"
+	end
+	
+  # Reads the next key and value in the sequence of struct
+  # elements by stuffing the fields of the passed in StructElement.
+  # @param se place to store the read key and value.
+  # @return true if a key and value were read, false if there aren't any more
+  # key / value pairs.
+  #
+	def readStructElement( se ) # returns boolean
+		raise "subclasser responsibility"
+	end
+	
+  # Ends a struct that we are reading.
+  # @param struct the struct that we read.
+  #
+	def endStruct( struct )
+		raise "subclasser responsibility"
+	end
+	
+  # Starts reading an array from the stream.
+  # @return the array that we are reading.
+  #
+	def startArray # returns ArrayValue
+		raise "subclasser responsibility"
+	end
+	
+  # Reads the next value in the sequence of array elements by
+  # stuffing the fields of the passed in ArrayElement.
+  # @param ae place to store the read value.
+  # @return true if a value was read, false if there aren't any more.
+  #
+	def readArrayElement( ae ) # returns boolean
+		raise "subclasser responsibility"
+	end
+	
+  # Ends an array that we are reading.
+  # @param array the array that we read.
+  #
+	def endArray( array )
+		raise "subclasser responsibility"
+	end
+	
+  # Closes and discards any underlying resources.
+	def close()
+		raise "subclasser responsibility"
+	end
+end
diff --git a/binding-ruby/src/main/ruby/msg/tagged_data_output.rb b/binding-ruby/src/main/ruby/msg/tagged_data_output.rb
new file mode 100644
index 0000000..9bfc566
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/tagged_data_output.rb
@@ -0,0 +1,76 @@
+# package 'etch/bindings/ruby/msg'
+
+# A TaggedDataOutputStream writes type tagged data values to 
+# an output stream.
+#
+module TaggedDataOutput
+	
+  # Writes the beginning of message data. A message is also a struct,
+  # and so the type of the struct is written. The fields and
+  # values of the struct should be written using 
+  # writeStructElement(key, value)
+  # @param msg the message being written out.
+  #
+  def startMessage( msg )
+		raise "subclasser responsibility"
+	end
+	
+  # Writes the end of message data.
+  # @param msg the message that was written. 
+  #
+	def endMessage ( msg )
+		raise "subclasser responsibility"
+	end
+	
+  # Writes the beginning of struct data. The type of the struct is
+  # written. The fields and values of the struct are written
+  # using writeStructElement(key, value).
+  # @param struct the struct being written out.
+  #
+	def startStruct( struct )
+		raise "subclasser responsibility"
+	end
+	
+  # Writes a struct element with the specified key and value.
+  # @param key
+  # @param value
+  #
+	def writeStructElement( key, value )
+		raise "subclasser responsibility"
+	end
+	
+  # Writes the end of struct data.
+  # @param struct the struct that was written.
+  #
+	def endStruct( struct )
+		raise "subclasser responsibility"
+	end
+	
+  # Writes the beginning of array data. The values of the array
+  # should be written using writeArrayElement(value)
+  # @param array the array to be written.
+  #
+	def startArray( array )
+		raise "subclasser responsibility"
+	end
+	
+  # Writes an array element with the specified value.
+  # @param value
+  #
+	def writeArrayElement( value )
+		raise "subclasser responsibility"
+	end
+	
+  # Writes the end of array data.
+  # @param array the array that was written.
+  #
+	def endArray( array )
+		raise "subclasser responsibility"
+	end
+	
+  # Closes and releases any resources.
+  #
+	def close
+		raise "subclasser responsibility"
+	end
+end
diff --git a/binding-ruby/src/main/ruby/msg/test/test_array_value.rb b/binding-ruby/src/main/ruby/msg/test/test_array_value.rb
new file mode 100644
index 0000000..2c26860
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/test/test_array_value.rb
@@ -0,0 +1,193 @@
+require 'test/unit'
+require 'etch/bindings/ruby/msg/array_element'
+require 'etch/bindings/ruby/msg/array_value'
+require 'etch/bindings/ruby/msg/id_name'
+require 'etch/bindings/ruby/msg/struct_value'
+require 'etch/bindings/ruby/msg/tagged_data_input'
+require 'etch/bindings/ruby/msg/tagged_data_output'
+
+class TestArrayValue < Test::Unit::TestCase
+  def testAddArrayValue
+    av = ArrayValue.new
+    assert( av.empty? )
+    assert_equal( 0, av.length )
+    
+    av1 = av.addArrayValue
+    assert_not_nil( av1 )
+    assert_not_same( av, av1 )
+    assert_instance_of( ArrayValue, av1 )
+    assert( !av.empty? )
+    assert_equal( 1, av.length )
+    assert_same( av1, av[0] )
+    
+    av2 = av.addArrayValue
+    assert_not_nil( av2 )
+    assert_not_same( av, av2 )
+    assert_not_same( av1, av2 )
+    assert_instance_of( ArrayValue, av2 )
+    assert( !av.empty? )
+    assert_equal( 2, av.length )
+    assert_same( av1, av[0] )
+    assert_same( av2, av[1] )
+  end
+  
+  def testAddStructValue
+    av = ArrayValue.new
+    assert_equal( 0, av.length )
+    
+    mt1 = IdName.new( 1, "foo" )
+    mt2 = IdName.new( 2, "bar" )
+    
+    sv1 = av.addStructValue( mt1 )
+    assert_not_nil( sv1 )
+    assert_not_same( av, sv1 )
+    assert_instance_of( StructValue, sv1 )
+    assert_same( mt1, sv1.stype )
+    assert( !av.empty? )
+    assert_equal( 1, av.length )
+    assert_same( sv1, av[0] )
+    
+    sv2 = av.addStructValue( mt2 )
+    assert_not_nil( sv2 )
+    assert_not_same( av, sv2 )
+    assert_not_same( sv1, sv2 )
+    assert_instance_of( StructValue, sv2 )
+    assert_same( mt2, sv2.stype )
+    assert( !av.empty? )
+    assert_equal( 2, av.length )
+    assert_same( sv1, av[0] )
+    assert_same( sv2, av[1] )
+  end
+  
+  def testRead
+    readHelper
+    readHelper( 1 )
+    readHelper( 2, 3.3 )
+    readHelper( 4, true, 6 )
+    readHelper( "a", "b", "c", "d" )
+  end
+  
+  def testWrite
+    writeHelper
+    writeHelper( 1 )
+    writeHelper( 2, 3.3 )
+    writeHelper( 4, true, 6 )
+    writeHelper( "a", "b", "c", "d" )
+  end
+  
+  def readHelper( *vals )
+    tdi = FakeTdi.new( vals )
+    av = ArrayValue.read( tdi )
+    assert_instance_of( ArrayValue, av )
+    tdi.close
+  end
+  
+  def writeHelper( *vals )
+    av = ArrayValue.new
+    vals.each {|v| av << v}
+    tdo = FakeTdo.new( vals )
+    av.write( tdo )
+    tdo.close()
+  end
+end
+
+class FakeTdo
+  include TaggedDataOutput
+  include Test::Unit::Assertions
+  
+  def initialize( vals )
+    @vals = vals
+    @started = false
+    @ended = false
+  end
+  
+  def startArray( array )
+    assert( !@started )
+    assert( !@ended )
+    assert_not_nil( array )
+    
+    @started = true
+    @xarray = array
+    @list = Array.new
+  end
+  
+  def writeArrayElement( value )
+    assert( @started )
+    assert( !@ended )
+    
+    @list << value
+  end
+  
+  def endArray( array )
+    assert( @started )
+    assert( !@ended )
+    assert_same( @xarray, array )
+    
+    @ended = true
+  end
+  
+  def close
+    assert( @started )
+    assert( @ended )
+    assert_equal( @vals.length, @list.length )
+    assert_equal( @vals, @list )
+  end
+end
+
+class FakeTdi
+  include TaggedDataInput
+  include Test::Unit::Assertions
+  
+  def initialize( vals )
+    @vals = vals
+    @started = false
+    @done = false
+    @ended = false
+  end
+  
+  def startArray
+    assert( !@started )
+    assert( !@done )
+    assert( !@ended )
+    
+    @started = true
+    @xarray = ArrayValue.new
+    @index = 0
+    
+    return @xarray
+  end
+  
+  def readArrayElement( ae )
+    assert( @started )
+    assert( !@done )
+    assert( !@ended )
+    assert( @index <= @vals.length )
+    
+    if @index < @vals.length
+      ae.value = @vals[@index]
+      @index += 1
+      return true
+    end
+    
+    @done = true
+    return false
+  end
+  
+  def endArray( array )
+    assert( @started )
+    assert( @done )
+    assert( !@ended )
+    assert_same( @xarray, array )
+    
+    @ended = true
+  end
+  
+  def close
+    assert( @started )
+    assert( @done )
+    assert( @ended )
+    
+    assert_equal( @vals.length, @xarray.length )
+    assert_equal( @vals, @xarray )
+  end
+end
diff --git a/binding-ruby/src/main/ruby/msg/test/test_id_name.rb b/binding-ruby/src/main/ruby/msg/test/test_id_name.rb
new file mode 100644
index 0000000..379c12f
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/test/test_id_name.rb
@@ -0,0 +1,58 @@
+require 'test/unit'
+require 'etch/bindings/ruby/msg/id_name'
+
+class TestIdName < Test::Unit::TestCase
+  def testGetId()
+    assert_equal( 1, IdName.new( 1, "foo" ).xid )
+    assert_equal( 1, IdName.new( 1, "bar" ).xid )
+    assert_equal( 2, IdName.new( 2, "foo" ).xid )
+    assert_equal( 2, IdName.new( 2, "bar" ).xid )
+  end
+  
+  def testGetName
+    assert_equal( "foo", IdName.new( 1, "foo" ).name )
+    assert_equal( "bar", IdName.new( 1, "bar" ).name )
+    assert_equal( "foo", IdName.new( 2, "foo" ).name )
+    assert_equal( "bar", IdName.new( 2, "bar" ).name )
+  end
+  
+  def testToString
+    assert_equal( "foo", IdName.new( 1, "foo" ).to_s )
+    assert_equal( "bar", IdName.new( 1, "bar" ).to_s )
+    assert_equal( "foo", IdName.new( 2, "foo" ).to_s )
+    assert_equal( "bar", IdName.new( 2, "bar" ).to_s )
+  end
+  
+  def testEqual
+    assert( IdName.new( 1, "foo" ).eql?( IdName.new( 1, "foo" ) ) )
+    assert( IdName.new( 1, "foo" ).eql?( IdName.new( 1, "bar" ) ) )
+    assert( IdName.new( 2, "foo" ).eql?( IdName.new( 2, "foo" ) ) )
+    assert( IdName.new( 2, "foo" ).eql?( IdName.new( 2, "bar" ) ) )
+    
+    assert( !IdName.new( 1, "foo" ).eql?( IdName.new( 2, "foo" ) ) )
+    assert( !IdName.new( 1, "foo" ).eql?( IdName.new( 2, "bar" ) ) )
+    assert( !IdName.new( 2, "foo" ).eql?( IdName.new( 1, "foo" ) ) )
+    assert( !IdName.new( 2, "foo" ).eql?( IdName.new( 1, "bar" ) ) )
+  end
+  
+  def testHash
+    assert_equal( IdName.new( 1, "foo" ).hash, IdName.new( 1, "foo" ).hash );
+    assert_equal( IdName.new( 1, "foo" ).hash, IdName.new( 1, "bar" ).hash );
+    assert_equal( IdName.new( 2, "foo" ).hash, IdName.new( 2, "foo" ).hash );
+    assert_equal( IdName.new( 2, "foo" ).hash, IdName.new( 2, "bar" ).hash );
+  end
+  
+  def testHashIt
+    assert_equal( 5381, IdName.hashit( "" ) );
+    assert_equal( 352988316, IdName.hashit( "a" ) );
+    assert_equal( 1511848646, IdName.hashit( "ab" ) );
+    assert_equal( 669497117, IdName.hashit( "abc" ) );
+    assert_equal( -1994190713, IdName.hashit( "abcd" ) );
+    assert_equal( -802680418, IdName.hashit( "abcde" ) );
+    assert_equal( 1266308680, IdName.hashit( "abcdef" ) );
+    assert_equal( -379372513, IdName.hashit( "abcdefg" ) );
+    assert_equal( -1416967159, IdName.hashit( "abcdefgh" ) );
+    assert_equal( 53556896, IdName.hashit( "abcdefghi" ) );
+    assert_equal( -4427318, IdName.hashit( "abcdefghij" ) );
+  end
+end
diff --git a/binding-ruby/src/main/ruby/msg/test/test_message.rb b/binding-ruby/src/main/ruby/msg/test/test_message.rb
new file mode 100644
index 0000000..a4b526d
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/test/test_message.rb
@@ -0,0 +1,260 @@
+require 'test/unit'
+require 'etch/bindings/ruby/msg/id_name'
+require 'etch/bindings/ruby/msg/field'
+require 'etch/bindings/ruby/msg/type'
+require 'etch/bindings/ruby/msg/message'
+require 'etch/bindings/ruby/msg/mailbox'
+require 'etch/bindings/ruby/msg/tagged_data_input'
+require 'etch/bindings/ruby/msg/tagged_data_output'
+require 'etch/bindings/ruby/msg/value_factory'
+
+class TestMessage < Test::Unit::TestCase
+  
+  attr :vf, true
+  attr :mt1, true
+  attr :rmt, true
+  attr :mf1, true
+  attr :mf2, true
+
+  def setup
+    @vf = MyValueFactory.new()
+    @mt1 = Type.new(1, "mt")
+    @rmt = Type.new(2, "rmt")
+    @mf1 = Field.new(1, "x")
+    @mf2 = Field.new(2, "y")
+  end
+
+  # Tests
+  #
+
+  def testgetVf
+    msg = Message.new(@mt1, @vf)
+    assert_equal(@vf, msg.vf())
+  end
+
+  def testread
+    readHelper(@mt1)
+    readHelper(@mt1, @mf1, 3)
+    readHelper(@mt1, @mf1, 3, @mf2, 4)
+  end
+
+  def readHelper(mt, *keyVals)
+    tdi = FakeTdi.new(@vf, mt, keyVals)
+    #puts tdi
+    msg = Message.read(tdi)
+    assert_not_nil(msg)
+    tdi.close()
+  end
+  
+  def testwriteMessage
+    msg = Message.new(@mt1, @vf)
+    writeHelper(msg)
+    
+    msg.store(@mf1, 123)
+    writeHelper(msg)
+    
+    msg.store(@mf2, 234)
+    writeHelper(msg)
+  end
+  
+  def writeHelper(msg)
+    tdo = FakeTdo.new(msg)
+    msg.writeMessage(tdo)
+    tdo.close()
+  end
+  
+  def testreply
+    msg = Message.new(@mt1, @vf)
+    msg.setMessageId(12345)
+    
+    rmsg = msg.reply(@rmt)
+    assert_equal(@rmt, rmsg.getType())
+    assert_equal(@vf, rmsg.vf())
+    assert_equal(12345, rmsg.getInReplyTo())
+  end
+  
+  def testgetMessageId
+    msg = Message.new(@mt1, @vf)
+    assert_nil(msg.getMessageId())
+    msg.setMessageId(234)
+    assert_equal(234, msg.getMessageId)
+    msg.setMessageId(345)
+    assert_equal(345, msg.getMessageId)
+  end
+  
+  def testgetInReplyTo
+    msg = Message.new(@mt1, @vf)
+    assert_nil(msg.getInReplyTo)
+    msg.setInReplyTo(234)
+    assert_equal(234, msg.getInReplyTo)
+  end
+
+
+  # Helper (mostly dummy) classes
+  #
+  class MyValueFactory 
+    include ValueFactory
+    
+    attr :mf_messageId, true
+    attr :mf_inReplyTo, true
+    def initialize()
+      @mf_messageId = Field.new(nil, "_messageId")
+      @mf_inReplyTo = Field.new(nil, "_inReplyTo")
+    end
+    
+    # Return message id of message.
+    def getMessageId(msg)
+      return msg[@mf_messageId]
+    end
+    
+    # Set message Id. of the message
+    def setMessageId(msg, msgId)
+      msg.store(@mf_messageId, msgId)
+    end
+    
+    def getInReplyTo(msg)
+      return msg[@mf_inReplyTo]
+    end
+    
+    def setInReplyTo(msg, msgId)
+      msg.store(@mf_inReplyTo, msgId)
+    end
+  end
+  
+  class FakeTdo 
+    include TaggedDataOutput
+    include Test::Unit::Assertions
+    
+    attr :xmsg, true
+    attr :started, true
+    attr :ended, true
+    attr :items, true
+    
+    def initialize(msg)
+      @xmsg = msg
+      @started = false
+      @ended = false
+      @items = Hash.new()
+    end
+    
+    def startMessage(msg)
+      assert_equal(@xmsg, msg)
+      assert_same(@xmsg, msg)
+      assert(!@started) 
+      assert(!@ended)
+      
+      @started = true
+    end
+    
+    def writeStructElement(key, value)
+      assert(@started)
+      assert(!@ended)
+      @items.store(key, value)
+    end
+    
+    def endMessage(msg)
+      assert_equal(@xmsg, msg)
+      assert_same(@xmsg, msg)  # testing ...
+      assert(!@ended)
+      @ended = true
+    end
+    
+    def close
+      assert(@started)
+      assert(@ended)
+      assert_equal(@xmsg.size(), @items.size())
+      assert_equal(@xmsg, @items)
+       
+    end
+  end
+  
+  class FakeTdi 
+    include TaggedDataInput
+    include Test::Unit::Assertions
+    
+    attr :vf, true
+    attr :mt, true
+    attr :fieldsandvalues, true
+    attr :started, true
+    attr :ended, true
+    attr :done, true
+    attr :xmsg, true
+    
+    def initialize(vf, mt, *fieldsandvalues)
+      @vf = vf
+      @mt = mt
+      @fieldsandvalues = fieldsandvalues
+    end
+    
+    def startMessage()
+      
+      assert(!@started)
+      assert(!@ended)
+      assert(!@done)
+    
+      @started = true
+      @xmsg = Message.new(@mt, @vf)
+      @index = 0
+      
+      return @xmsg
+    end
+    
+    def readStructElement(se)
+      assert(@started)
+      assert(!@done)
+      assert(!@ended)
+      
+      index = 0
+      while (@keyVals != nil) and (index < @keyVals.length)
+        key = @keyVals[index]
+        value = @keyVals[index+1]
+        assert_same( value, @xmsg[key] )
+        index += 2
+      end
+      
+      @done = true
+      return false
+    end
+
+    def endMessage(msg)
+      assert_equal(@xmsg, msg)
+      assert(@started)
+      assert(@done)
+      assert( !@ended )
+      @ended = true
+    end
+
+    def close()
+     assert(@started)
+     assert(@done)
+     assert(@ended)
+      
+      assert_equal(@mt, @xmsg.getType())
+      assert_equal(@fieldsandvalues.length/2, @xmsg.length/2)
+      
+      index = 0
+      while index < @fieldsandvalues.length
+        key = @fieldsandvalues[index]
+        value = @fieldsandvalues[index+1]
+        assert_equal( value, @xmsg[key] )
+        index += 2
+      end
+    end
+
+  end
+
+end
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/binding-ruby/src/main/ruby/msg/test/test_struct_value.rb b/binding-ruby/src/main/ruby/msg/test/test_struct_value.rb
new file mode 100644
index 0000000..d4e9c86
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/test/test_struct_value.rb
@@ -0,0 +1,234 @@
+require 'test/unit'

+require 'etch/bindings/ruby/msg/array_value'

+require 'etch/bindings/ruby/msg/id_name'

+require 'etch/bindings/ruby/msg/struct_value'

+require 'etch/bindings/ruby/msg/tagged_data_input'

+require 'etch/bindings/ruby/msg/tagged_data_output'

+

+class TestStructValue < Test::Unit::TestCase

+  def setup

+    @mt1 = IdName.new( 1, "one" )

+    @mt2 = IdName.new( 2, "two" )

+    @mt3 = IdName.new( 3, "three" )

+    @mf1 = IdName.new( 4, "four" )

+    @mf2 = IdName.new( 5, "five" )

+  end

+  

+  def testStype

+    sv = StructValue.new( @mt1 )

+    assert_same( @mt1, sv.stype )

+    assert_not_same( @mt2, sv.stype )

+    

+    sv = StructValue.new( @mt2 )

+    assert_same( @mt2, sv.stype )

+    assert_not_same( @mt1, sv.stype )

+  end

+  

+  def testStype?

+    sv = StructValue.new( @mt1 )

+    assert( sv.stype?( @mt1 ) )

+    assert( !sv.stype?( @mt2 ) )

+    

+    sv = StructValue.new( @mt2 )

+    assert( sv.stype?( @mt2 ) )

+    assert( !sv.stype?( @mt1 ) )

+  end

+  

+  

+  def testPutArrayValue

+    sv = StructValue.new( @mt1 )

+    assert( sv.empty? )

+    assert_equal( 0, sv.length )

+    

+    av1 = sv.putArrayValue( @mf1 )

+    assert_not_nil( av1 )

+    assert_not_same( sv, av1 )

+    assert_instance_of( ArrayValue, av1 )

+    assert( !sv.empty? )

+    assert_equal( 1, sv.length )

+    assert_same( av1, sv[@mf1] )

+    

+    av2 = sv.putArrayValue( @mf2 )

+    assert_not_nil( av2 )

+    assert_not_same( sv, av2 )

+    assert_not_same( av1, av2 )

+    assert_instance_of( ArrayValue, av2 )

+    assert( !sv.empty? )

+    assert_equal( 2, sv.length )

+    assert_same( av1, sv[@mf1] )

+    assert_same( av2, sv[@mf2] )

+  end

+  

+  def testPutStructValue

+    sv = StructValue.new( @mt1 )

+    assert( sv.empty? )

+    assert_equal( 0, sv.length )

+    

+    sv1 = sv.putStructValue(@mf1, @mt2)

+    assert_not_nil( sv1 )

+    assert_not_same( sv, sv1 )

+    assert_instance_of( StructValue, sv1 )

+    assert( !sv.empty? )

+    assert_equal( 1, sv.length )

+    assert_same( sv1, sv[@mf1] )

+    

+    sv2 = sv.putStructValue(@mf2, @mt3)

+    assert_not_nil( sv2 )

+    assert_not_same( sv, sv2 )

+    assert_not_same( sv1, sv2 )

+    assert_instance_of( StructValue, sv2 )

+    assert( !sv.empty? )

+    assert_equal( 2, sv.length )

+    assert_same( sv1, sv[@mf1] )

+    assert_same( sv2, sv[@mf2] )

+  end

+  

+  def testRead

+    readHelper( @mt )

+    readHelper( @mt, @mf1, 3 )

+    readHelper( @mt, @mf1, 3, @mf2, 4 )

+  end

+  

+  def readHelper( mt, *keyVals )

+    tdi = FakeTdi.new( mt, keyVals )

+    sv = StructValue.read tdi

+    assert_not_nil( sv )

+    tdi.close

+  end

+  

+  def testWriteStruct

+    sv = StructValue.new @mt1

+    writeHelper( sv )

+    

+    sv.store( @mf1, 123 )

+    writeHelper( sv )

+    

+    sv.store( @mf2, 234 )

+    writeHelper( sv )

+  end

+  

+  def writeHelper( sv )

+    tdo = FakeTdo.new( sv )

+    sv.writeStruct( tdo )

+    tdo.close

+  end

+  

+  def testReadKeysAndValues

+    assert( true )

+  end

+  

+  def testWriteKeysAndValues

+    assert( true )

+  end

+end

+

+class FakeTdi

+  include TaggedDataInput

+  include Test::Unit::Assertions

+  

+  def initialize( mt, keyVals )

+    @mt = mt

+    @keyVals = keyVals

+    @started = false

+    @done = false

+    @ended = false

+  end

+  

+  def startStruct

+    assert( !@started )

+    assert( !@done )

+    assert( !@ended )

+    

+    @started = true

+    @index = 0

+    @xstruct = StructValue.new( @mt )

+    

+    return @xstruct
+  end

+  

+  def readStructElement( se )

+    assert( @started )

+    assert( !@done )

+    assert( !@ended )

+    assert( @index <= @keyVals.length )

+    

+    if @index < @keyVals.length

+      se.key = @keyVals[@index]

+      se.value = @keyVals[@index+1]

+      @index += 2

+      return true

+    end

+    

+    @done = true

+    return false

+  end

+  

+  def endStruct( struct )

+    assert_same( @xstruct, struct )

+    assert( @started )

+    assert( @done )

+    assert( !@ended )

+    

+    @ended = true

+  end

+  

+  def close

+    assert( @started )

+    assert( @done )

+    assert( @ended )

+    

+    assert_same( @mt, @xstruct.stype )

+    assert_equal( @keyVals.length/2, @xstruct.length )

+    

+    index = 0

+    while index < @keyVals.length

+      key = @keyVals[index]

+      value = @keyVals[index+1]

+      assert_same( value, @xstruct[key] )

+      index += 2

+    end

+  end

+end

+

+class FakeTdo

+  include TaggedDataOutput

+  include Test::Unit::Assertions

+  

+  def initialize( struct )

+    @xstruct = struct
+    @started = false

+    @ended = false

+  end

+  

+  def startStruct( struct )

+    assert_same( @xstruct, struct )

+    assert( !@started )

+    assert( !@ended )

+    

+    @started = true

+    @items = {}

+  end

+  

+  def writeStructElement( key, value )

+    assert( @started )

+    assert( !@ended )

+    @items[key] = value

+  end

+  

+  def endStruct ( struct )

+    assert_same( @xstruct, struct )

+    assert( @started )

+    assert( !@ended )

+    

+    @ended = true

+  end

+  

+  def close

+    assert( @started )

+    assert( @ended )

+    

+    assert_equal( @xstruct.length, @items.length )

+    assert_equal( @xstruct, @items )

+  end

+end

+

diff --git a/binding-ruby/src/main/ruby/msg/type.rb b/binding-ruby/src/main/ruby/msg/type.rb
new file mode 100644
index 0000000..c9668ec
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/type.rb
@@ -0,0 +1,22 @@
+# package 'etch/bindings/ruby/msg'
+
+class Type < IdName
+
+  
+  # Constructs the Type.
+  # @param id the id of the field.
+  # @param name the name of the field.
+  
+  def initialize(id, name)
+    super(id, name)
+  end
+  
+  # Constructs the Type, computing the appropriate value
+  # for the id.
+  # @param name the name of the type.
+=begin  
+  def initialize(name)
+    super(name)
+  end
+=end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/msg/value_factory.rb b/binding-ruby/src/main/ruby/msg/value_factory.rb
new file mode 100644
index 0000000..6960c3c
--- /dev/null
+++ b/binding-ruby/src/main/ruby/msg/value_factory.rb
@@ -0,0 +1,141 @@
+# package 'etch/bindings/ruby/msg'
+
+# Interface which defines the value factory which helps
+# the idl compiler serialize and deserialize messages,
+# convert values, etc.
+#
+module ValueFactory
+
+  # Adds a type to the set of types.
+  # 
+  # @param type a type to add.
+  # 
+  # @return the argument. If there is a collision with
+  # an id and name, both associated with the same type,
+  # then that type is returned instead of the argument.
+  #
+  def addType( type )
+    raise "subclasser responsibility"
+  end
+
+  # Translates a type id into the appropriate Type
+  # object.
+  # @param id a type id.
+  # @return id translated into the appropriate Type.
+  #
+	def getType( xid )
+		raise "subclasser responsibility"
+	end
+	
+  # @return a collection of all the types.
+  def getTypes()
+    raise "subclasser responsibility"
+  end
+  
+  # Adds a field to the set of fields.
+  # 
+  # @param field a field to add.
+  # 
+  # @return the argument. If there is a collision with
+  # an id and name, both associated with the same field,
+  # then that field is returned instead of the argument. 
+  #
+  def addField( field )
+    raise "subclasser responsibility"
+  end
+  
+  # Translates a field id into the appropriate Field object.
+  # @param id a field id.
+  #
+	def getField( xid )
+		raise "subclasser responsibility"
+	end
+	
+  # Get a collection of fields
+  def getFields()
+    raise "subclasser responsibility"
+  end
+  
+  # @return the encoding to use for strings
+	def getStringEncoding
+		raise "subclasser responsibility"
+	end
+	
+  # @param msg the message whose well-known message-id field is to be
+  # returned.
+  # @return the value of the well-known message-id field. This is a
+  # unique identifier for this message on a particular transport
+  # during a particular session. If there is no well-known message-id
+  # field defined, or if the message-id field has not been set, then
+  # return null.
+	def getMessageId( msg )
+		raise "subclasser responsibility"
+	end
+	
+  # Sets the value of the well-known message-id field. This is a
+  # unique identifier for this message on a particular transport
+  # during a particular session. If there is no well-known message-id
+  # field defined then nothing is done. If msgid is null, then the
+  # field is cleared.
+  # @param msg the message whose well-known message-id field is to
+  # be set.
+  # @param msgid the value of the well-known message-id field.
+  #
+	def setMessageId( msg, msgid )
+		raise "subclasser responsibility"
+	end
+	
+  # @param msg the message whose well-known in-reply-to field is to
+  # be returned.
+  # @return the value of the in-reply-to field, or null if there is
+  # none or if there is no such field defined.
+  #
+	def getInReplyTo( msg )
+		raise "subclasser responsibility"
+	end
+	
+  # @param msg the message whose well-known in-reply-to field is to
+  # be set.
+  # @param msgid the value of the well-known in-reply-to field. If
+  # there is no well-known in-reply-to field defined then nothing
+  # is done. If msgid is null, then the field is cleared.
+  #
+	def setInReplyTo( msg, msgid )
+		raise "subclasser responsibility"
+	end
+	
+  # Converts a value to a struct value representation to be exported
+  # to a tagged data output.
+  # @param value a custom type defined by a service, or a well-known
+  # standard type (e.g., date).
+  # @return a struct value representing the value.
+  #
+	def exportCustomValue( value )
+		raise "subclasser responsibility"
+	end
+	
+  # Converts a struct value imported from a tagged data input to
+  # a normal type.
+  # @param sv a struct value representation of a custom type, or a
+  # well known standard type.
+  # @return a custom type, or a well known standard type.
+  #
+	def importCustomValue( sv )
+		raise "subclasser responsibility"
+	end
+	
+  # @param c the class of a custom value.
+  # @return the struct type of a custom value class.
+  #
+  def getCustomStructType( type )
+    raise "subclasser responsibility"
+  end
+  
+  # @param type the type of a custom value
+  # @return the class of a custom struct value type.
+  #
+  def getCustomType( type )
+    raise "subclasser responsibility"
+  end
+  
+end
diff --git a/binding-ruby/src/main/ruby/support/close.rb b/binding-ruby/src/main/ruby/support/close.rb
new file mode 100644
index 0000000..8511042
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/close.rb
@@ -0,0 +1,17 @@
+# package etch/bindings/ruby/support
+
+# Interface which a service implementation may implement which
+# is used by the service stub to give notice of a closed message
+# source.
+
+module Close
+
+  # Notifies the service implementation that the message
+  # source is closed.
+  # @param src the message source that is closed.
+  #
+  def _close( src )
+    raise "subclasser responsibility"
+  end
+  
+end
diff --git a/binding-ruby/src/main/ruby/support/converter.rb b/binding-ruby/src/main/ruby/support/converter.rb
new file mode 100644
index 0000000..e78e068
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/converter.rb
@@ -0,0 +1,7 @@
+# package etch/bindings/ruby/support
+
+module Converter
+  def convert( obj )
+    raise "subclasser responsibility"
+  end
+end
diff --git a/binding-ruby/src/main/ruby/support/default_value_factory.rb b/binding-ruby/src/main/ruby/support/default_value_factory.rb
new file mode 100644
index 0000000..16b1845
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/default_value_factory.rb
@@ -0,0 +1,231 @@
+# package etch/bindings/ruby/support
+require 'etch/bindings/ruby/msg/value_factory'
+require 'etch/bindings/ruby/msg/id_name'
+require 'etch/bindings/ruby/support/id_name_map'
+require 'etch/bindings/ruby/msg/type'
+require 'etch/bindings/ruby/msg/field'
+require 'etch/bindings/ruby/support/etch__auth_exception'
+
+# Default implementation of ValueFactory which provides some
+# dynamic type and field support, as well as standard
+# value conversions and import and export.
+#
+class DefaultValueFactory
+  include ValueFactory
+  
+  attr :types, true
+  attr :fields, true
+    
+  MT__Etch_RuntimeException = Type.new( nil, "_Etch_RuntimeException" )
+  MT__Etch_AuthException = Type.new( nil, "_Etch_AuthException" )
+  MT__Etch_Date = Type.new( nil, "_Etch_Date" )
+  MT__exception = Type.new( nil, "_exception" )
+
+  MF_msg = Field.new( nil, "msg"  )
+  MF_ticks = Field.new( nil, "ticks" )
+  MF_messageId = Field.new( nil, "_messageId" )
+  MF_inReplyTo = Field.new( nil, "_inReplyTo" )
+
+  def initialize( *params )
+    
+        
+    # Call parametrized constructor
+    temp = 100
+    temp = params.first unless params.nil? 
+    paramInitialize( temp )
+    
+  end
+  
+  def paramInitialize( maxAutoCount )
+    
+    @types = IdNameMap.new( maxAutoCount )
+    
+    # verify anonymous class technique
+    def @types.makeNew( id, name )
+      return Type.new( id, name )
+    end
+    
+    # verify anonymous class technique
+    @fields = IdNameMap.new( maxAutoCount )
+    def @fields.makeNew( id, name )
+      return Field.new(id, name )
+    end
+    
+    addType( MT__Etch_RuntimeException );
+    addType( MT__Etch_AuthException );
+    addType( MT__Etch_Date );
+    addType( MT__exception );
+    
+    addField( MF_msg );
+    addField( MF_ticks );
+    addField( MF_messageId );
+    addField( MF_inReplyTo );
+    
+  end
+  
+  # 
+  # Types
+  #
+  
+  def addType( type )
+    return @types.add( type )
+  end
+  
+  def getType( xid )
+    
+    if ( xid.class != Fixnum )
+      if ( xid.class == String )
+        getTypeByName( xid )
+      end
+    end
+    
+    case ( xid )
+      when MT__Etch_RuntimeException.xid then return MT__Etch_RuntimeException
+      when MT__Etch_AuthException.xid then return MT__Etch_AuthException
+      when MT__Etch_Date.xid then return MT__Etch_Date
+      when MT__exception.xid then return MT__exception
+    end
+    
+    return @types.get( xid )
+  end
+
+  def getTypeByName( name )
+    @types.get( name )
+  end
+  
+  def getTypes()
+    return @types.values()
+  end
+  
+  #
+  # Fields
+  #
+  
+  def addField( mf )
+    return @fields.add( mf )
+  end
+  
+  def getField( xid )
+    
+    if ( xid.class == String )
+      getFieldByName( xid ) 
+    else
+      case ( xid )
+        when MF_msg.xid then return MF_msg
+        when MF_ticks.xid then return MF_ticks
+        when MF_messageId.xid then return MF_messageId
+        when MF_inReplyTo.xid then return MF_inReplyTo
+      end
+      return @fields.get( xid )
+      
+    end
+  end
+  
+  def getFieldByName( name )
+    return @fields.get( name )
+  end
+  
+  def getFields()
+    return @fields.values()
+  end
+  
+  # Figure out the encoding implementation
+  def getStringEncoding()
+    raise "not implemented as yet"
+  end
+  
+  #
+  # MessageID
+  #
+  
+  def getMessageId( msg )
+    return msg[MF_messageId]
+  end
+  
+  def setMessageId( msg, msgid )
+    
+    if (msgid != nil)
+      msg[MF_messageId] = msgid
+    else
+      msg.delete(MF_messageId)
+    end
+    
+  end
+  
+  #
+  # InReplyTo
+  #
+  def getInReplyTo( msg )
+    return msg[MF_inReplyTo]
+  end
+  
+  def setInReplyTo( msg, msgid )
+    
+    if (msgid != nil)
+      msg[MF_inReplyTo] = msgid
+    else
+      msg.delete(MF_inReplyTo)
+    end
+  end
+  
+  # 
+  # Value Conversion
+  #
+  def exportCustomValue( value )
+    
+    c = value.class
+    
+    if ( c == Time )
+      sv = StructValue.new( MT__Etch_Date )
+      sv.store( MF_ticks, value.to_i )
+      return sv
+    end
+    
+    if ( c == Etch_AuthException )
+      sv = StructValue.new( MT__Etch_AuthException )
+      sv.store( MF_msg, v.to_s() )
+      return sv
+    end
+    
+    # catch any exception which wasn't otherwise
+    # handled and pass it through.
+    #
+    if ( c == Exception )
+      sv = StructValue.new( MT__Etch_RuntimeException )
+      sv.store( MF_msg, value.to_s )
+      return sv
+    end
+    
+    return nil
+  end
+  
+  def importCustomValue( sv )
+    
+    type = sv.getType()
+
+    case ( type.xid )
+      when MT__Etch_RuntimeException.xid then return Etch_RuntimeException.new( sv[ MF_msg ] )
+      when MT__Etch_AuthException.xid then return Etch_AuthException.new( sv[ MF_msg ])
+      when MT__Etch_Date.xid then return Time.at( sv[ MF_ticks ] )
+    end
+    
+    return nil
+  end
+  
+  def getCustomStructType( c )
+    if (c == DateTime )
+      return MT__Etch_Date
+    end
+    return nil
+  end
+  
+  def getCustomType( type )
+    
+    case ( type.xid )
+      when MT__Etch_Date then return DateTime
+    end
+    
+    return nil
+  end
+  
+end
diff --git a/binding-ruby/src/main/ruby/support/delivery_service.rb b/binding-ruby/src/main/ruby/support/delivery_service.rb
new file mode 100644
index 0000000..356218c
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/delivery_service.rb
@@ -0,0 +1,59 @@
+# package etch/bindings/ruby/support
+
+
+# Adapter between remote and message source.
+#
+module DeliveryService
+  
+  # Sends the message to the recipient, but does not wait for
+  # any response.
+  # @param msg the message to send
+  # @throws Exception if there is a problem sending
+  #
+  def send( msg )
+    raise "subclasser responsibility"
+  end
+  
+  # Sends the message which begins a call sequence.
+  # @param msg the message to send.
+  # @return a mailbox which can be used to read response
+  #
+  def begincall( msg )
+    raise "subclasser responsibility"
+  end
+  
+  # @param mb the mailbox returned by begincall( msg )}.
+  # @param responseType the type of the expected response.
+  # @param responseField the field of the expected response
+  # which would contain any result value or thrown exception.
+  # @param timeout time in ms to wait for a response.
+  # @throws Exception if there is a problem sending or a timeout
+  # waiting or if the result value was an exception.
+  #
+  def endvoidcall( mb, responseType, responseField, timeout )
+    raise "subclasser responsibility"
+  end
+  
+  # @param mb
+  # @param responseType the type of the expected response.
+  # @param responseField the field of the expected response
+  # which would contain any result value or thrown exception.
+  # @param timeout time in ms to wait for a response.
+  # @return the value of the response field if it isn't an exception.
+  # @throws Exception if there is a problem sending or a timeout
+  # waiting or if the result value was an exception.
+  #
+  def endcall( mb, responseType, responseField, timeout )
+    raise "subclasser responsibility"
+  end
+  
+  # Shuts down output so no more messages may be sent. The
+  # other end should see the input message stream close, and
+  # would in turn shutdown its output (which we would then see).
+  # @throws Exception if there is a problem shutting down out
+  # output stream.
+  #
+  def shutdownOutput
+    raise "subclasser responsibility"
+  end
+end
diff --git a/binding-ruby/src/main/ruby/support/element.rb b/binding-ruby/src/main/ruby/support/element.rb
new file mode 100644
index 0000000..0a111c8
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/element.rb
@@ -0,0 +1,10 @@
+# package etch/bindings/ruby/support
+
+class Element
+  
+  def initialize( sender, msg )
+    @sender = sender
+    @msg = msg
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/support/enum.rb b/binding-ruby/src/main/ruby/support/enum.rb
new file mode 100644
index 0000000..369892a
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/enum.rb
@@ -0,0 +1,33 @@
+# package etch/bindings/ruby/support
+
+class Enum
+  include Comparable
+  
+  def initialize( name, ord )
+    @name = name
+    @ord = ord
+  end
+  
+  def <=>( other )
+    return @ord<=>( other.ord )
+  end
+  
+  def to_s
+    return @name.to_s
+  end
+  
+  attr :name
+  attr :ord
+  
+  alias :to_int :ord
+  alias :to_i :ord
+  
+  protected :initialize
+end
+
+# Usage:
+#class PrimaryColor < Enum
+#  RED = PrimaryColor.new( :RED, 0 )
+#  GREEN = PrimaryColor.new( :GREEN, 1 )
+#  BLUE = PrimaryColor.new( :BLUE, 2 )
+#end
diff --git a/binding-ruby/src/main/ruby/support/etch__auth_exception.rb b/binding-ruby/src/main/ruby/support/etch__auth_exception.rb
new file mode 100644
index 0000000..81b65bf
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/etch__auth_exception.rb
@@ -0,0 +1,10 @@
+# package 'etch/bindings/ruby/support'
+require 'etch/bindings/ruby/support/etch__runtime_exception'
+
+class Etch_AuthException < Etch_RuntimeException
+  
+  def initialize( msg )
+    super( msg )
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/support/etch__runtime_exception.rb b/binding-ruby/src/main/ruby/support/etch__runtime_exception.rb
new file mode 100644
index 0000000..66f0ee8
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/etch__runtime_exception.rb
@@ -0,0 +1,18 @@
+# package etch/bindings/ruby/support
+
+class Etch_RuntimeException < Exception
+  
+  attr :msg, true
+  
+  # Constructs the EtchRuntimeException.
+  # @param msg description of the exception that was caught by the stub
+  #
+  def initialize( msg )
+    @msg = msg
+  end
+  
+  def message()
+    return msg
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/support/etch_enum.rb b/binding-ruby/src/main/ruby/support/etch_enum.rb
new file mode 100644
index 0000000..8530cf2
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/etch_enum.rb
@@ -0,0 +1,21 @@
+
+# Adding Enum capability to ruby
+
+module EtchEnum
+  
+  def self.enum( *syms )
+    
+    syms.each { |s| const_set( s, s.to_s ) }
+    const_set( :DEFAULT, syms.first ) unless ( syms.nil? || const_defined?( :DEFAULT ) )
+  end
+  
+  def self.enum2( *syms )
+    
+    order = 0
+    syms.each { |s| 
+      const_set( s.to_s, order ) 
+      order += 1 
+    } unless ( syms.nil? || syms.length == 0 )
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/support/etch_mutex.rb b/binding-ruby/src/main/ruby/support/etch_mutex.rb
new file mode 100644
index 0000000..b8bfc7d
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/etch_mutex.rb
@@ -0,0 +1,38 @@
+require 'thread'
+
+# Check whether the mutex is  
+# being held by the current thread itself,
+# in which case, don't try to lock again. 
+# @param threadId holds the information 
+# regarding "which" thread holds the lock
+
+class EtchMutex < Mutex
+  
+  def synchronize
+    
+    # do checking here
+    if (@threadId == nil)
+      # no thread holds lock
+      @threadId = Thread.current
+      super
+    else
+      if (@threadId == Thread.current)
+        # don't call synchronize again
+        # because this thread already holds lock
+        # just yield !
+        yield
+      else
+        # another thread wants the lock
+        # proceed normal locking operation
+        super
+      end
+    end
+  end
+  
+  # When unlock is called, threadId should be set back
+  # nil. 
+  def unlock
+    @threadId = nil
+    super
+  end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/support/id_name_map.rb b/binding-ruby/src/main/ruby/support/id_name_map.rb
new file mode 100644
index 0000000..f064b04
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/id_name_map.rb
@@ -0,0 +1,166 @@
+require 'thread'
+require 'etch/bindings/ruby/support/etch_mutex'
+# Map by id and name of IdNames (or subclasses thereof).
+#
+class IdNameMap
+
+  attr :maxAutoCount, true
+  attr :byId, true
+  attr :byName, true
+  attr :autocount, true
+  
+  # Constructs the IdNameMap.
+  # @param maxAutoCount the maximum number of automatically
+  # declared IdNames allowed. Set to 0 if you don't want any,
+  # but this may prevent working with a slightly different
+  # version of a service.
+  #
+  def initialize( maxAutoCount )
+  
+    @mutex = EtchMutex.new 
+    
+    @maxAutoCount = maxAutoCount
+    @byId = Hash.new
+    @byName = Hash.new
+    @autocount = 0
+  end
+  
+  # Gets the IdName subclass which corresponds to the specified
+  # id, or creates it if it isn't found and if autoCount <
+  # maxAutoCount. If created, the IdName is given the name which
+  # is id.toString().
+  # @param id the id of an IdName.
+  # @return the IdName subclass found or created.
+  #
+
+  def get( id )
+    
+    if ( id.class == String )
+      
+      # print "getByName() call"
+      getByName( id )
+    else
+      # Check if the synchronization is correct !
+      @mutex.synchronize do
+        t = @byId[id]
+        
+        if (t == nil)
+          # print "autocount = ", @autocount, "maxAutocount = ", @maxAutoCount
+          if ( @autocount >= @maxAutoCount )
+            raise "maxAutoCount would be exceeded"
+          end
+          
+          @autocount += 1
+          
+          var = add( makeNew( id, id.to_s() ) )
+          return var
+        end
+        
+        return t
+      end 
+    end
+  end
+  
+  # Gets the IdName subclass which corresponds to the specified
+  # name, or creates it if it isn't found and if autoCount <
+  # maxAutoCount. If created, the IdName is given the id which
+  # is IdName.hash( name ).
+  # @param name the name of an IdName.
+  # @return the IdName subclass found or created.
+  #
+  def getByName( name )
+    @mutex.synchronize do
+      
+      t = @byName[ name ]
+      if (t == nil)
+        if (@autocount >= @maxAutoCount)
+          raise "maxAutoCount would be exceeded"
+        end
+        @autocount += 1
+        
+        return add( makeNew( IdName.hashit( name ), name ) )
+      end
+      
+      return t
+      
+    end # mutex end
+  end
+  
+  # Adds the IdName subclass to the map. If the entry matches
+  # a current entry (both id and name), then return the current
+  # entry instead.
+  # 
+  # @param t the IdName subclass to add.
+  # 
+  # @return the IdName from the map, either the new one or a current
+  # one.
+  # 
+  # @throws IllegalArgumentException if there is a collision with
+  # id or name, or a collision with id and name where they are not
+  # associated with the same object.
+  #
+  def add( t )
+    @mutex.synchronize do
+    
+      # four cases:
+      # 1) t.id and t.name do not exist (no collision)
+      # 2) t.id exists but t.name does not (collision)
+      # 3) t.id does not exist but t.name does (collision)
+      # 4) t.id and t.name exist (possible collision)    
+      
+      sameId = @byId[ t.xid ]
+      sameName = @byName[ t.name ]
+      if ( sameId!=nil || sameName!=nil )
+        # sameId has the same id as t.
+        # sameName has the same name as t.
+        # the only way this isn't a problem is if sameId == sameName,
+        # because that is the only case where there is a single
+        # entry which has both the same id and name as t.
+        if (sameId != sameName)
+          
+          if (sameId != nil && sameName != nil)
+            raise "id & name collision" 
+          else 
+            if (sameId != nil)
+              raise "id collision"
+            end
+            if (sameName != nil )
+              raise "id collision"
+            end
+          end
+          
+        end
+        
+        return sameId
+      end
+      
+      @byId.store( t.xid, t )
+      @byName.store( t.name, t )
+      
+      return t
+    
+    end # mutex end
+    
+  end
+  
+  def values()
+    
+    @mutex.synchronize do
+      
+      return @byId.values()
+    
+    end # mutex end
+    
+  end
+  
+  # Makes a new subclass of IdName to put in this map.
+  # @param id the id of the new subclass of IdName.
+  # @param name the name of the new subclass of IdName.
+  # @return a newly constructed subclass of IdName to put in
+  # this map.
+  #
+  def makeNew( id, name )
+    raise "subclasser responsibility"
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/support/mailbox.rb b/binding-ruby/src/main/ruby/support/mailbox.rb
new file mode 100644
index 0000000..5250317
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/mailbox.rb
@@ -0,0 +1,40 @@
+# package etch/bindings/ruby/support
+require 'etch/bindings/ruby/support/message_handler'
+
+# An interface used to deliver responses to a message. Support for
+# the mechanism is somewhat dependent upon properties of the transport
+# and message format. 
+#
+module Mailbox 
+  include MessageHandler
+  
+  def getMessageId()
+    raise "subclasser responsibility"
+  end
+  
+  # @param maxDelay the maximum amount of time in milliseconds to
+  # wait to read a message from an empty mailbox. 0 means wait
+  # forever, -1 means don't wait at all.
+  # @return the next message to be read from the mailbox, or null if
+  # the mailbox is empty and closed. Wait forever for such a message
+  # to be delivered.
+  #
+  def read( maxDelay )
+    raise "subclasser responsibility"
+  end
+  
+  # Closes the mailbox so that no more messages can be delivered.
+  # Queued messages remain to be read. Reading an empty closed
+  # mailbox returns null.
+  def closeDelivery()
+    raise "subclasser responsibility"
+  end
+  
+  # Closes the mailbox so that no more messages will be delivered or
+  # read. Any remaining queued messages are delivered to a default
+  # handler.
+  def closeRead()
+    raise "subclasser responsibility"
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/support/message_handler.rb b/binding-ruby/src/main/ruby/support/message_handler.rb
new file mode 100644
index 0000000..8267e2d
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/message_handler.rb
@@ -0,0 +1,15 @@
+# package etch/bindings/ruby/support
+
+module MessageHandler
+  
+  # Delivers a message from a message source.
+  # @param src the message source
+  # @param sender the message sender (meaning depends upon the message
+  # source).
+  # @param msg the message from the message source.
+  # @return true if the message was processed.
+  # 
+  def message( src, sender, msg )
+    raise "subclasser responsibility"
+  end
+end
diff --git a/binding-ruby/src/main/ruby/support/message_source.rb b/binding-ruby/src/main/ruby/support/message_source.rb
new file mode 100644
index 0000000..67b05bb
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/message_source.rb
@@ -0,0 +1,23 @@
+# package 'etch/bindings/ruby/support'
+
+# A message source is used to model the origin of a message to a
+# stub so that a reply might be sent.
+#
+module MessageSource
+
+  # Sends a message to a message source. The message is encoded
+  # in some way (e.g., compressed binary format or xml), and then delivered
+  # to a transport (e.g., packetized data stream or http response).
+  # 
+  # @param recipient a transport specific opaque value which identifies
+  # the sender of a message. Delivered by a message handler to the stub
+  # and may be passed here to send a message back to the original sender.
+  # Passing null means "use the default recipient".
+  # 
+  # @param msg the message to send.
+	
+  def message( recipient, msg )
+		raise "subclasser responsibility"
+	end
+  
+end
diff --git a/binding-ruby/src/main/ruby/support/pool.rb b/binding-ruby/src/main/ruby/support/pool.rb
new file mode 100644
index 0000000..4a7155e
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/pool.rb
@@ -0,0 +1,7 @@
+# package etch/bindings/ruby/support
+
+module Pool
+
+  # Figure Pool out ... 
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/support/remote_base.rb b/binding-ruby/src/main/ruby/support/remote_base.rb
new file mode 100644
index 0000000..6184ec6
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/remote_base.rb
@@ -0,0 +1,25 @@
+# package etch/bindings/ruby/support
+
+# Base class for call to message translators.
+#
+require 'etch/bindings/ruby/msg/message'
+class RemoteBase
+
+  attr :_svc, true
+  attr :_vf, true
+  
+  def initialize( svc, vf )
+    @_svc = svc
+    @_vf = vf
+  end
+  
+  def _newMessage( type )
+    return Message.new( type, @_vf )
+  end
+  
+  # Shuts down output on this remote object. No more
+  # messges may be sent.
+  def _shutdownOutput()
+    return @_svc.shutdownOutput()
+  end
+end
diff --git a/binding-ruby/src/main/ruby/support/stub_base.rb b/binding-ruby/src/main/ruby/support/stub_base.rb
new file mode 100644
index 0000000..d1682ad
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/stub_base.rb
@@ -0,0 +1,32 @@
+# package etch/bindings/ruby/support
+require 'etch/bindings/ruby/support/message_handler'
+
+
+# Base class of stub implementations.
+#
+class StubBase
+  include MessageHandler
+  
+  
+  attr :_obj
+  attr :_free
+  attr :_pool
+  
+  def initialize( obj, pool, free )
+    @_obj = obj
+    @_free = free
+    @_pool = pool
+  end
+  
+  
+  def message( src, sender, msg )
+    
+    if (msg == nil)
+      if ( @_obj.class.method_defined? :_close )
+        @_obj._close( src )
+      end
+      return true
+    end
+    return false
+  end
+end
diff --git a/binding-ruby/src/main/ruby/support/test/test_default_value_factory.rb b/binding-ruby/src/main/ruby/support/test/test_default_value_factory.rb
new file mode 100644
index 0000000..d973eeb
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/test/test_default_value_factory.rb
@@ -0,0 +1,335 @@
+require 'test/unit'
+require 'etch/bindings/ruby/support/id_name_map'
+require 'etch/bindings/ruby/msg/id_name'
+require 'etch/bindings/ruby/support/etch_enum'
+require 'etch/bindings/ruby/support/delivery_service'
+require 'etch/bindings/ruby/support/default_value_factory'
+require 'etch/bindings/ruby/support/remote_base'
+require 'etch/bindings/ruby/support/close'
+require 'etch/bindings/ruby/support/unwanted'
+require 'etch/bindings/ruby/support/message_source'
+require 'etch/bindings/ruby/support/stub_base'
+require 'etch/bindings/ruby/support/who'
+require 'etch/bindings/ruby/support/default_value_factory'
+
+class TestDefaultValueFactory < Test::Unit::TestCase
+  
+  def setup
+    @vf = DefaultValueFactory.new( 3 )
+  end
+
+  def test_add_type
+    
+    #
+    # a
+    #
+    
+    a = @vf.addType( Type.new( nil, "a" ) )
+    assert_not_nil( a )
+    
+    x = @vf.addType( @vf.getType( "a" ) )
+    assert_not_nil( x )
+    assert_same( a, x )
+    
+    x = @vf.addType( Type.new( nil, "a" ) )
+    assert_not_nil( x )
+    assert_same( a, x )
+    
+    #
+    # b
+    #
+    
+    b = @vf.addType( Type.new( nil, "b" ) )
+    assert_not_nil( b )
+    
+    y = @vf.addType( @vf.getType( "b" ) )
+    assert_not_nil( y )
+    assert_same( b, y )
+    
+    y = @vf.addType( Type.new( nil, "b" ) )
+    assert_not_nil( y )
+    assert_same( b, y )
+    
+    #
+    # c
+    #
+    
+    c = @vf.addType( Type.new( nil, "c" ) )
+    assert_not_nil( c )
+    
+    z = @vf.addType( @vf.getType( "c" ) )
+    assert_not_nil( z )
+    assert_same( c, z )
+    
+    z = @vf.addType( Type.new( nil, "c" ) )
+    assert_not_nil( z )
+    assert_same( c, z )
+    
+  end
+  
+  def test_getType_id_Etch_Runtime_Exception
+    x = @vf.getType( DefaultValueFactory::MT__Etch_RuntimeException.xid )
+    assert_not_nil( x )
+    assert_same( DefaultValueFactory::MT__Etch_RuntimeException, x )
+  end
+  
+  def test_getType_name_Etch_Runtime_Exception
+    x = @vf.getType( "_Etch_RuntimeException" )
+    assert_not_nil( x )
+    assert_same( DefaultValueFactory::MT__Etch_RuntimeException, x )
+  end
+
+  def test_just_enough
+    @vf.getType( "a" )
+    @vf.getType( "b" )
+    @vf.getType( "c" )
+  end
+  
+  def test_too_many
+  
+    @vf.getType( "a" )
+    @vf.getType( "b" )
+    @vf.getType( "c" )
+    
+    exceptionCaught = false
+    begin 
+      @vf.getType( "d" )
+    rescue Exception
+      exceptionCaught = true
+    end
+    
+    flunk "test should have failed" if ( exceptionCaught == false )
+  end
+
+  def test_getTypes
+    list = Array.new
+    list << @vf.getType( "a" )
+    list << @vf.getType( "b" )
+    list << @vf.getType( "c" )
+    list << DefaultValueFactory::MT__Etch_RuntimeException
+    list << DefaultValueFactory::MT__Etch_AuthException
+    list << DefaultValueFactory::MT__Etch_Date
+    list << DefaultValueFactory::MT__exception
+    
+    c = @vf.getTypes
+    
+    # Check for inclusivity. 
+    list.each { |element| assert( c.include?( element ) ) }
+    c.each{ |element| assert( list.include?( element ) ) }
+    
+  end
+  
+  def test_add_field()
+    
+    #
+    # a
+    #
+    
+    a = @vf.addField( Field.new( nil, "a" ) )
+    assert_not_nil( a ) 
+    
+    x = @vf.getField( "a" )
+    assert_not_nil( x )
+    assert_same( a, x )
+    
+    #
+    # b
+    #
+    
+    b = @vf.addField( Field.new( nil, "b" ) )
+    assert_not_nil( b ) 
+    
+    y = @vf.getField( "b" )
+    assert_not_nil( y )
+    assert_same( b, y )
+    
+    #
+    # c
+    #
+    
+    c = @vf.addField( Field.new( nil, "c" ) )
+    assert_not_nil( c ) 
+    
+    z = @vf.getField( "c" )
+    assert_not_nil( z )
+    assert_same( c, z )
+    
+  end
+
+  def test_get_field_id_messageId
+    x = @vf.getField( DefaultValueFactory::MF_messageId.xid )
+    assert_not_nil( x ) 
+    assert_same( DefaultValueFactory::MF_messageId, x )
+  end
+  
+  def test_get_field_id_inReplyTo
+    x = @vf.getField( DefaultValueFactory::MF_inReplyTo.xid )
+    assert_not_nil( x ) 
+    assert_same( DefaultValueFactory::MF_inReplyTo, x )
+  end
+
+  def test_get_field_id_msg
+    x = @vf.getField( DefaultValueFactory::MF_msg.xid )
+    assert_not_nil( x ) 
+    assert_same( DefaultValueFactory::MF_msg, x )
+  end
+  
+  def test_get_field_name_messageId
+    x = @vf.getField( "_messageId" )
+    assert_not_nil( x ) 
+    assert_same( DefaultValueFactory::MF_messageId, x )
+  end
+  
+  def test_get_field_name_inReplyTo
+    x = @vf.getField( "_inReplyTo" )
+    assert_not_nil( x ) 
+    assert_same( DefaultValueFactory::MF_inReplyTo, x )
+  end
+  
+  def test_get_field_name_msg
+    x = @vf.getField( "msg" )
+    assert_not_nil( x ) 
+    assert_same( DefaultValueFactory::MF_msg, x )
+  end
+  
+  def test_get_field_name_ticks
+    x = @vf.getField( "ticks" )
+    assert_not_nil( x ) 
+    assert_same( DefaultValueFactory::MF_ticks, x )
+  end
+  
+  def test_getField_auto_just_enough
+    @vf.getField( "a" )
+    @vf.getField( "b" )
+    @vf.getField( "c" )
+  end
+  
+  def test_getField_auto_too_many
+  
+    @vf.getField( "a" )
+    @vf.getField( "b" )
+    @vf.getField( "c" )
+  
+    exceptionCaught = false
+    begin 
+      @vf.getField( "d" )
+    rescue Exception
+      exceptionCaught = true
+    end  
+    flunk "test should have failed" if ( exceptionCaught == false )
+    
+  end
+  
+  def test_getFields
+    list = Array.new
+    list << @vf.getField( "a" )
+    list << @vf.getField( "b" )
+    list << @vf.getField( "c" )
+    list << DefaultValueFactory::MF_msg
+    list << DefaultValueFactory::MF_ticks
+    list << DefaultValueFactory::MF_messageId
+    list << DefaultValueFactory::MF_inReplyTo
+    
+    c = @vf.getFields
+    
+    # Check for inclusivity. 
+    list.each { |element| assert( c.include?( element ) ) }
+    c.each{ |element| assert( list.include?( element ) ) }
+    
+  end
+  
+  def test_get_type_and_fields_are_distinct
+    
+    # verify that the type and field maps are distinct
+    mta = @vf.getType( "a" )
+    assert_not_nil( mta )
+    mfa = @vf.getField( "a" )
+    assert_not_nil( mfa )
+    
+    assert_not_same( mta, mfa )
+  end
+  
+  # TODO: Test for string encoding
+  
+  def test_messageId
+    
+    msg = Message.new( nil, @vf )
+    assert_nil( @vf.getMessageId( msg ) )
+    
+    @vf.setMessageId( msg, 234 )
+    msgId = @vf.getMessageId( msg )
+    assert_not_nil( msgId ) 
+    assert_equal( 234, msgId )
+    
+    @vf.setMessageId( msg, nil )
+    assert_nil( @vf.getMessageId( msg ) ) 
+  end
+  
+  def test_inReplyTo
+    
+    msg = Message.new( nil, @vf )
+    assert_nil( @vf.getInReplyTo( msg ) )
+    
+    @vf.setInReplyTo( msg, 234 )
+    msgId = @vf.getInReplyTo( msg )
+    assert_not_nil( msgId )
+    assert_equal( msgId, 234 )
+    
+    @vf.setInReplyTo( msg, nil )
+    assert_nil( @vf.getInReplyTo( msg ) )
+  end
+  
+  def test_exportcustomvalue_runtimeexception
+    
+    value = Exception.new()
+    sv = @vf.exportCustomValue( value )
+    sv.checkType( DefaultValueFactory::MT__Etch_RuntimeException )
+    
+    assert_equal( 1, sv.size )
+    assert_equal( sv[ DefaultValueFactory::MF_msg ], "Exception" )
+  end
+  
+  def test_exportcustomvalue_runtimeexception_msg
+    
+    value = Exception.new( "foo!=null" )
+    sv = @vf.exportCustomValue( value )
+    sv.checkType( DefaultValueFactory::MT__Etch_RuntimeException )
+    
+    assert_equal( 1, sv.size )
+    assert_equal( sv[ DefaultValueFactory::MF_msg ], "foo!=null"  )
+  end
+  
+  def test_exportcustomvalue_date
+    
+    # the argument gives the no. of seconds since epoch
+    value = Time.at(12395)
+    sv = @vf.exportCustomValue( value )
+    sv.checkType( DefaultValueFactory::MT__Etch_Date )
+    assert_equal( 1, sv.size )
+    assert_equal( 12395, sv[ DefaultValueFactory::MF_ticks ])
+  end
+
+  def test_importcustomvalue_etch_runtimeexception
+    sv = StructValue.new( DefaultValueFactory::MT__Etch_RuntimeException )
+    e = @vf.importCustomValue( sv )
+    assert_not_nil( e )
+    assert_nil( e.message() )
+  end
+  
+  def test_importcustomvalue_etch_runtimeexception_msg
+    sv = StructValue.new( DefaultValueFactory::MT__Etch_RuntimeException )
+    sv.store( DefaultValueFactory::MF_msg, "foo")
+    e = @vf.importCustomValue( sv )
+    assert_not_nil( e )
+    assert_equal( "foo", e.message())
+  end
+  
+  def test_importcustomvalue_etch_date
+    sv = StructValue.new( DefaultValueFactory::MT__Etch_Date )
+    sv.store( DefaultValueFactory::MF_ticks, 12345)
+    e = @vf.importCustomValue( sv )
+    assert_not_nil( e )
+    assert_equal( 12345, e.to_i)
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/support/test/test_id_name_map.rb b/binding-ruby/src/main/ruby/support/test/test_id_name_map.rb
new file mode 100644
index 0000000..dff2787
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/test/test_id_name_map.rb
@@ -0,0 +1,219 @@
+require 'test/unit'
+require 'etch/bindings/ruby/support/id_name_map'
+require 'etch/bindings/ruby/msg/id_name'
+
+class TestIdNameMap < Test::Unit::TestCase
+  
+  def setup
+    
+    @map = IdNameMap.new( 3 )
+    def @map.makeNew( id, name )
+      
+      # print "makeNew called with ", id, " & ", name, "\n"
+      return IdName.new( id, name )
+    end
+    
+    @a = @map.add( IdName.new( 1, "a" ) )
+    @b = @map.add( IdName.new( 2, "b" ) )
+  end
+
+  def testget_1
+    x = @map.get( 1 )
+    assert_not_nil( x )
+    assert_same( @a, x )
+    assert_equal( 1, x.xid )
+    assert_equal( "a", x.name() )
+  end
+
+  def testget_a
+    x = @map.get( "a" )
+    assert_not_nil( x )
+    assert_same( @a, x )
+    assert_equal( 1, x.xid )
+    assert_equal( "a", x.name )
+  end
+
+  def testget_2
+    x = @map.get( 2 )
+    assert_not_nil( x )
+    assert_same( @b, x )
+    assert_equal( 2, x.xid )
+    assert_equal( "b", x.name() )
+  end
+
+  def testget_b
+    x = @map.get( "b" )
+    assert_not_nil( x )
+    assert_same( @b, x )
+    assert_equal( 2, x.xid )
+    assert_equal( "b", x.name )
+  end
+  
+  def testget_3
+    x = @map.get( 3 )
+    assert_not_nil( x )
+    assert_not_same( @a, x )
+    assert_not_same( @b, x )
+    assert_equal( 3, x.xid )
+    assert_equal( "3", x.name )
+    
+    y = @map.get( 3 )
+    assert_same( x, y )
+  end
+  
+  def testget_c
+    x = @map.get( "c" )
+    assert_not_same( @a, x )
+    assert_not_same( @b, x )
+    assert_equal( 352988318, x.xid )
+    assert_equal( "c", x.name )
+
+    y = @map.get( "c" )
+    assert_same( x, y )
+  end
+  
+  def testjustgetenough
+    c = @map.get( "c" )
+    assert_not_nil( c )
+    assert_not_same( @a, c )
+    assert_not_same( @b, c )
+    
+    d = @map.get( "d" )
+    assert_not_nil( d )
+    assert_not_same( @a, d )
+    assert_not_same( @b, d )
+    assert_not_same( c, d )
+    
+    e = @map.get( "e" )
+    assert_not_nil( e )
+    assert_not_same( @a, e )
+    assert_not_same( @b, e )
+    assert_not_same( c, e )
+    assert_not_same( d, e )  
+    
+  end
+  
+  def testgettoomany1
+    
+    c = @map.get( "c" )
+    assert_not_nil( c )
+    assert_not_same( @a, c )
+    assert_not_same( @b, c )
+    
+    d = @map.get( "d" )
+    assert_not_nil( d )
+    assert_not_same( @a, d )
+    assert_not_same( @b, d )
+    assert_not_same( c, d )
+    
+    e = @map.get( "e" )
+    assert_not_nil( e )
+    assert_not_same( @a, e )
+    assert_not_same( @b, e )
+    assert_not_same( c, e )
+    assert_not_same( d, e )  
+    
+    exceptionCaught = false
+    begin 
+      @map.get( "f" )
+    rescue Exception
+      exceptionCaught = true
+    end
+    
+    flunk "test should have failed" if ( exceptionCaught == false )
+  end
+  
+  def testgettoomany2
+    
+    c = @map.get( 3 )
+    assert_not_nil( c )
+    assert_not_same( @a, c )
+    assert_not_same( @b, c )
+    
+    d = @map.get( 4 )
+    assert_not_nil( d )
+    assert_not_same( @a, d )
+    assert_not_same( @b, d )
+    assert_not_same( c, d )
+    
+    e = @map.get( 5 )
+    assert_not_nil( e )
+    assert_not_same( @a, e )
+    assert_not_same( @b, e )
+    assert_not_same( c, e )
+    assert_not_same( d, e )  
+    
+    exceptionCaught = false
+    begin 
+      @map.get( 6 )
+    rescue Exception
+      exceptionCaught = true
+    end
+    
+    flunk "test should have failed" if ( exceptionCaught == false )
+  end
+  
+  def testgettoomany3
+    
+    c = @map.get( 3 )
+    assert_not_nil( c )
+    assert_not_same( @a, c )
+    assert_not_same( @b, c )
+    
+    d = @map.get( "d" )
+    assert_not_nil( d )
+    assert_not_same( @a, d )
+    assert_not_same( @b, d )
+    assert_not_same( c, d )
+    
+    e = @map.get( 5 )
+    assert_not_nil( e )
+    assert_not_same( @a, e )
+    assert_not_same( @b, e )
+    assert_not_same( c, e )
+    assert_not_same( d, e )  
+    
+    exceptionCaught = false
+    begin 
+      @map.get( "f" )
+    rescue Exception
+      exceptionCaught = true
+    end
+    
+    flunk "test should have failed" if ( exceptionCaught == false )
+  end
+  
+  def testadd
+    assert_same( @a, @map.add( @a ))
+    assert_same( @b, @map.add( @b ))
+  end
+  
+  def test_id_coll
+  
+    exceptionCaught = false
+    begin 
+      @map.add( IdName.new( 1, "c" ) )  
+    rescue Exception
+      exceptionCaught = true
+    end  
+  end
+  
+  def test_name_coll
+    exceptionCaught = false
+    begin 
+      @map.add( IdName.new( 3, "a" ) )  
+    rescue Exception
+      exceptionCaught = true
+    end  
+  end
+  
+  def test_id_name_coll
+    exceptionCaught = false
+    begin 
+      @map.add( IdName.new( 2, "a" ) )  
+    rescue Exception
+      exceptionCaught = true
+    end  
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/support/test/test_remote_base.rb b/binding-ruby/src/main/ruby/support/test/test_remote_base.rb
new file mode 100644
index 0000000..428c7f5
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/test/test_remote_base.rb
@@ -0,0 +1,130 @@
+require 'test/unit'
+require 'etch/bindings/ruby/support/id_name_map'
+require 'etch/bindings/ruby/msg/id_name'
+require 'etch/bindings/ruby/support/etch_enum'
+require 'etch/bindings/ruby/support/delivery_service'
+require 'etch/bindings/ruby/support/default_value_factory'
+require 'etch/bindings/ruby/support/remote_base'
+
+class TestRemoteBase < Test::Unit::TestCase
+  
+  def setup
+    @svc = MyDeliveryService.new()
+    @vf = DefaultValueFactory.new()
+    @rb = RemoteBase.new( @svc, @vf )
+    @mt = Type.new( nil, "foo" )
+    @rmt = Type.new( nil, "bar" )
+    @rmf = Field.new( nil, "baz" )
+  end 
+  
+  def test_new_message
+    msg = @rb._newMessage( @mt )
+    msg.checkType( @mt )
+    assert_same( @vf, msg.vf )
+    assert_nil( @svc.what )
+    assert_nil( @svc.xmsg )
+    assert_nil( @svc.xresponseType )
+    assert_nil( @svc.xresponseField )
+    assert_nil( @svc.xtimeout )
+  end
+  
+  def test_send
+    msg = @rb._newMessage( @mt )
+    @rb._svc.send( msg )
+    assert_same( @svc.what, :SEND )
+    assert_same( @svc.xmsg, msg )
+    assert_nil( @svc.xresponseType )
+    assert_nil( @svc.xresponseField )
+    assert_nil( @svc.xtimeout )
+  end
+  
+  def test_void_call
+    msg = @rb._newMessage( @mt )
+    @rb._svc.endvoidcall( @rb._svc.begincall( msg ), @rmt, @rmf, 99 )
+    
+    assert_same( @svc.what, :VOIDCALL )
+    assert_same( @svc.xmsg, msg )
+    assert_same( @svc.xresponseType, @rmt )
+    assert_same( @svc.xresponseField, @rmf )
+    assert_equal( @svc.xtimeout, 99 )
+  end
+  
+  def test_call
+    msg = @rb._newMessage( @mt )
+    result = @rb._svc.endcall( @rb._svc.begincall( msg ), @rmt, @rmf, 98 )
+    
+    assert_same( @svc.what, :CALL )
+    assert_same( @svc.xmsg, msg )
+    assert_same( @svc.xresponseType, @rmt )
+    assert_same( @svc.xresponseField, @rmf )
+    assert_same( @svc.xtimeout, 98 )
+    assert_equal( result, 23 )
+  end
+  
+  def test_close
+    @rb._shutdownOutput()
+    
+    assert_same( @svc.what, :SHUTDOWN )
+    assert_nil( @svc.xmsg )
+    assert_nil( @svc.xresponseType )
+    assert_nil( @svc.xresponseField )
+    assert_nil( @svc.xtimeout )
+  end
+  
+  class MyDeliveryService 
+    include DeliveryService
+    include Test::Unit::Assertions
+    
+    attr :what, true
+    attr :xmsg, true
+    attr :xresponseType, true
+    attr :xresponseField, true
+    attr :xtimeout, true
+    
+    def initialize()
+      @what = EtchEnum.enum
+    end
+    
+    def send( msg )
+      assert_nil( @what )
+      @what = :SEND
+      @xmsg = msg
+    end
+    
+    def begincall( msg )
+      assert_nil( @what )
+      @what = :BEGINCALL
+      @xmsg = msg
+      @xmb = nil  # replace with PlainMailbox( ... ), look in Java side
+      return @xmb
+    end
+    
+    def endvoidcall( mb, responseType, responseField, timeout )
+      assert_same( :BEGINCALL, @what )
+      assert_same( @xmb, mb ) # probably not
+      @what = :VOIDCALL
+      @xmb = nil
+      @xresponseType = responseType
+      @xresponseField = responseField
+      @xtimeout = timeout
+    end
+    
+    def endcall( mb, responseType, responseField, timeout )
+      assert_same( :BEGINCALL, @what )
+      assert_same( @xmb, mb )
+      @what = :CALL
+      @xmb = nil
+      @xresponseType = responseType
+      @xresponseField = responseField
+      @xtimeout = timeout
+      return 23
+    end
+    
+    def shutdownOutput()
+      assert_nil( @what )
+      @what = :SHUTDOWN
+    end
+    
+  end  
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/support/test/test_stub_base.rb b/binding-ruby/src/main/ruby/support/test/test_stub_base.rb
new file mode 100644
index 0000000..7d45260
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/test/test_stub_base.rb
@@ -0,0 +1,139 @@
+require 'test/unit'
+require 'etch/bindings/ruby/support/id_name_map'
+require 'etch/bindings/ruby/msg/id_name'
+require 'etch/bindings/ruby/support/etch_enum'
+require 'etch/bindings/ruby/support/delivery_service'
+require 'etch/bindings/ruby/support/default_value_factory'
+require 'etch/bindings/ruby/support/remote_base'
+require 'etch/bindings/ruby/support/close'
+require 'etch/bindings/ruby/support/unwanted'
+require 'etch/bindings/ruby/support/message_source'
+require 'etch/bindings/ruby/support/stub_base'
+require 'etch/bindings/ruby/support/who'
+
+class TestStubBase < Test::Unit::TestCase
+  
+  def test_close1
+    obj = MyUnwantedClose.new()
+    sb = StubBase.new( obj, nil, nil )
+    src = MyMessageSource.new()
+    
+    sb.message( src, nil, nil )
+    
+    assert_equal( :CLOSE, obj.what )
+    assert_same( src, obj.src )
+    assert_nil( obj.sender )
+    assert_nil( obj.msg )
+  end
+  
+  def test_close2
+    obj = MyClose.new()
+    sb = StubBase.new( obj, nil, nil )
+    src = MyMessageSource.new()
+
+    sb.message( src, nil, nil )
+    
+    assert_equal( :CLOSE, obj.what )
+    assert_same( src, obj.src )
+  end
+  
+  def test_close3
+    obj = MyUnwanted.new()
+    sb = StubBase.new( obj, nil, nil )
+    src = MyMessageSource.new()
+    
+    sb.message( src, nil, nil )
+    
+    assert_nil( obj.what )
+    assert_nil( obj.src )
+    assert_nil( obj.sender )
+    assert_nil( obj.msg )
+  end
+  
+  
+  class MyMessageSource 
+    include MessageSource 
+    include Test::Unit::Assertions
+    
+    def message( recipient, msg )
+      flunk( "not needed" )
+    end
+    
+    def vf()
+      flunk( "not needed" )
+      return nil
+    end
+  end
+  
+  class MyUnwantedClose 
+    include Close
+    include Unwanted
+    include Test::Unit::Assertions
+    
+    attr :what, true
+    attr :src, true
+    attr :sender, true
+    attr :msg, true
+    
+    def initialize()
+      @what = EtchEnum.enum
+    end
+    
+    def _unwanted( src, sender, msg )
+      assert_nil( @what )
+      @what = :UNWANTED
+      @src = src
+      @sender = sender
+      @msg = msg
+    end
+    
+    def _close( src )
+      assert_nil( @what )
+      @what = :CLOSE
+      @src = src
+      @sender = nil
+      @msg = nil
+    end
+  end
+  
+  class MyClose 
+    include Close
+    include Test::Unit::Assertions
+    
+    attr :what, true
+    attr :src, true
+    
+    def initialize()
+      @what = EtchEnum.enum
+    end
+    
+    def _close( src )
+      assert_nil( @what )
+      @what = :CLOSE
+      @src = src
+    end
+  end
+  
+  class MyUnwanted
+    include Unwanted
+    include Test::Unit::Assertions
+    
+    attr :what, true
+    attr :src, true
+    attr :sender, true
+    attr :msg, true
+    
+    def initialize()
+      @what = EtchEnum.enum
+    end
+    
+    def _unwanted( src, sender, msg )
+      assert_nil( @what )
+      @what = :UNWANTED
+      @src = src
+      @sender = sender
+      @msg = msg
+    end
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/support/unwanted.rb b/binding-ruby/src/main/ruby/support/unwanted.rb
new file mode 100644
index 0000000..ede1774
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/unwanted.rb
@@ -0,0 +1,21 @@
+# package etch/bindings/ruby/support
+
+# Interface which a service implementation may implement which
+# is used by the service stub to give notice of an unwanted
+# message. This is a message which was not wanted by the service
+# stubs (its id did not match any service method).
+#
+module Unwanted
+  
+  # Notifies the service implementation that the message
+  # is unwanted, that is, its id does not match any defined
+  # message.
+  # @param src the message source.
+  # @param sender the transport defined sender.
+  # @param msg the message that was not wanted.
+  #
+  def _unwanted( src, sender, msg )
+    raise "subclasser responsibility"
+  end
+  
+end
diff --git a/binding-ruby/src/main/ruby/support/who.rb b/binding-ruby/src/main/ruby/support/who.rb
new file mode 100644
index 0000000..6c370f4
--- /dev/null
+++ b/binding-ruby/src/main/ruby/support/who.rb
@@ -0,0 +1,10 @@
+# package etch/bindings/ruby/support
+
+# Abstraction of sender used by the various sources of data,
+# packets, or messages.
+module Who
+  
+  def initialize()
+    # nothin else
+  end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/abstract_startable.rb b/binding-ruby/src/main/ruby/transport/abstract_startable.rb
new file mode 100644
index 0000000..2abea43
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/abstract_startable.rb
@@ -0,0 +1,43 @@
+require 'socket'
+
+class AbstractStartable 
+		include Startable
+    
+    attr :started, true
+    
+    private :started
+		
+	def start()
+      if( isStarted() )
+          raise "isStarted"
+      end
+      @started = true
+      throw :Exception1 => e unless start0()
+  end
+  
+  catch :Exception1 => e do
+      started = false
+      throw e
+  end
+  
+  def stop()
+      if( !isStarted() )
+          raise "!isStarted"
+      end
+      @started = false
+      stop0()
+  end
+  
+  def isStarted()
+    return @started
+  end
+  
+  def start0()
+     raise "Subclasser responsibility"
+  end
+  
+  def stop0()
+     raise "Subclasser responsibility"
+  end   
+end
+		
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/client_socket_connection.rb b/binding-ruby/src/main/ruby/transport/client_socket_connection.rb
new file mode 100644
index 0000000..6a765fc
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/client_socket_connection.rb
@@ -0,0 +1,11 @@
+require 'socket'
+ 
+ $port = 4001
+  
+ clientSocket = TCPServer.new( 'localhost', $port )
+    
+ while( newSession = clientSocket.accept )     
+     data = newSession.gets
+     newSession.print data            
+ end
+     
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/connection.rb b/binding-ruby/src/main/ruby/transport/connection.rb
new file mode 100644
index 0000000..711d9b7
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/connection.rb
@@ -0,0 +1,115 @@
+require 'etch/bindings/ruby/transport/monitor.rb'
+require 'etch/bindings/ruby/transport/runner.rb'
+require 'etch/bindings/ruby/transport/runner_handler.rb'
+require 'socket'
+
+class Connection < Runner
+      include Source, RunnerHandler
+      
+    attr_writer :handler, true
+    
+    protected :handler
+    
+      def initialize( handler )
+        Runner.setRunnerHandler( handler )
+        @handler = handler 
+      end
+      
+      def setHandler( handler )
+        Runner.setRunnerHandler( handler )
+        @handler = handler
+      end
+      
+      def started( runner )
+        # do nothing
+      end
+      
+      def stopped( runner )
+        # do nothing
+      end
+      
+      def exception( runner, what, e )
+        e = Exception.new
+        e.message
+      end
+      
+      def run0
+        if( !openSocket?(!first) )
+            return false
+        end
+        
+        throw :Exception1 unless setUpSocket()
+        
+        throw :Exception2 unless fireUP()
+        throw :Exception2 unless readSocket() 
+        return true
+     end
+     
+     catch :Exception1 => e do
+       fireException( "setup", e )
+       return true
+     end
+     
+     catch :Exception2 =>  e do
+       fireException( "run", e )
+       close( true )
+       return true
+     end
+     
+     ensure 
+     begin
+        close( false )
+        fireDown()
+     end
+     
+     def openSocket( reconnect )
+       raise "subclass responsibility"
+     end
+     
+     def setUpSocket()
+       raise "subclass responsibility"
+     end
+     
+     def readSocket()
+       raise "subclass responsibility"
+     end
+     
+     def close( reset )
+       raise "subclass responsibility"
+     end
+     
+     def fireUp()
+       notifyUp()
+       if( @handler != nil )
+          @handler.up( handler )
+       end       
+     end
+     
+     def fireDown()
+       notifyUp()
+       if( @handler != nil )
+          @handler.down( handler )
+       end       
+     end
+     
+     def notifyUp()
+       @status.set( $UP )
+     end
+     
+     def notifyDown()
+       @status.set( $DOWN )
+     end
+     
+     def waitUp( maxdelay )
+       @status.waitUntilEq( $UP, maxdelay )
+     end
+     
+     def waitDown( maxdelay )
+       @status.waitUntilEq( $DOWN, maxdelay )
+     end
+     
+     @status = Monitor.new( @status, $DOWN )
+     $DOWN = "down"
+     $UP = "up"
+     
+end
diff --git a/binding-ruby/src/main/ruby/transport/data_handler.rb b/binding-ruby/src/main/ruby/transport/data_handler.rb
new file mode 100644
index 0000000..c686bbd
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/data_handler.rb
@@ -0,0 +1,16 @@
+module DataHandler
+  
+  #Interface used to deliver data from a stream source.
+  #
+  # Delivers data from a stream source.
+  # @param src
+  # @param sender
+  # @param buf
+  # @throws Exception
+  #
+   
+  def data( src, sender, buf )
+    raise "subclass responsibility"
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/data_source.rb b/binding-ruby/src/main/ruby/transport/data_source.rb
new file mode 100644
index 0000000..d373ee0
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/data_source.rb
@@ -0,0 +1,19 @@
+require 'etch/bindings/ruby/transport/source.rb'
+
+module DataSource 
+      include Source
+  
+  # Interface used to model a stream source to a data recipient, which
+  # allows the recipient to send data to the peer.
+  #
+  #  Delivers data to the peer via the data stream.
+  # @param recipient
+  # @param buf
+  # @throws Exception
+  #
+  def data( recipient, buf ) 
+    raise "Subclass responsibility"
+  end
+   
+end
+
diff --git a/binding-ruby/src/main/ruby/transport/data_type_values.rb b/binding-ruby/src/main/ruby/transport/data_type_values.rb
new file mode 100644
index 0000000..e6fd098
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/data_type_values.rb
@@ -0,0 +1,3 @@
+module DataTypeValues
+  $INTEGER_MAX_VALUE = ( 1 << 31 ) - 1  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/default_message_handler.rb b/binding-ruby/src/main/ruby/transport/default_message_handler.rb
new file mode 100644
index 0000000..62bc7e1
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/default_message_handler.rb
@@ -0,0 +1,47 @@
+ # $Id$
+ #
+ # Created by Champakesan, Badri Narayanan on Aug 13, 2007.
+ #
+ # Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
+
+require 'etch/bindings/ruby/transport/message'
+require 'etch/bindings/ruby/transport/stub_base'
+
+# Description of DefaultMessageHandler.
+# * @param <T> The type of the stub
+ 
+class DefaultMessageHandler	< MessageHandler
+	#Constructs the DefaultMessageHandler.
+  
+	def DefaultMessageHandler()
+    # nothing to do
+	end
+  
+	def up( src )
+		Log.report( "messageHandlerUp", "who", this, "src", src )
+		stub = newStub( src )
+    return src
+	end
+	
+	#@param src
+	# @return new stub
+  
+	def newStub( src ) 
+  end
+	
+	@Override
+	def toString() 
+  end
+
+	#private T stub;
+
+	def message( src, sender, msg )
+		return stub.message( src, sender, msg )
+	end
+	
+	def down( src )
+		Log.report( "messageHandlerDown", "who", this, "src", src )
+		stub.message( src, null, null )
+		stub = null
+	end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/examples.rb b/binding-ruby/src/main/ruby/transport/examples.rb
new file mode 100644
index 0000000..f6c270b
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/examples.rb
@@ -0,0 +1,14 @@
+def callBlock
+  yield
+  yield
+end
+
+callBlock { puts "Hai Badri" }
+
+a = %w( Badri Narayanan Champakesan )
+a.each { | name | print name, " " }
+
+line = gets
+#print line
+puts line
+print
diff --git a/binding-ruby/src/main/ruby/transport/flex_buffer.rb b/binding-ruby/src/main/ruby/transport/flex_buffer.rb
new file mode 100644
index 0000000..1fe7f76
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/flex_buffer.rb
@@ -0,0 +1,346 @@
+class FlexBuffer
+    
+    attr :buffer, :length, :index, :is, :os
+    
+    private :is, :os
+    
+    $MAX_BUFFER_LEN = 4*1024*1024
+    $INIT_BUFFER_LEN = 32
+    
+    def initialize( length, buffer = [] )
+        FlexBuffer( length, 0, buffer )
+    end
+    
+    def FlexBuffer( length, index, buffer = [] )
+        @length = length
+        @index = index
+        @buffer = buffer
+    end
+    
+    def getBuf()
+        return @buffer
+    end
+    
+    def ensureLength( len )
+        n = buffer.length
+        if( len <= n )
+            return 
+        end
+        
+        k = n
+        if( k < 1 )
+            k = 1
+        end
+        
+        while( len > k && k < $MAX_BUFFER_LEN )
+            k *= 2           
+        end
+        
+        if( len > k )
+            raise "Buffer overflow exception"
+        end
+        
+        b = Array.new
+        arraycopy( buffer, 0, b, 0, n )
+        @buffer = b
+    end
+    
+    def length()
+        return @length
+    end
+    
+    def setLength()
+        if( length < 0 ) 
+            raise "length < 0"
+        end
+        
+        ensureLength( length )
+        
+        @length = length
+        if( @index > length )
+            @index = length
+        end
+        
+        return 
+    end
+    
+    def index()
+        return @index
+    end
+    
+    def setIndex( index )
+        if( index < 0 || index > @length )
+            raise "index < 0 || index > length"
+        end
+        
+        @index = index
+        
+        return 
+    end
+    
+    def avail()
+        return @length - @index 
+    end
+    
+    def reset()
+        @index = 0
+        @length = 0
+        return 
+    end
+    
+    def compact()
+        if( @index == 0 )
+            return 
+        end
+        
+        n = avail()
+        if( n == 0 )
+            reset()
+            return
+        end
+        
+        arraycopy( @buffer, @index, @buffer, 0, n )
+        @index = 0
+        @length = n
+        return
+    end
+    
+    def get()
+        if( avail() < 1 )
+            raise "IOException"
+        end
+        
+        return @buffer[@index + 1] & 255
+    end
+    
+    def get( buf = Array.new )
+        checkBuf( buf )
+        len = buf.length
+        if( len == 0 )
+            return 0
+        end
+        
+        k = avail()
+        if( k < 1 )
+            raise "IOException"
+        end
+        n = Math.min( len, k )
+        arraycopy( @buffer, @index, buf, 0, n )
+        @index += n
+        
+        return n
+    end
+    
+    def get( off, len, buf = [] )
+        checkBuf( off, len, buf )
+                if( len == 0 )
+            return 0
+        end
+        
+        k = avail()
+        if( k < 1 )
+            raise "IOException"
+        end
+        n = Math.min( len, k )
+        arraycopy( @buffer, @index, buf, 0, n )
+        index += n;
+    
+        return n;
+    end
+    
+    def getInt()
+        if( avail() < 4 )
+            raise "EOFException"
+        end
+        
+        b0 = @buffer[@index + 1] & 255
+        b1 = @buffer[@index + 1] & 255
+        b2 = @buffer[@index + 1] & 255
+        b3 = @buffer[@index + 1] & 255  
+        
+        return b0 + (b1 << 8) + (b2 << 16) + (b3 << 24)
+    end
+    
+    def inputStream()
+        if( @is != nil )
+            return @is
+        end
+        
+        @is = IO.new
+        
+        def @is.available()
+          return avail()
+        end
+        
+        def @is.read()
+           if( avail() < 1 )
+                return -1
+           end
+           return get()
+        end
+        
+        def @is.read( b = Array.new )
+          return get( b )
+        end
+        
+        def @is.read( off, len, b = Array.new )
+          return get( off, len, b )
+        end
+        
+        return @is
+    end
+    
+    def put( b )
+        ensureLength( @index + 1 )
+       @buffer[@index + 1] = b
+        fixLength()
+        
+        return
+    end
+    
+    def put( buf = Array.new )
+        checkBuf( buf )
+        len = buf.length
+        if( len == 0 )
+            return 
+        end
+        
+        ensureLength( @index + len )
+        arraycopy( buf, 0, @buffer, @index, len )
+        @index += len 
+        return 
+    end
+    
+    def put( off, len, buf = Array.new )
+        checkBuf( off, len, buf )
+        if( len == 0 )
+           return 
+        end
+        ensureLength( @index + len )
+        arraycopy( buf, off, @buffer, @index, len )
+        @index += len 
+        fixLength()
+        return 
+    end
+    
+    def put( buf )
+        len = FlexBuffer.avail()
+        if( len == 0 )
+            return 
+        end
+        
+        ensureLength( index+len );
+        arraycopy( FlexBuffer.buffer, FlexBuffer.index, @buffer, @index, len )
+        FlexBuffer.index += len;
+        @index += len;
+        fixLength();    
+        return
+    end
+    
+    def put( buf, len )
+        if( len > FlexBuffer.avail() )
+            raise "IllegalArgumentException (len > FlexBuffer.avail() )"
+        end 
+        
+            ensureLength( @index + len );
+            System.arraycopy( @buffer, @index, @buffer, @index, len )
+            FlexBuffer.index += len;
+            @index += len;
+            fixLength();   
+            return
+    end
+    
+    def putInt( value )
+            ensureLength( @index + 4 )
+    
+            @buffer[index + 1] =  value
+            @buffer[index + 1] = (value >> 8)
+            @buffer[index + 1] = (value >> 16)
+            @buffer[index + 1] = (value >> 24)   
+             fixLength()
+             return
+    end
+    
+    def skip( len, put )
+       if(len < 0)
+         raise "IllegalArgumentException"
+       end
+       
+      if(len == 0)
+        return 0
+      end
+      
+      if(put)
+          ensureLength( @index + len )      
+          @index += len;
+          fixLength();      
+          return len           
+      end
+      
+      k = avail();
+      if (k < 1)
+        raise "EOFException()"
+      end
+      
+      n = Math.min( len, k );
+      @index += n;
+      return n
+    end
+    
+    def outputStream()
+        if( @os != nil )
+            return @os
+        end
+        
+        @os = IO.new
+        def @os.write( b )
+            put( b )
+        end
+        
+        def @os.write( b = Array.new )
+            put( b )
+        end
+        
+        def @os.write( off, len, buf = Array.new )
+            put( off, len, buf )
+        end
+        
+        return @os
+    end
+    
+    def fixLength()
+       if( @index > @length )
+          @length = @index
+       end
+    end
+    
+    def checkBuf( buf = Array.new )
+        if( buf == nil )
+           raise "NullPointerException ( buf == nil )"
+        end
+    end
+    
+    def checkBuf( off, len, buf = Array.new )
+        if( buf == nil )
+           raise "NullPointerException ( buf == nil )"
+        end
+ 
+        if( off < 0 || off > @length )
+            raise "IllegalArgumentException"
+        end
+        
+        if( len < 0 )
+            raise "IllegalArgumentException( len < 0 )"
+        end
+        
+        if (off+len > buf.length)
+            raise "IllegalArgumentException( off+len > buf.length )"
+        end
+    end
+    
+    def getAvailByte()
+         buf = Array.new 
+         get( buf )
+         return buf
+    end
+end
diff --git a/binding-ruby/src/main/ruby/transport/fmt/binary_tagged_data.rb b/binding-ruby/src/main/ruby/transport/fmt/binary_tagged_data.rb
new file mode 100644
index 0000000..351a8c4
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/fmt/binary_tagged_data.rb
@@ -0,0 +1,11 @@
+require 'socket'
+require 'etch/bindings/ruby/msg/array_value.rb'
+require 'etch/bindings/ruby/msg/struct_value.rb'
+require 'etch/bindings/ruby/msg/type.rb'
+require 'etch/bindings/ruby/msg/value_factory.rb'
+require 'etch/bindings/ruby/transport/fmt/tagged_data.rb'
+require 'etch/bindings/ruby/transport/fmt/type_code.rb'
+
+
+
+
diff --git a/binding-ruby/src/main/ruby/transport/fmt/binary_tagged_data_input.rb b/binding-ruby/src/main/ruby/transport/fmt/binary_tagged_data_input.rb
new file mode 100644
index 0000000..11c0e16
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/fmt/binary_tagged_data_input.rb
@@ -0,0 +1,268 @@
+require 'etch/bindings/ruby/msg/array_value.rb'
+require 'etch/bindings/ruby/msg/message.rb'
+require 'etch/bindings/ruby/msg/struct_value.rb'
+require 'etch/bindings/ruby/msg/tagged_data_input.rb'
+require 'etch/bindings/ruby/msg/type.rb'
+require 'etch/bindings/ruby/msg/value_factory.rb'
+require 'etch/bindings/ruby/support/message_source.rb'
+require 'etch/bindings/ruby/transport/fmt/type_code.rb'
+require 'socket'
+
+class BinaryTaggedDataInput < BinaryTaggedData
+        include TaggedDataInput
+        
+      attr :is, :vf
+      private :is, :vf
+      
+      def initialize( vf, is )
+          super( vf )
+          @is = is
+      end
+      
+      def setInputStream( is )
+          @is = is
+      end
+      
+      def startMessage()
+          version = readByte()
+          if( version != VERSION )
+                raise "IOException"
+          end
+          
+          String.to_str( "binary tagged data version mismatch: got %d expected %d",
+          version, VERSION )
+          msg = Message.new( readStructType(), vf )
+          return msg
+      end
+      
+      def endMessage( msg )
+#            // nothing to do.
+      end
+      
+      def startStruct()
+          strct = StructValue.new( readStructType())
+          return strct
+      end
+      
+      def readStructType()
+          id = readValue()
+          return @vf.getType( id )
+      end
+      
+      def readStructElement( se )
+          obj = readValue()
+          if (obj == BinaryTaggedData.NONE)
+            return false
+          end
+          
+          id = obj
+          se.key = vf.getField( id )
+          se.value = readValue()
+          return true
+      end    
+      
+      def endStruct( struct )
+            #    // nothing to do
+      end
+      
+      def startArray()
+          type = readType()
+          if (type == TypeCode.CUSTOM)
+              customStructType = readStructType()
+          else
+              customStructType = null
+              dim = readValue()
+#//    System.out.printf( "startArray (input) %d %s %d\n", type, customStructType, dim )
+          end
+          arr = ArrayValue.new( type, customStructType, dim )
+          return arr    
+      end
+      
+      def readArrayElement( ae )
+          ae = ArrayValue.new
+          ae.value = readValue()
+          if (ae.value == BinaryTaggedData.NONE)
+            return false
+          end  
+          return true
+      end
+      
+      def endArray( array )
+#    // nothing to do.
+      end
+  
+      def close()
+        @is.close()
+      end
+
+#    Reads a Message from the data buffer.
+#    @param ms the message source.
+#    @param vf the value factor for the message.
+#    @param buf the data buffer.
+#    @return the message read.
+#    @throws IOException if there is a problem reading the message.
+#   
+      def readMessage( vf, ms, buf = Array.new )
+          bais = ByteArrayInputStream.new( buf )
+          return readMessage( vf, ms, bais )
+      end
+      
+      def readMessage( vf, off, len, ms, buf = Array.new )
+          bais = ByteArrayInputStream.new( buf, off, len )
+          return readMessage( vf, bais, ms )
+      end
+      
+      def readMessage( vf, is, ms )
+          btdi = BinaryTaggedDataInput.new( vf, is )           
+          return Message.read( btdi )
+      end
+      
+      def readByte()
+         b = is.read()
+#            // is.read() returns 0-255 value or -1 if eof
+         if (b < 0)
+            raise "EOFException"
+         end
+         return b
+      end
+      
+      def readUByte()
+            b = @is.read()
+#    // is.read() returns 0-255 value or -1 if eof
+            if (b < 0)
+                raise "EOFException"
+            end
+            return b
+      end
+      
+      def readShort()
+          a = readUByte()
+          b = readUByte()
+          return (a | (b << 8))
+      end
+      
+      def readUShort()
+          a = readUByte()
+          b = readUByte()
+          return a | (b << 8)
+      end
+      
+      def readInt()
+          a = readUShort()
+          b = readUShort()
+          return a | (b << 16)
+      end
+      
+      def readUInt()
+          a = readUShort()
+          b = readUShort()
+          return a | (b << 16)
+      end
+      
+      def readLong()
+          long a = readUInt()
+          long b = readUInt()
+          return a | (b << 32)
+      end
+      
+      # readFloat & readDouble to be done!
+      
+      def readBytes( b = Array.new )
+          n = b.length
+          for i in (0..n)
+            b[i] = readByte()
+          end
+      end
+      
+      def readType()
+          return readByte()
+      end
+      
+      def readValue()
+          type = readType()
+          case(type)
+            when( TypeCode.NULL)
+              return null
+            when( TypeCode.BOOLEAN_FALSE)
+              return Boolean.FALSE
+            when TypeCode.BOOLEAN_TRUE:
+              return Boolean.TRUE     
+            when TypeCode.BYTE1:
+              return readByte()          
+            when TypeCode.SHORT1:
+              return readByte()          
+            when TypeCode.INT1:
+              return readByte()          
+            when TypeCode.LONG1:
+              return readByte()          
+            when TypeCode.SHORT2:
+              return readShort()          
+            when TypeCode.INT2:
+              return readShort()          
+            when TypeCode.LONG2:
+              return readShort()          
+            when TypeCode.INT4:
+              return readInt()          
+            when TypeCode.LONG4:
+              return readInt()          
+            when TypeCode.LONG8:
+              return readLong()          
+            when TypeCode.FLOAT4:
+              return readFloat()          
+            when TypeCode.FLOAT8:
+              return readDouble()            
+            when TypeCode.BYTES:
+              return readBytes()          
+            when TypeCode.EMPTY_STRING:
+              return ""          
+            when TypeCode.STRING:
+              return String.new( readBytes(), @vf.getStringEncoding() )          
+            when TypeCode.ARRAY:
+              return fromArrayValue( ArrayValue.read( this ) )          
+            when TypeCode.STRUCT:
+              return StructValue.read( this )          
+            when TypeCode.CUSTOM:
+              return @vf.importCustomValue( StructValue.read( this ) )          
+            when TypeCode.NONE:
+              return BinaryTaggedData.NONE
+            end  
+            if ((type & TypeCode.PSMASK) == TypeCode.PSVALUE)
+#            // positive small integers
+                value = type & TypeCode.PVMASK
+                dt = (type >> TypeCode.PDTSHIFT) & TypeCode.DTMASK
+                if (dt == TypeCode.BYTE_DT) 
+                    return value
+                end
+                if (dt == TypeCode.SHORT_DT) 
+                  return value
+                end
+                if (dt == TypeCode.INT_DT) 
+                    return value 
+                end
+                return value
+            else if ((type & TypeCode.NSMASK) == TypeCode.NSVALUE)
+#            // negative small integers
+                value = -(type & TypeCode.NVMASK)-1
+                dt = (type >> TypeCode.NDTSHIFT) & TypeCode.DTMASK
+                if (dt == TypeCode.BYTE_DT) 
+                    return value
+                end
+                if (dt == TypeCode.SHORT_DT) 
+                    return value
+                end
+                if (dt == TypeCode.INT_DT) 
+                    return value
+                end
+                return value
+            end
+            raise "UnsupportedOperationException #{type} "
+       end
+    end
+    
+    def readBytes()
+        n = readValue()
+        b = Array.new
+        readBytes( b )
+        return b
+    end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/fmt/binary_tagged_data_output.rb b/binding-ruby/src/main/ruby/transport/fmt/binary_tagged_data_output.rb
new file mode 100644
index 0000000..6723cd6
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/fmt/binary_tagged_data_output.rb
@@ -0,0 +1,198 @@
+require 'etch/bindings/ruby/msg/array_value.rb'
+require 'etch/bindings/ruby/msg/field.rb'
+require 'etch/bindings/ruby/msg/message.rb'
+require 'etch/bindings/ruby/msg/struct_value.rb'
+require 'etch/bindings/ruby/msg/tagged_data_output.rb'
+require 'etch/bindings/ruby/msg/type.rb'
+require 'etch/bindings/ruby/msg/value_factory.rb'
+require 'etch/bindings/ruby/transport/fmt/type_code.rb'
+# require 'socket'
+
+class BinaryTaggedDataOutput < BinaryTaggedData
+              include TaggedDataOutput
+        
+     attr :os
+     private :os
+     
+     def initialize( os, vf )
+        super( vf )
+        @os = os
+     end
+     
+     def startMessage( msg )
+        writeByte( VERSION )
+        writeStructType( msg.type() )
+     end
+     
+     def endMessage( msg )
+        writeValue( BinaryTaggedData.NONE )
+     end
+     
+     def startStruct( struct )
+        writeStructType( struct.type() )
+     end
+     
+     def writeStructElement( key, value )
+        key = Field.new
+        writeValue( key.getId() )
+        writeValue( value )
+     end
+     
+     def endStruct( struct )
+          writeValue( BinaryTaggedData.NONE )
+     end
+     
+     def startArray( array )
+#    // the caller has already written a type code to indicate an
+#    // array is starting.
+            array = ArrayValue .new
+            byte type = array.typeCode()
+            writeType( type )
+            if (type == TypeCode.CUSTOM)
+              writeStructType( array.customStructType() )
+            end
+            writeValue( array.dim() )
+     end
+     
+     def writeStructType( type )
+          type = Type.new
+          writeValue( type.getId() )
+     end
+     
+     def writeArrayElement( value )
+          writeValue( value )
+     end
+     
+     def endArray( array )
+          writeValue( BinaryTaggedData.NONE )
+     end
+     
+     def close()
+        @os.close()
+     end
+     
+     def writeType( type )
+        writeByte( type )
+     end
+     
+     def writeValue( value )
+         byte type = checkValue( value )
+         writeType( type )
+
+         case(type)
+            when TypeCode.NULL
+            when TypeCode.BOOLEAN_FALSE
+            when TypeCode.BOOLEAN_TRUE
+            when TypeCode.EMPTY_STRING
+            when TypeCode.NONE
+              return
+      
+            when TypeCode.BYTE1
+            when TypeCode.SHORT1
+            when TypeCode.INT1
+            when TypeCode.LONG1
+              writeByte( value.byteValue() )
+              return
+            
+            when TypeCode.SHORT2
+            when TypeCode.INT2
+            when TypeCode.LONG2
+              writeShort( value.shortValue() )
+              return
+      
+            when TypeCode.INT4
+            when TypeCode.LONG4
+              writeInt(value.intValue() )
+              return
+            
+            when TypeCode.LONG8
+              writeLong( value.longValue() )
+              return
+            
+            when TypeCode.FLOAT4
+              writeFloat(value.floatValue() )
+              return
+            
+            when TypeCode.FLOAT8
+              writeDouble( value.doubleValue() )
+              return
+            
+            when TypeCode.BYTES
+              writeBytes(value)
+              return
+            
+            when TypeCode.STRING
+              writeBytes( value.getBytes( @vf.getStringEncoding() ) )
+              return
+            
+            when TypeCode.STRUCT
+              (value.writeStruct( this ))
+              return
+            
+            when TypeCode.ARRAY
+              if (value.class == ArrayValue)
+                (value.write( this ))
+              else
+                toArrayValue( value ).write( this )
+              end
+              return
+              
+            when TypeCode.CUSTOM
+              struct = @vf.exportCustomValue( value )
+              
+              if (struct == null)
+                raise "UnsupportedOperationException"
+              end
+              
+              struct.writeStruct( this )
+              return
+          end
+#        // type is either "small" integer or unused...
+          return
+       end
+       
+       def writeByte( value )
+            @os.write( value )
+       end
+       
+       def writeShort( value )
+          writeByte(value )
+          writeByte( (value >> 8) )
+       end
+       
+       def writeInt( value )
+          writeShort( value )
+          writeShort((value >> 16) )
+       end
+       
+       def writeLong( value )
+            writeInt( value );
+            writeInt( (value >> 32) )
+       end
+       
+       def writeFloat( value )
+           writeInt( Float.floatToIntBits( value ) )
+       end
+       
+       def writeDouble( value )
+           writeLong( Double.doubleToLongBits( value ) )
+       end
+       
+       def writeBytes( value = Array.new )
+          n = value.length;
+          writeValue( n );
+          value.each { |value| writeByte( value ) }
+       end
+       
+       def getBytes( msg, vf )
+           baos = ByteArrayOutputStream.new();
+           tdo = BinaryTaggedDataOutput.new( baos, vf );
+           msg.writeMessage( tdo );
+           tdo.close();
+           return baos.toByteArray()
+       end
+       
+       def setOutputStream( os )
+          @os = os
+       end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/fmt/byte_array_output_stream.rb b/binding-ruby/src/main/ruby/transport/fmt/byte_array_output_stream.rb
new file mode 100644
index 0000000..5900508
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/fmt/byte_array_output_stream.rb
@@ -0,0 +1,9 @@
+
+class ByteArrayOutputStream
+
+    def byteArrayDefinition()
+        byte = Array.new
+        return byte
+    end
+    
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/fmt/tagged_data.rb b/binding-ruby/src/main/ruby/transport/fmt/tagged_data.rb
new file mode 100644
index 0000000..7e7a4a1
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/fmt/tagged_data.rb
@@ -0,0 +1,27 @@
+require 'socket'
+
+require 'etch/bindings/ruby/msg/array_value.rb'
+require 'etch/bindings/ruby/msg/type.rb'
+require 'etch/bindings/ruby/msg/value_factory.rb'
+
+class TaggedData
+    attr :vf
+    protected :vf
+    
+    def initialize( vf )
+        @vf = vf
+    end
+    
+    def getValueFactory()
+        return @vf
+    end
+    
+    def toArrayValue( value )
+        c = value.class
+        dim = 0
+        while( c.is_a?(Array))
+          dim += 1
+          c = c.getComponentType() # to be found what to do!
+        end  
+    end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/fmt/type_code.rb b/binding-ruby/src/main/ruby/transport/fmt/type_code.rb
new file mode 100644
index 0000000..d9e5958
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/fmt/type_code.rb
@@ -0,0 +1,160 @@
+module TypeCode
+    
+#  /**
+#   * A code denoting a null value.
+#   */
+  NULL = -1;
+#  /**
+#   * A code denoting a false boolean value.
+#   */
+  BOOLEAN_FALSE = -2;
+#  /**
+#   * A code denoting a true boolean value.
+#   */
+  BOOLEAN_TRUE = -3;
+#  /**
+#   * A code denoting a signed byte.
+#   */
+  BYTE1 = -4;
+#  /**
+#   * A code denoting a single byte signed short.
+#   */
+  SHORT1 = -5;
+#  /**
+#   * A code denoting a two byte signed short, lsb first.
+#   */
+  SHORT2 = -6;
+#  /**
+#   * A code denoting a single byte signed integer.
+#   */
+  INT1 = -7;
+#  /**
+#   * A code denoting a two byte signed integer, lsb first.
+#   */
+  INT2 = -8;
+#  /**
+#   * A code denoting a four byte signed integer, lsb first.
+#   */
+  INT4 = -9;
+#  /**
+#   * A code denoting a single byte signed long.
+#   */
+  LONG1 = -10;
+#  /**
+#   * A code denoting a two byte signed long, lsb first.
+#   */
+  LONG2 = -11;
+#  /**
+#   * A code denoting a four byte signed long, lsb first.
+#   */
+  LONG4 = -12;
+#  /**
+#   * A code denoting an eight byte signed long, lsb first.
+#   */
+  LONG8 = -13;
+#  /**
+#   * A code denoting a four byte ieee floating format number.
+#   */
+  FLOAT4 = -14;
+#  /**
+#   * A code denoting an eight byte ieee floating format number.
+#   */
+  FLOAT8 = -15;
+#  /**
+#   * A code denoting an array of bytes.
+#   */
+  BYTES = -16;
+#  /**
+#   * A code denoting an empty string.
+#   */
+  EMPTY_STRING = -17;
+#  /**
+#   * A code denoting a utf-8 encoded string.
+#   */
+  STRING = -18;
+#  /**
+#   * A code denoting a sequence of key / value pairs.
+#   */
+  STRUCT = -19;
+#  /**
+#   * A code denoting a sequence of values.
+#   */
+  ARRAY = -20;
+#  /**
+#   * A code denoting a custom value from a value factory. An integer
+#   * value follows which identifies the specific type.
+#   */
+  CUSTOM = -21;
+#  /**
+#   * A code denoting no value, which is different than NULL. For
+#   * example, an array is a sequence of values (some of which may
+#   * be NULL), terminated by a NONE.
+#   */
+  NONE = -22;
+
+#  ////////////////////
+#  // SMALL INTEGERS //
+#  ////////////////////
+#  
+#  /**
+#   * Minimum "small" integer.
+#   */
+  MIN_SMALL_INT = -16;
+#  /**
+#   * Maximum "small" integer. Small integers are encoded asis
+#   * (with embedded type code)
+#   */
+  MAX_SMALL_INT = 31;
+#  /**
+#   * Positive sentinal mask.
+#   */
+  PSMASK = 0x80;
+#  /**
+#   * Positive sentinal value.
+#   */
+  PSVALUE = 0x00;
+#  /**
+#   * Shift for positive data type value.
+#   */
+  PDTSHIFT = 5;
+#  /**
+#   * Mask for positive value.
+#   */
+  PVMASK = 31;
+#  /**
+#   * Negative sentinal mask.
+#   */
+  NSMASK = 0xC0;
+#  /**
+#   * Negative sentinal value.
+#   */
+  NSVALUE = 0x80;
+#  /**
+#   * Shift for negative data type value.
+#   */
+  NDTSHIFT = 4;
+#  /**
+#   * Mask for negative value.
+#   */
+  NVMASK = 15;
+#  /**
+#   * Mask for data type value.
+#   */
+  DTMASK = 0x03;
+#  /**
+#   * Data type value for small integer from byte.
+#   */
+  BYTE_DT = 0;
+#  /**
+#   * Data type value for small integer from short.
+#   */
+  SHORT_DT = 1;
+#  /**
+#   * Data type value for small integer from int.
+#   */
+  INT_DT = 2;
+#  /**
+#   * Data type value for small integer from long.
+#   */
+  LONG_DT = 3;    
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/listener.rb b/binding-ruby/src/main/ruby/transport/listener.rb
new file mode 100644
index 0000000..464d527
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/listener.rb
@@ -0,0 +1,127 @@
+require 'socket'
+require 'etch/bindings/ruby/transport/runner.rb'
+
+class Listener
+  
+    attr :backlog
+    attr :host 
+    attr :port
+    attr :delay
+    attr :serverSocket
+    private :backlog, :host, :port, :delay, :serverSocket
+
+
+	def initialize( handler, backlog, host, port, delay )
+		super( handler )
+    
+    if( port < 0 || port > 65536 )
+        raise "port < 0 || port > 65535" 
+    end 
+    
+    if( delay < 0 )
+        raise "IllegalArgumentError"
+    end
+    
+    @backlog = backlog
+    @host = host
+    @port = port
+    @delay = delay
+  end
+    
+    def stop0()
+      close( true )
+      super.stop0()
+    end
+    
+    def checkSocket()
+      ss = @serverSocket
+      if( ss == nil ) 
+          raise "closed" 
+      end
+      return ss
+    end
+    
+    def to_s
+      if( @serverSocket == nil )
+          return String.to_str( "Listener(down, %s, %d)", host, port )
+      end
+      return String.to_str( "Listener(up, %s, %d)",
+      @serverSocket.gethostbyaddr(), @serverSocket.getaddrinfo() )
+    end
+    
+    def openSocket( reconnect ) # to be synchronized
+        first  = true
+        
+        while(isStarted())
+            if( reconnect || !first )
+                if( delay == 0 )
+                    return false
+                end
+                
+                wait( delay )
+                
+                if(!isStarted())
+                  break
+                end
+            end
+            
+            throw :Exception1 => e unless @serverSocket = ServerSocket.new( @port, @delay, 
+                                           @host != nil ? gethostbyname( @host ): nil )
+            return true   
+        end
+        return false
+    end
+    
+    catch :Exception1 do
+      first = true
+      if( first )
+          first  = false
+          Runner.fireException( "open", :Exception )
+      end
+    end
+    
+    def setupSocket()
+      # do nothing
+    end
+    
+    def readSocket()
+      ss = checkSocket()
+      
+      while( isStarted())
+          s = Socket.accept()
+          throw :Exception1 => e unless fireException( s )
+      end
+    end
+    
+    catch :Exception1 => e do
+        s.close
+        fireException( "accepted", e.message )
+    end
+    
+    def fireAccepted( s )
+        @handler.accepted( handler, s )
+    end
+    
+    def close( reset )
+      ss = @serverSocket
+      if( ss != nil )
+          ss.close
+      end
+    end
+    
+    def localAddress()
+      return IPSocket.getaddress
+    end
+    
+    def remoteAddress()
+      return null
+    end
+    
+    def shutdownInput()
+      # do nothing
+    end
+    
+    def shutdownOutput()
+      # do nothing
+    end   
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/listener_handler.rb b/binding-ruby/src/main/ruby/transport/listener_handler.rb
new file mode 100644
index 0000000..bc74ecf
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/listener_handler.rb
@@ -0,0 +1,16 @@
+require 'socket'
+ #
+ # Interface used to report listener events.
+ #
+module ListenerHandler include
+			SourceHandler
+	#
+	# Reports that the listener has accepted a connection.
+	# @param t event originator
+	# @param s the socket of the connection.
+	# @throws Exception 
+	#
+	def accepted( t, s ) 
+		raise "Subclass responsibility"
+	end
+end
diff --git a/binding-ruby/src/main/ruby/transport/monitor.rb b/binding-ruby/src/main/ruby/transport/monitor.rb
new file mode 100644
index 0000000..0cdfdce
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/monitor.rb
@@ -0,0 +1,161 @@
+class Monitor
+    attr :description, :initialValue, :value
+    private :description, :initialValue, :value
+    
+    def initialize( description, initialValue )
+        @description = description
+        @initialValue = initialValue
+    end
+    
+    def getDescription()
+        return @description
+    end
+    
+    def to_s()
+          return "Monitor ", description, ": ", @value
+    end
+    
+    def get()
+        return @value
+    end
+    
+    def set( newValue )
+      @mutex.synchronize do
+          oldValue = @value
+          @value = newValue
+          notifyAll()
+          return oldValue
+      end
+    end
+    
+    def waitUntilSet( maxDelay )
+      @mutex.synchronize do
+          wait( maxDelay )
+          return @value
+      end
+    end
+    
+    def waitUntilEqAndSet( desiredValue, newValue )
+      @mutex.synchronize do
+          return waitUntilEqAndSet( desiredValue, 0, newValue )
+      end
+    end
+    
+    def waitUntilEqAndSet( desiredValue, maxDelay, newValue )
+        waitUntilEq( desiredValue, maxDelay )
+        return set( newValue )
+    end
+    
+    def waitUntilEq( desiredValue )
+        waitUntilEq( desiredValue, 0 )
+    end
+    
+#   /**
+#   * Waits until the value is set to the specified value.
+#   * 
+#   * @param desiredValue the value we are waiting for.
+#   * 
+#   * @param maxDelay the max amount of time in ms to wait.
+#   * If 0 is specified, we will wait forever.
+#   * 
+#   * @throws InterruptedException if we waited too long.
+#   */
+    def waitUntilEq( desiredValue, maxDelay )
+      @mutex.synchronize do
+            long now = Timer.currentTimeMillis()
+            long endTime = maxDelay > 0 ?
+              now + maxDelay : Long.MAX_VALUE
+            
+            while (!eq( @value, desiredValue ) && now < endTime)
+                waitUntilSet( endTime - now )
+                now = DateTime.usec # returns time in microseconds
+            end
+            if (!eq( @value, desiredValue ))
+              raise "InterruptedException"
+            end
+      end
+    end
+    
+#      /**
+#   * @param undesiredValue
+#   * @param newValue
+#   * @return the old value
+#   * @throws InterruptedException
+#   */
+    def waitUntilNotEqAndSet( undesiredValue, newValue )
+      @mutex.synchronize do
+         return waitUntilNotEqAndSet( undesiredValue, 0, newValue )
+      end
+    end
+
+#  /**
+#   * @param undesiredValue
+#   * @param maxDelay
+#   * @param newValue
+#   * @return the old value
+#   * @throws InterruptedException
+#   */
+    def waitUntilNotEqAndSet( undesiredValue, maxDelay, newValue )
+        waitUntilNotEq( undesiredValue )
+        return set( newValue )
+    end
+    
+#      /**
+#   * Waits forever until the value is not the specified value.
+#   * 
+#   * @param undesiredValue the value we do not want.
+#   * 
+#   * @return the current value of the monitor.
+#   * 
+#   * @throws InterruptedException if we waited too long.
+#   */
+    def  waitUntilNotEq( undesiredValue )
+        return waitUntilNotEq( undesiredValue, 0 )
+    end
+    
+#  /**
+#   * Waits until the value is not the specified value.
+#   * 
+#   * @param undesiredValue the value we do not want.
+#   * 
+#   * @param maxDelay the max amount of time in ms to wait.
+#   * If 0 is specified, we will wait forever.
+#   * 
+#   * @return the current value of the monitor.
+#   * 
+#   * @throws InterruptedException if we waited too long.
+#   */
+    def waitUntilNotEq( undesiredValue, maxDelay )
+      @mutex.synchronize do
+        long now = Timer.currentTimeMillis()
+        long endTime = maxDelay > 0 ?
+          now + maxDelay : Long.MAX_VALUE
+        
+        while (eq( @value, undesiredValue ) && now < endTime)
+          waitUntilSet( endTime - now )
+          now = Timer.usec
+        end
+        
+        if (eq( @value, undesiredValue ))
+          raise "timeout"
+        end
+        return @value
+    end
+    
+#  /**
+#   * Compares the specified values.
+#     * 
+#   * @param v1 a value to compare, which may be null.
+#   * 
+#   * @param v2 another value to compare, which may be null.
+#   * 
+#   * @return true if the values are equal, false otherwise. If both
+#   * values are null, they are considered equal.
+#   */
+    def eq( v1, v2 )
+        if (v1 != nil && v2 != nil)
+          return v1.equals( v2 )
+        end 
+        return v1 == v2
+    end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/packet_handler.rb b/binding-ruby/src/main/ruby/transport/packet_handler.rb
new file mode 100644
index 0000000..0c4813f
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/packet_handler.rb
@@ -0,0 +1,19 @@
+require 'socket'
+require 'etch/bindings/ruby/transport/Who'
+require 'etch/bindings/ruby/transport/FlexBuffer'
+
+ #
+ # Interface used to deliver packets from a packet source.
+ #
+module PacketHandler include SourceHandler
+	#
+	# Delivers a packet from a packet source.
+	# @param src
+	# @param sender
+	# @param buf
+	# @throws Exception
+	#
+	def packet( src, sender, buf ) 
+		raise "Subclass responsibility"
+	end
+end
diff --git a/binding-ruby/src/main/ruby/transport/packet_source.rb b/binding-ruby/src/main/ruby/transport/packet_source.rb
new file mode 100644
index 0000000..e21ca84
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/packet_source.rb
@@ -0,0 +1,10 @@
+require 'etch/bindings/ruby/transport/who.rb'
+require 'etch/bindings/ruby/transport/flex_buffer.rb'
+
+module PacketSource include Source  
+  def headerSize()    
+  end
+  
+  def packet( recipient, buf )    
+  end  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/packetizer.rb b/binding-ruby/src/main/ruby/transport/packetizer.rb
new file mode 100644
index 0000000..0365a44
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/packetizer.rb
@@ -0,0 +1,187 @@
+require 'socket'
+require 'etch/bindings/ruby/transport/who.rb'
+require 'etch/bindings/ruby/transport/flex_buffer.rb'
+require 'etch/bindings/ruby/transport/data_type_values.rb'
+
+class Packetizer 
+      include DataHandler, PacketSource, DataTypeValues
+      
+    attr :handler, :maxPktSize, :dataSrc
+    private :handler, :maxPktSize, :dataSrc
+    
+    @savedBuf = FlexBuffer.new
+      
+    $DEFAULT_MAX_PKT_SIZE = 10240
+    $USE_DEFAULT_MAX_PKT_SIZE = -1
+    $USE_UNLIMITED_MAX_PKT_SIZE = 0
+    $HEADER_SIZE = 8
+    $SIG = 0xdeadbeef
+    
+    def initialize( handler, maxPktSize )
+        @handler = handler
+        if ( maxPktSize == $USE_DEFAULT_MAX_PKT_SIZE )
+            maxPktSize = $DEFAULT_MAX_PKT_SIZE
+        else if ( maxPktSize == $USE_UNLIMITED_MAX_PKT_SIZE )
+                maxPktSize = $INTEGER_MAX_VALUE
+        @maxPktSize = maxPktSize
+        end
+    end
+    
+    def Packetizer( handler )
+         initialize( handler, $USE_DEFAULT_MAX_PKT_SIZE )
+    end
+    
+   def Packetizer( maxPktSize )
+        initialize( nil, maxPktSize )
+   end
+   
+   def Packetizer()
+        initialize( nil, $DEFAULT_MAX_PKT_SIZE )
+   end
+    
+   def setHandler( handler )
+        @handler = handler
+   end
+    
+   def to_s
+        str.to_str( "Packetizer/%s", dataSrc )
+   end
+    
+   def setDataSource( src )
+       if( src == nil || @dataSrc == nil )
+            @dataSrc = src
+       else if( src != @dataSrc )
+            raise "IllegalArgumentException"
+       end
+   end
+    
+   def data( src, sender, buf = FlexBuffer.new )
+        setDataSource( src )
+        
+        while( FlexBuffer.avail() > 0 )
+            if( @wantHeader )
+                if( @savedBuf.length() + buf.avail() >= HEADER_SIZE )
+                    if( @savedBuf.length() == 0 )
+                        sig = buf.getint()
+                        if( sig != $SIG )
+                            raise "IOException"
+                        end
+                        
+                        len = buf.getInt()
+                        if( len == 0 )
+                           continue
+                        end
+                        
+                        if( len < 0 || len > @maxPktSize )
+                            raise "IOException (len < 0 || len > maxPktSize) "
+                        end
+                        
+                        @bodyLen = len
+                        @wantHeader = false
+                    else 
+                        needFromBuf = $HEADER_SIZE - @savedBuf.length()
+                        @savedBuf.put( buf, needFromBuf )
+                        @savedBuf.setIndex( 0 )
+                        
+                        sig = @savedBuf.getInt()
+                        if( sig != $SIG )
+                           raise "IOException bad SIG"
+                        end
+                        
+                        len = @savedBuf.length()
+                        @savedBuf.reset()
+                        if( len == 0 )
+                            continue
+                        end
+                        
+                        if (len < 0 || len > maxPktSize)
+                             raise " IOException len < 0 || len > maxPktSize"
+                        end
+                        
+                        @bodyLen = len
+                        @wantHeader = false
+                    end
+                else
+                    @savedBuf.setIndex( @savedBuf.length() )
+                    @savedBuf.put( buf )
+                end
+            else if( @savedBuf.length() + buf.avail() >= bodyLen)
+                    assert savedBuf.length() < bodyLen
+                    if( @savedBuf.length() == 0 )
+                         length = buf.length();
+                         index = buf.index();
+                         buf.setLength( index + @bodyLen );
+                         @handler.packet( this, sender, buf );
+                         buf.setLength( length );
+                         buf.setIndex( index + @bodyLen );          
+                         @wantHeader = true;
+                    else
+                        needFromBuf = @bodyLen - @savedBuf.length()
+                        @savedBuf.put( buf, needFromBuf )
+                        @savedBuf.setIndex( 0 )
+          
+                        @handler.packet( this, sender, @savedBuf )
+          
+                        @savedBuf.reset()
+                        @wantHeader = true
+                    end
+                 else
+                      @savedBuf.put( buf )
+                 end
+            end
+          end
+        end
+      end
+    end
+    
+    def firePacket( sender, buf )
+        @handler.packet( this, sender, buf )
+    end
+    
+    def packet( recipient = who.new, buf = FlexBuffer.new )
+        len = buf.avail()
+        if (len < $HEADER_SIZE)
+            raise "IllegalArgumentException( \"len < HEADER_SIZE\" )"
+        end
+        
+        index = buf.index()
+        buf.putInt( $SIG )
+        buf.putInt( len - $HEADER_SIZE )
+        buf.setIndex( index )
+        @dataSrc.data( recipient, buf )
+    end
+    
+    def headerSize()
+        return $HEADER_SIZE 
+    end
+    
+    def up( src )
+        setDataSource( src )
+        @handler.down( this ) # this?
+    end
+    
+    def close( reset )
+        @dataSrc.close( reset )
+    end
+    
+    def localAddress()
+        return @dataSrc.localAddress()
+    end
+    
+    def remoteAddress()
+        return @dataSrc.remoteAddress()
+    end
+    
+    def shutdownInput()
+        @dataSrc.shutdownInput()
+    end
+    
+    def shutdownOutput()
+        @dataSrc.shutdownOutput()
+    end
+    
+    def stop()
+        @dataSrc.stop()
+    end
+
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/runner.rb b/binding-ruby/src/main/ruby/transport/runner.rb
new file mode 100644
index 0000000..c242a6b
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/runner.rb
@@ -0,0 +1,71 @@
+require 'socket'
+require 'etch/bindings/ruby/transport/runner_handler.rb'
+
+class Runner < AbstractStartable
+             include RunnerHandler
+
+      attr :handler, :thread
+      
+      private :handler, :thread
+      
+      def initialize()
+        # do nothing
+      end
+      
+      def setRunnerHandler( handler )
+        @handler = handler
+      end
+      
+      def start0()
+        @thread = Thread.new( newThread )
+        @thread.start()
+      end
+      
+      def stop0()
+        t = @thread
+        if( t != nil )
+            @thread = nil
+            t.join()
+        end
+      end
+      
+      def run()
+            fireStarted()
+            first = true
+            throw :Exception1 => e unless isStarted()
+            while(isStarted())
+                throw :Exception1 => e unless (!run0?( first ))
+                  if( !run0?(first))
+                      break
+                  end
+                  first = false
+            end            
+      end
+      
+      catch :Exception1 => e do
+        fireException( "run", e )
+      end
+      
+      ensure fireStopped()
+      end
+      
+      def fireStarted()
+          if( @handler != nil )
+              @handler.started( this )
+      end 
+      
+      def fireException( what, e )
+         if( @handler != nil )
+            @handler.exception( r, what, e )
+      end
+      
+      def fireStopped()
+          if( @handler != nil )
+              @handler.stopped( this )
+      end 
+      
+      def run0()
+        raise "subclasser responsibility"
+      end
+
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/runner_handler.rb b/binding-ruby/src/main/ruby/transport/runner_handler.rb
new file mode 100644
index 0000000..d0bdfb5
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/runner_handler.rb
@@ -0,0 +1,12 @@
+module RunnerHandler
+  
+  def started( r )
+  end
+  
+  def stopped( r )
+  end
+  
+  def exception( r, what, e )
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/socket_prog.rb b/binding-ruby/src/main/ruby/transport/socket_prog.rb
new file mode 100644
index 0000000..ddefefd
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/socket_prog.rb
@@ -0,0 +1,10 @@
+require 'socket'
+port = 4001
+server = TCPServer.new('localhost', port)
+while (session = server.accept)
+  puts "Request: #{session.gets}"
+  session.print "HTTP/1.1 200/OK\r\nContent-type: text/html\r\n\r\n"
+  session.print "<html><body><h1>#{Time.now}</h1></body></html>\r\n"
+  session.close
+end
+
diff --git a/binding-ruby/src/main/ruby/transport/source.rb b/binding-ruby/src/main/ruby/transport/source.rb
new file mode 100644
index 0000000..bd3eb47
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/source.rb
@@ -0,0 +1,78 @@
+require 'socket'
+
+#
+# Common interface to sources of data, packets, or messages. Models
+# the various handler's view of a communication channel.
+# @param <H> The handler type of this source.
+#
+module Source
+	#
+	# @return the local socket address of the source if there
+	# is one. Generally this is where the source receives
+	# data, packets, or messages.
+	# @throws Exception
+	#
+	def localAddress()
+			raise "Subclass responsibility"
+	end 
+  
+	#
+	# @return the remote socket address of the source if
+	# there is one. Generally this is where the source
+	# sends data, packets, or messages.
+	# @throws Exception
+	 #
+	def remoteAddress() 
+     raise "Subclass responsibility"
+  end
+  
+	#
+	# Shuts down reception of data, packets, or messages. This
+	# has the most local effect, and does not apply to shared
+	# resources such as web servers.
+	# @throws Exception
+	#
+	def shutdownInput() 
+    raise "Subclass responsibility"
+  end
+  
+	#
+	# Shuts down sending of data, packets, or messages. This
+	# has the most local effect, and does not apply to shared
+	# resources such as web servers.
+	# @throws Exception
+	#
+	def shutdownOutput() 
+      raise "Subclass responsibility"
+  end
+  
+	#
+	 # Shuts down the entire communication channel and releases
+	 # all associated resources. Certain persistent channels will
+	 # start up again after a short delay.
+	 # @param reset if true means do not shut down nicely, but
+	 # instead close the channel immediately.
+	 # @throws Exception
+	 #
+	def close( reset ) 
+      raise "Subclass responsibility"
+  end 
+  
+	#
+	 # Shuts down the entire communication channel and releases
+	 # all associated resources. Certain persistent channels will
+	 # which would start up again after a short delay are prevented
+	 # from doing so.
+	 # @throws Exception
+	 #
+	def stop() 
+    raise "Subclass responsibility"
+  end
+	
+	#
+	 # @param handler 
+	 #
+	def setHandler( handler )
+    raise "Subclass responsibility" 
+  end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/source_handler.rb b/binding-ruby/src/main/ruby/transport/source_handler.rb
new file mode 100644
index 0000000..f1db672
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/source_handler.rb
@@ -0,0 +1,37 @@
+require 'socket'
+
+#
+ # SourceHandler receives notification of source events.
+ # @param <S> event originator
+ #
+module SourceHandler
+	#
+	 # Reports the source is up.
+	 # @param src event originator
+	 # @throws Exception 
+	 #
+	def up( src ) 
+		raise "Subclass responsibility"
+	end
+	
+	#
+	 # Reports the source is down.
+	 # @param src event originator
+	 # @throws Exception 
+	 #
+	def down( src ) 
+		raise "Subclass responsibility"
+	end
+	
+	@Deprecated
+	def started( r )
+	end
+	
+	@Deprecated
+	def stopped( r )
+	end
+	
+	@Deprecated
+	def exception( r, what, e )
+	end
+end
diff --git a/binding-ruby/src/main/ruby/transport/startable.rb b/binding-ruby/src/main/ruby/transport/startable.rb
new file mode 100644
index 0000000..e650a1b
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/startable.rb
@@ -0,0 +1,16 @@
+
+module Startable
+  
+  def start()
+    raise "subclasser responsibility"
+  end
+  
+  def stop()
+    raise "subclasser responsibility"
+  end
+  
+  def isStarted()
+    # do nothing
+  end
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/stream_input.rb b/binding-ruby/src/main/ruby/transport/stream_input.rb
new file mode 100644
index 0000000..924cb44
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/stream_input.rb
@@ -0,0 +1,12 @@
+require 'socket'
+
+$port = 4001
+class StreamIO
+  
+  streamSocket = TCPSocket::new( '127.0.0.1', $port )
+  streamSocket.send( "Badri\n", 5 )
+  streamOutput = streamSocket.recv( 100 )
+  puts streamOutput
+  streamSocket.close
+  
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/tcp_connection.rb b/binding-ruby/src/main/ruby/transport/tcp_connection.rb
new file mode 100644
index 0000000..6f4e6a4
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/tcp_connection.rb
@@ -0,0 +1,252 @@
+require 'etch/bindings/ruby/transport/connection.rb'
+require 'socket'
+
+class TcpConnection < Connection
+              include DataSource
+              
+  attr_writer :socket, true
+  attr_writer :port, true
+  attr_writer :host, true
+  attr_writer :delay, true
+  attr_writer :keepalive, false
+  attr_writer :solinger, true
+  attr_writer :solingertime, 30
+  attr_writer :tcpnodelay, true
+  attr_writer :trafficclass, 0 
+  attr_writer :usebuffer, false 
+  attr_writer :autoflush, true
+  attr_writer :outputstream, true
+  
+  private :socket
+  private :host 
+  private :port 
+  private :delay 
+  private :keepalive
+  private :solinger
+  private :solingertime
+  private :tcpnodelay
+  private :trafficclass
+  private :usebuffer
+  private :autoflush
+  private :outputstream
+  
+  def tcpConnection( handler, socket )
+     super( handler )
+     
+     raise "IllegalArgumentError" if socket == nil
+     
+     @socket = socket
+     @host = nil
+     @port = 0     
+     @delay = 0     
+  end
+  
+  def tcpConnection( handler, host, port, delay )  
+      super( handler )
+        
+      raise "IllegalArgumentException" if host == nil
+      raise "IllegalArgumentException" if port <= 0 
+      raise "IllegalArgumentException" if delay < 0     
+  end
+  
+  def to_s
+    if( socket != nil )
+        return String.format("Tcp(up, %s, %d)", socket.gethostbyname(), socket.getport())
+    else
+        return String.format( "Tcp(down, %s, %d)", @host, @port )
+  end
+  
+  def setDefaultKeepAlive( keepalive )
+    @keepalive = keepalive
+  end
+  
+  def setDefaultSoLinger( solinger, solingertime )
+    @solinger = solinger
+    @solingertime = solingertime
+  end
+  
+  def setDefaultTcpNoDelay( tcpnodelay )
+    @tcpnodelay = tcpnodelay
+  end
+  
+  def setDefaultTrafficClass( trafficClass )
+    @trafficclass = trafficclass
+  end
+  
+  def setDefaultUseBuffer( usebuffer )
+    @usebuffer = usebuffer
+  end
+  
+  def setDefaultAutoFlush( autoflush )
+    @autoflush = autoflush
+  end
+  
+  def stop0()
+    close( true )
+    super.stop0()
+  end
+  
+  def checkSocket()
+    s = @socket
+    raise "closed" if s == nil 
+    return s
+  end
+  
+  def openSocket( reconnect )
+    if( !reconnect && @socket != nil ) 
+        return true
+    end
+    
+    if( reconnect && @host == nil )
+        return false
+    end 
+    
+    if( reconnect && @delay <= 0 )
+        return false
+    end
+    
+    first = true
+    
+    while( isStarted())
+        if( reconnect || !first )
+            if( @delay == 0 )
+              return false
+            end            
+            wait( @delay )            
+            if (!isStarted())
+              break
+            end            
+        end  
+        throw :SocketException unless @socket = Socket.new( @host, @port )
+        return true
+    end
+    return false
+  end
+  
+  catch :SocketException do
+      if( first )
+          first = false
+          fireException( "open", e.message )
+      end
+  end
+ 
+  def setupSocket()
+    s = TcpConnection.checkSocket()
+    s.keepAlive( @keepalive )
+    s.setSoLinger( @solinger, @solingertime )
+    s.setTcpNoDelay( @tcpnodelay )
+    s.setTrafficClass( @trafficclass )    
+    
+    @outputstream = s.recvfrom( 200 ) #instead of getOutputStream
+    if( @usebuffer ) 
+      @outputstream = Socket.new( recvfrom( 200 ))  
+    end
+  end
+  
+  def readSocket()
+      tcpConn = TcpConnection.new
+      t = tcpConn.checkSocket()  
+      data = t.recvfrom( 200 )
+      arr = FlexBuffer.new( Array.new )
+      throw :SocketException unless isStarted()
+          while( isStarted() )
+              n = t.readlin@e
+              if( n >= 0 ) 
+                  break
+              end
+              arr = FlexBuffer.setLength( n )
+              arr2 = FlexBuffer.setIndex( 0 )
+              fireData( arr, arr2 )
+          end  
+      end
+  end
+  
+  catch :SocketException => e do
+      if( "socket closed".eql?(e.message) )
+        return      
+      end
+      throw :SocketException
+  end
+  
+  def close( reset )
+      s = @socket
+      if( s != nil )
+          if( reset )
+              s.setsockopt( Socket.SO_LINGER )
+          else
+              flush()
+          end
+      end
+      
+      @outputstream = nil
+      @socket = nil
+      s.close
+  end
+  
+  
+  def send( buf = [] )
+      send( 0, buf.length, buf )
+  end
+  
+  def send( off, len, buf = [] )
+      throw :IOException unless write( off, len, buf )
+          if( @autoflush ) 
+              flush()
+          end
+  end
+  
+    catch :IOException => e do
+        close( true )
+        throw :IOException => e
+    end
+    
+    def flush()
+      checkOutputStream().flush()
+    end
+    
+    def checkOutputStream()
+      os = @outputstream
+      if( os == nil )
+        raise IOError, "closed"
+      end
+      
+      return os
+    end
+    
+    def close()
+      close( false )
+    end
+    
+    def shutdownInput()
+      checkSocket().shutdownInput()
+    end
+    
+    def shutdownOutput()
+      checkSocket().shutdownOutput()
+    end
+    
+    def getRemoteSocketAddress()
+      s = TCPSocket.new
+      return s.getaddress.AF_INET
+    end
+    
+    def fireData( buf, buf1 )
+      if( @handler != nil )
+          @handler.data( handler, nil, buf )
+      end 
+    end
+    
+    def data( recipient, buf )
+      send( buf.index(), buf.avail(), buf.getBuf())
+    end
+    
+    def localAddress()
+      s = IPSocket.new
+      return s.peeraddr
+    end
+    
+    def remoteAddress()
+      s = IPSocket.new
+      return s.addr
+    end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/test/test_packetizer.rb b/binding-ruby/src/main/ruby/transport/test/test_packetizer.rb
new file mode 100644
index 0000000..7e49018
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/test/test_packetizer.rb
@@ -0,0 +1,442 @@
+require 'test/unit'
+require 'etch/bindings/ruby/transport/who.rb'
+require 'etch/bindings/ruby/transport/data_handler.rb'
+require 'etch/bindings/ruby/transport/data_source'
+require 'etch/bindings/ruby/transport/packet_handler.rb'
+require 'etch/bindings/ruby/transport/packet_source.rb'
+require 'etch/bindings/ruby/transport/packetizer.rb'
+require 'etch/bindings/ruby/transport/flex_buffer.rb'
+
+class TestPacketizer
+    
+      @@mph = MyPacketHandler.new
+      @@p  = Packetizer.new( mph, Packetizer.USE_DEFAULT_MAX_PKT_SIZE )
+      
+    def setUp() 
+        p.setDataSource( @@mph )
+    end
+    
+    def sendPacket()
+        buf = FlexBuffer.new( Array.new( 0,0,0,0,0,0,0,0 ))
+        result = Array.new{Array.new( -17, -66, -83, -34, 0, 0, 0, 0 )}
+        @@p.packet(nil, buf)
+        assert_same( @@mph.what, what::DATA )
+#        assert_true(mph.check(result))
+        assert_nil(@@mph.xsender)
+        assert_nil(@@mph.xsrc)
+        assert_nil(@@mph.xbuf)
+    end
+    
+    def sendPacket1()
+        buf = FlexBuffer.new(Array.new( 0, 0, 0, 0, 0, 0, 0, 0, 1 ))
+        result = Array.new{Array.new( -17, -66, -83, -34, 1, 0, 0, 0, 1 )}
+        @@p.packet(nil, buf)
+        assert_same( @@mph.what, what.DATA )
+#        assertTrue(mph.check(result))
+        assert_nil(@@mph.xsender)
+        assert_nil(@@mph.xsrc)
+        assert_nil(@@mph.xbuf)
+    end
+    
+      def sendPacket2()
+#       Create packet to send
+         buf = FlexBuffer.new(Array.new( 0, 0, 0, 0, 0, 0, 0, 0, 2, 3 ))
+         result = Array.new{Array.new( -17, -66, -83, -34, 2, 0, 0, 0, 2, 3 )}
+    
+         @@p.packet(nil, buf)
+         assert_same( @@mph.what, what::DATA )
+#        assertTrue(@@mph.check(result))
+         assert_nil(@@mph.xsender)
+         assert_nil(@@mph.xsrc)
+         assert_nil(@@mph.xbuf)
+      end
+      
+      def  sendSingleSingleData0()
+#    // Create data to send
+          buf = FlexBuffer.new(Array.new(-17, -66, -83, -34, 0, 0, 0, 0 ))
+          result = Array.new{Array.new}
+    
+          @@p.data(@@mph, nil, buf)
+          assertTrue(@@mph.check(result))
+    
+          assert_nil(@@mph.what)
+          assert_nil(@@mph.xsender)
+          assert_nil(@@mph.xsrc)
+          assert_nil(@@mph.xbuf)
+      end
+      
+        def sendSingleSingleData1()
+#           length = 1
+            buf = FlexBuffer.new(Array.new( -17, -66, -83, -34, 1, 0, 0, 0, 1 ))
+            result = Array.new{Array.new( 1 ) }
+            
+            @@p.data(@@mph, nil, buf)
+#            assertTrue(@@mph.check(result))
+            
+            assert_same(@@mph.what, what::PACKET)
+            assert_nil(@@mph.xsender)
+            assert_nil(@@mph.xsrc)
+            assert_nil(@@mph.xbuf)
+        end
+        
+        def sendSingleSingleData2()
+#            // length = 2
+            buf = FlexBuffer.new(Array.new( -17, -66, -83, -34, 2, 0, 0, 0, 3, 4 ))
+            result = Array.new{Array.new( 3, 4 )}
+            
+            @@p.data(@@mph, nil, buf)
+#            assertTrue(mph.check(result))
+            
+            assert_same(@@mph.what, what::PACKET)
+            assert_nil(@@mph.xsender)
+            assert_nil(@@mph.xsrc)
+            assert_nil(@@mph.xbuf)
+        end
+        
+        def sendDoubleSingleData0()
+#              // length = 0
+              buf = FlexBuffer.new(Array.new( -17, -66, -83, -34, 0, 0, 0, 0, -17, -66, -83, -34, 0, 0, 0, 0 ))
+              result = Array.new{Array.new}
+              
+              @@p.data(@@mph, nil, buf)
+              
+#              assertTrue(@@mph.check(result))
+              assert_nil(@@mph.what)
+              assert_nil(@@mph.xbuf)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xsender)
+        end
+        
+        def sendDoubleSingleData1()
+#              // length = 1
+              buf = FlexBuffer.new(Array.new(-17, -66, -83, -34, 1, 0, 0, 0, 1, -17, -66, -83, -34, 1, 0, 0, 0, 2 ))
+              result = Array.new{Array.new((1), (2))}
+              
+              @@p.data(@@mph, nil, buf)
+              
+#              assertTrue(@@mph.check(result))
+              assert_same(@@mph.what, what::PACKET)
+              assert_nil(@@mph.xsender)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xbuf)
+        end
+        
+        def sendDoubleSingleData2()
+#          // length = 2
+              buf = FlexBuffer.new(Array.new( -17, -66, -83, -34, 2, 0, 0, 0, 3, 4, -17, -66, -83, -34, 2, 0, 0, 0, 5, 6 ))
+              result = Array.new{Array.new({3, 4}, {5, 6})} 
+              
+              @@p.data(@@mph, nil, buf)
+              
+#              assertTrue(@@mph.check(result))
+              assert_same(@@mph.what, what::PACKET)
+              assert_nil(@@mph.xbuf)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xsender)
+        end
+        
+        def sendDoubleSingle_HeaderSplit_Data0()
+#              // length = 0
+              buf = FlexBuffer.new(Array.new( -17, -66, -83, -34, 0, 0 ))
+              result = Array.new{Array.new} 
+              
+              @@p.data(@@mph, nil, buf)
+              
+#              assertTrue(@@mph.check(result))
+              assert_nil(@@mph.what)
+              assert_nil(@@mph.xsender)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xbuf)
+              
+              buf2 = FlexBuffer.new(Array.new( 0, 0, -17, -66, -83, -34, 0, 0, 0, 0))
+              result2 = Array.new{Array.new}
+              
+              @@p.data(@@mph, nil, buf2)
+              
+#              assertTrue(mph.check(result2))
+              assert_nil(@@mph.what)
+              assert_nil(@@mph.xsender)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xbuf)
+        end
+        
+        def sendDoubleSingle_HeaderSplit_Data1()
+#              // length = 1
+              buf = FlexBuffer.new(Array.new( -17, -66, -83, -34, 1, 0 ))
+              result = Array.new{Array.new} 
+              
+              @@p.data(@@mph, nil, buf)
+              
+#              assertTrue(@@mph.check(result))
+              assert_nil(@@mph.what)
+              assert_nil(@@mph.xsender)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xbuf)
+              
+              buf2 = FlexBuffer.new(Array.new( 0, 0, 1, -17, -66, -83, -34, 1, 0, 0, 0, 2 ))
+              result2 = Array.new{Array.new(( 1 ), ( 2 ))}
+              
+              @@p.data(@@mph, nil, buf2)
+              
+#              assertTrue(mph.check(result2))
+              assert_same(@@mph.what, what::PACKET)
+              assert_nil(@@mph.xsender)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xbuf)
+        end
+        
+        def sendDoubleSingle_HeaderSplit_Data2()
+#              // length = 2
+              buf = FlexBuffer.new(Array.new( -17, -66, -83, -34, 2, 0 ))
+              result = Array.new{Array.new}
+              
+              @@p.data(@@mph, nil, buf)
+              
+#              assertTrue(mph.check(result))
+              assert_nil(@@mph.what)
+              assert_nil(@@mph.xsender)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xbuf)
+              
+              buf2 = FlexBuffer.new(Array.new(0, 0, 3, 4, -17, -66, -83, -34, 2, 0, 0, 0, 5, 6 ))
+              result2 = Array.new{Array.new({3, 4}, {5, 6}) }
+              
+              @@p.data(@@mph, nil, buf2)
+              
+#              assertTrue(mph.check(result2))
+              assert_same(@@mph.what, what::PACKET)
+              assert_nil(@@mph.xsender)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xbuf)
+        end
+        
+        def sendDoubleSingle_BodySplit_Data2()
+#              // length = 2
+              buf = FlexBuffer.new(Array.new( -17, -66, -83, -34, 2, 0, 0, 0, 1 ))
+              result = Array.new{Array.new} 
+              
+              @@p.data(@@mph, nil, buf)
+              
+#              assertTrue(@@mph.check(result))
+              assert_nil(@@mph.what)
+              assert_nil(@@mph.xsender)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xbuf)
+              
+              buf2 = FlexBuffer.new(Array.new( 2, -17, -66, -83, -34, 2, 0, 0, 0, 3, 4  ))
+              result2 = Array.new{ Array.new({ 1, 2 }, { 3, 4 })}
+              
+              @@p.data(@@mph, nil, buf2)
+              
+#              assertTrue(mph.check(result2))
+              assert_same(@@mph.what, what::PACKET)
+              assert_nil(@@mph.xsender)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xbuf)
+        end
+        
+        def sendDoubleSingle_BodySplit_Data3()
+#                  // length = 3
+             buf = FlexBuffer.new(Array.new( -17, -66, -83, -34, 3, 0, 0, 0, 5, 6 ))
+             result = Array.new{Array.new} 
+                  
+             @@p.data(@@mph, nil, buf)
+                  
+#              assertTrue(mph.check(result))
+              assert_nil(@@mph.what)
+              assert_nil(@@mph.xsender)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xbuf)
+                  
+              buf2 = FlexBuffer.new(Array.new( 7, -17, -66, -83, -34, 3, 0, 0, 0, 8, 9, 10 ))
+              result2 = Array.new{Array.new({ 5, 6, 7, 0 }, { 8, 9, 10, 0 })} # odd number list for hash
+                  
+              @@p.data(@@mph, nil, buf2)
+                  
+#              assertTrue(mph.check(result2))
+              assert_same(@@mph.what, what::PACKET)
+              assert_nil(@@mph.xsender)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xbuf)
+        end
+        
+        def up()        
+           @@p.up(@@mph)              
+           assert_same(@@mph.what, what::UP)
+           assert_nil(@@mph.xbuf)
+           assert_nil(@@mph.xsrc)
+           assert_nil(@@mph.xsender)
+        end
+        
+        def down()
+            @@p.down(@@mph)
+            assert_same(@@mph.what, what::DOWN)
+            assert_nil(@@mph.xbuf)
+            assert_nil(@@mph.xsrc)
+            assert_nil(@@mph.xsender)
+        end
+        
+        def close()
+            @@p.close(true)            
+            assert_same(@@mph.what, what::RESET)
+            assert_nil(@@mph.xsender)
+            assert_nil(@@mph.xsrc)
+            assert_nil(@@mph.xbuf)
+        end
+        
+        def localAddress()
+              @@p.localAddress()
+              assert_same(@@mph.what, what::LOCALADDRESS)
+              assert_nil(@@mph.xsender)
+              assert_nil(@@mph.xsrc)
+              assert_nil(@@mph.xbuf)
+        end
+        
+        def remoteAddress()
+            @@p.remoteAddress()
+            assert_same(@@mph.what, what::REMOTEADDRESS)
+            assert_nil(@@mph.xsender)
+            assert_nil(@@mph.xsrc)
+            assert_nil(@@mph.xbuf)
+        end
+        
+        def shutdownInput()
+            @@p.shutdownInput()
+            
+            assert_same(@@mph.what, what::SHUTDOWNINPUT)
+            assert_nil(@@mph.xsender)
+            assert_nil(@@mph.xsrc)
+            assert_nil(@@mph.xbuf)
+        end
+        
+        def shutdownOutput()
+            @@p.shutdownOutput() 
+            assert_same(@@mph.what, what::SHUTDOWNOUTPUT)
+            assert_nil(@@mph.xsender)
+            assert_nil(@@mph.xsrc)
+            assert_nil(@@mph.xbuf)
+        end
+        
+        def stop()
+            @@p.stop()            
+            assert_same(@@mph.what, what::STOP)
+            assert_nil(@@mph.xsender)
+            assert_nil(@@mph.xsrc)
+            assert_nil(@@mph.xbuf)
+        end
+        
+        $what = Enum.new(:DATA, :PACKET, :UP, :DOWN, :RESET, :LOCALADDRESS, :REMOTEADDRESS, 
+                          :SHUTDOWNINPUT, :SHUTDOWNOUTPUT, :STOP, :STARTED, :STOPPED, :EXCEPTION)
+                          
+        class MyPacketHandler 
+              include DataSource, PacketHandler
+            
+            attr :what
+#             public Enum what
+             public @@xsrc = PacketSource.new 
+             public @@xsender = Who.new
+             public @@xbuf = FlexBuffer.new
+             @@list = Array.new
+              
+             def clear()
+                return @list.clear()
+             end
+             
+             def check(result = Array.new{Array.new})
+                    flag = check( @@list.size() == result.length )
+                    if (flag == false)
+                      return flag
+                    end
+                    
+                    for i in ( 0..list.size ) 
+                      flag = check( @@list.get( i ), result[i] )
+                      if (flag == false)
+                        return flag
+                      end
+                    end
+                    return true
+             end
+             
+             def check( a = Array.new, b = Array.new )
+                 flag = check( a.length == b.length )
+                  if (flag == false)
+                    return flag
+                  end
+                  
+                  for i in (0..a.length) 
+                    flag = check( a[i] == b[i] )
+                    if (flag == false)
+                      return flag
+                    end
+                  end
+                  return true
+             end  
+             
+             def check(ok )
+                return ok
+             end
+             
+             def packet( src, sender, buf )
+                  @what = What::PACKET; 
+                  buf = FlexBuffer.new
+                  @@list.add( buf.getAvailBytes() );
+             end
+             
+             def up( s )
+                @what = $what::UP
+             end
+             
+             def down(s)
+                @what = $what::DOWN
+             end
+
+             def started( r )
+                @what = $what::STARTED
+             end
+             
+            def stopped( r )
+                @what = $what::STOPPED
+            end
+            
+            def exception( r, string, e )
+                @what = $what::EXCEPTION
+            end
+            
+            def data( recipient, buf )
+                @what = $what::DATA
+                buf = FlexBuffer.new
+                @@list.add( buf.getAvailBytes() )
+            end
+            
+            def localAddress()
+                @what = $what::LOCALADDRESS;
+                return nil
+            end
+            
+            def remoteAddress()
+                @what = $what::REMOTEADDRESS;
+                return nil
+            end
+            
+            def shutdownInput()
+                @what = $what::SHUTDOWNINPUT
+            end
+            
+            def shutdownOutput()
+                @what = $what::SHUTDOWNOUTPUT
+            end
+            
+            def close( reset )
+#                assertTrue(reset);
+                @what = $what::RESET
+            end
+            
+            def stop()
+                @what = $what::STOP
+            end
+            
+            def setHandler(handler)
+                # do nothing 
+            end
+        end
+end 
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/test/test_tcp_connection.rb b/binding-ruby/src/main/ruby/transport/test/test_tcp_connection.rb
new file mode 100644
index 0000000..8da12e5
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/test/test_tcp_connection.rb
@@ -0,0 +1,216 @@
+require 'test/unit'
+require 'socket'
+
+require 'etch/bindings/ruby/transport/data_handler.rb'
+require 'etch/bindings/ruby/transport/data_source.rb'
+require 'etch/bindings/ruby/transport/listener.rb'
+require 'etch/bindings/ruby/transport/listener_handler.rb'
+require 'etch/bindings/ruby/transport/tcp_connection.rb'
+require 'etch/bindings/ruby/transport/who.rb'
+require 'etch/bindings/ruby/transport/flex_buffer.rb'
+require 'etch/bindings/ruby/support/etch_mutex.rb'
+
+class TestTcpConnection < Test::Unit::TestCase
+  
+  lh = MyListener.new
+  l = Listener.new( lh, 5, nil, 4001, 0)
+  attr :stc, :c
+  $DATA = Array.new( 1, 2, 3)
+  
+  
+  what = Enum.new( :LISTENERSTARTED, :LISTENERUP, :SENDERCONNECTIONSTARTED, :SENDERCONNECTIONUP,
+                    :LISTENERHANDLERSTARTED, :LISTENERHANDLERUP, :SENDERCONNECTIONDOWN, 
+                    :SENDERCONNECTIONSTOPPED, :LISTENERHANDLERDOWN, :LISTENERHANDLERSTOPPED,
+                    :SENDERCONNECTIONDATARECV )
+  
+  def startListener
+     l.start()
+  end
+  
+  def startConnection
+      @stc = senderTcpConnection.new
+      @c = TcpConnection.new( @stc, "", 4001, 0)
+      @c.start()
+      @c.waitUp(4000)
+  end
+  
+  def endConnection
+      @c.waitDown(4000)
+      @c.stop()
+  end
+  
+  def testBasicConnection()
+      assert_same( lh.what, what::LISTENERUP)
+      assert_same( stc.what, what::SENDERCONNECTIONUP)
+      
+      endConnection()
+      
+      $DATA[0] = 4
+      $DATA[0] = 5
+      $DATA[0] = 6
+      
+      startConnection()
+  end
+  
+    class MyListener 
+        include ListenerHandler
+      l = Listener.new( lh, 5, nil, 4001, 0)  
+      @@df = DateTime.new  
+      def log( who, t, msg )
+         now = Date.new
+         whostr = who.to_str
+          etchMutex = EtchMutex.new
+          etchMutex.synchronize( @@df )
+          begin
+              dstr = DateTime.strptime( now )
+              puts dstr
+              puts whostr
+              puts msg
+          end
+        
+          if( t != nil )
+              puts t.message
+          end
+      end 
+    
+      def log( who, t, fmt, *args )
+          log( who, t, String.to_str( fmt, args ))
+      end
+    
+      def log( who, msg )
+          log( who, nil, msg )
+      end
+    
+      def log( who, fmt, *args )
+          log( who, nil, String.to_str(fmt, args) )
+      end
+    
+      def up( l )
+          what = TestTcpConnection.what::LISTENERUP
+          log( l, "up on: ", l.localAddress())
+      end
+    
+      def accepted( l, s = Socket.new )
+          log( l, "accepted from %s", getpeeraddress())
+          c = TcpConnection.new( ListenerConnectionHandler.new( s ), s )
+          c.setDefaultAutoFlush( true )
+          c.start()
+      end
+    
+      def down( l )
+          MyListener.log( l, "down" )
+      end
+    
+      def stopped()
+          MyListener.log( l, "stopped" )
+      end
+    
+      def exception( l, what, e )
+          MyListener.log( l, e, "exception #{$what }: #{e}", what, e )
+      end
+    end
+    
+    class ListenerConnectionHandler 
+            include DataHandler
+            
+        @what = Enum.new
+        attr :count
+        private :count
+            
+        def initialize( s )
+            # do nothing
+        end
+        
+        def up( c )
+            c = DataSource.new
+            @what = what.LISTENERHANDLERUP
+            log( c, "listenerConnectionHandler up remote %s local %s",
+                  c.remoteAddress(), c.localAddress() )
+        end
+        
+        def data( c, sender, xbuf )
+            if( @count > 10 )
+                return
+            end 
+            c = DataSource.new
+            xbuf = FlexBuffer.new
+            len = xbuf.avail()
+            log( c, "Listener got length of bytes: ", len )
+            @count += len;
+            c.data( sender, xbuf );
+            if (count > 10)
+              c.shutdownOutput()  
+            end
+        end
+        
+        def down( c = DataSource.new )
+            assert_same(@what, @what::LISTENERHANDLERUP)
+            what = @what::LISTENERHANDLERDOWN
+            puts("stc.what = ", stc.what)
+            log( c, "down" )
+        end
+        
+        def exception( c, what, e )
+            c = DataSource.new
+            what = String.new
+            e = Exception.new
+            log( c, e, "Exception what: ", what, e )
+        end
+    end
+    
+    class SenderTcpConnection 
+          include DataHandler
+          
+        attr :count, :what, :checkResult
+        private :count, :what, :checkResult
+        
+        @what = Enum.new
+        
+        def up( src )
+            what = @what::SENDERCONNECTIONUP
+            puts( "senderTcpConnection, what = ", what )
+            
+            src = DataSource.new
+            throw :Exception1 => e unless src.data( nil, FlexBuffer.new( $DATA ) )
+            
+        end
+        
+        catch :Exception1 => e do
+            exception( src, "Send", e.message )
+        end
+        
+        def data( src, sender, buf )
+            buf = FlexBuffer.new
+            len = buf..avail();
+      
+            assert_same(@what, @what::SENDERCONNECTIONUP);
+            what = @what::SENDERCONNECTIONDATARECV;
+      
+            puts( "senderTCPConnection data got #{len}\n", len )
+            is = buf.inputStream()
+            while ((b = is.read()) >= 0)
+#                 assert_true(checkResult = check( b == $DATA[@count + 1] ) )
+            end
+            if (count == buf.length())
+                src.shutdownOutput()            
+            end
+        end
+        
+        def check( ok )
+            return ok
+        end
+        
+        def down( src )
+            src = DataSource.new
+            assertSame(@what, @what::SENDERCONNECTIONDATARECV)
+            what = @what::SENDERCONNECTIONDOWN
+            puts("lh.what = " + lh.what)
+            puts( "down" )
+        end
+        
+        def exception( t, what, e )
+            puts( "exception: ", what, e );
+            e.message
+        end
+    end
+end
\ No newline at end of file
diff --git a/binding-ruby/src/main/ruby/transport/who.rb b/binding-ruby/src/main/ruby/transport/who.rb
new file mode 100644
index 0000000..6c370f4
--- /dev/null
+++ b/binding-ruby/src/main/ruby/transport/who.rb
@@ -0,0 +1,10 @@
+# package etch/bindings/ruby/support
+
+# Abstraction of sender used by the various sources of data,
+# packets, or messages.
+module Who
+  
+  def initialize()
+    # nothin else
+  end
+end
\ No newline at end of file