diff --git a/build.xml b/build.xml
index 741b669ff..5118b5b50 100644
--- a/build.xml
+++ b/build.xml
@@ -18,7 +18,7 @@
-
@@ -36,6 +36,7 @@
+
@@ -163,7 +164,7 @@
-
@@ -241,7 +242,7 @@
-
+
@@ -252,6 +253,7 @@
+
@@ -283,6 +285,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
DisconnectEvent;
+}
\ No newline at end of file
diff --git a/src/cpp/presents/InvocationDecoder.cpp b/src/cpp/presents/InvocationDecoder.cpp
new file mode 100644
index 000000000..1249b4005
--- /dev/null
+++ b/src/cpp/presents/InvocationDecoder.cpp
@@ -0,0 +1,9 @@
+#include "stable.h"
+#include "InvocationDecoder.h"
+
+using namespace presents;
+
+InvocationDecoder::InvocationDecoder(utf8 rcode) :
+ receiverCode(rcode)
+{
+}
\ No newline at end of file
diff --git a/src/cpp/presents/InvocationDecoder.h b/src/cpp/presents/InvocationDecoder.h
new file mode 100644
index 000000000..0cea2122f
--- /dev/null
+++ b/src/cpp/presents/InvocationDecoder.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "Streamable.h"
+
+namespace presents
+{
+ class InvocationDecoder {
+ public:
+ const utf8 receiverCode;
+ InvocationDecoder(utf8 receiverCode);
+ virtual void dispatchNotification(int8 methodId, const std::vector< Shared >& args) = 0;
+
+ private:
+ // not implemented
+ InvocationDecoder (const InvocationDecoder&);
+ InvocationDecoder& operator= (const InvocationDecoder&);
+ };
+}
\ No newline at end of file
diff --git a/src/cpp/presents/ObjectInputStream.cpp b/src/cpp/presents/ObjectInputStream.cpp
new file mode 100644
index 000000000..ed429bde9
--- /dev/null
+++ b/src/cpp/presents/ObjectInputStream.cpp
@@ -0,0 +1,100 @@
+#include "stable.h"
+
+#include
+
+#include "ObjectInputStream.h"
+#include "PresentsError.h"
+#include "presents/io/InputStream.h"
+
+#include "Streamer.h"
+
+#include "Util.h"
+bool ObjectInputStream::readBoolean ()
+{
+ return readByte() != 0;
+}
+
+namespace
+{
+ template
+ T readInteger(presents::InputStream* in)
+ {
+ T value;
+ assert(in->read(&value, sizeof(T)) == sizeof(T));
+ return presents::presentsToHost(value);
+ }
+}
+
+int8 ObjectInputStream::readByte ()
+{
+ return readInteger(_in);
+}
+
+int16 ObjectInputStream::readShort ()
+{
+ return readInteger(_in);
+}
+
+int32 ObjectInputStream::readInt ()
+{
+ return readInteger(_in);
+}
+
+int64 ObjectInputStream::readLong ()
+{
+ return readInteger(_in);
+}
+
+void ObjectInputStream::readBytes (uint8* bytes, size_t length)
+{
+ _in->read(bytes, length);
+}
+
+float ObjectInputStream::readFloat ()
+{
+ float value;
+ readBytes((uint8*) &value, 4);
+ return value;
+}
+
+double ObjectInputStream::readDouble ()
+{
+ double value;
+ readBytes((uint8*) &value, 8);
+ return value;
+}
+
+utf8 ObjectInputStream::readUTF ()
+{
+ uint16 dataLength = readInteger(_in);
+ boost::scoped_array data(new uint8[dataLength]);
+ readBytes((uint8*)&data[0], dataLength);
+ return std::string((char*)&data[0], dataLength);
+}
+
+Shared ObjectInputStream::readObject ()
+{
+ int16 code = readShort();
+ if (code == 0) {
+ return Shared();
+ }
+
+ Streamer* streamer;
+ if (code < 0) {
+ code *= -1;
+
+ utf8 name = readUTF();
+
+ streamer = getStreamer(name);
+ ClassMapping cmap = { code, streamer };
+ _classMap.insert(_classMap.begin() + code, cmap);
+
+ } else {
+ streamer = (&_classMap[code])->streamer;
+ if (streamer == NULL) {
+ throw PresentsError((boost::format("Unknown streamer code '%1%'") % code).str());
+ }
+ }
+
+ return streamer->createObject(*this);
+}
\ No newline at end of file
diff --git a/src/cpp/presents/ObjectInputStream.h b/src/cpp/presents/ObjectInputStream.h
new file mode 100644
index 000000000..322507004
--- /dev/null
+++ b/src/cpp/presents/ObjectInputStream.h
@@ -0,0 +1,49 @@
+//
+// $Id$
+
+#pragma once
+
+#include "ClassMapping.h"
+#include "Streamer.h"
+
+namespace presents { class InputStream; }
+
+using namespace presents;
+
+class ObjectInputStream
+{
+public:
+ ObjectInputStream (presents::InputStream* stream) : _in(stream), _classMap(1) { }
+
+ bool readBoolean ();
+ int8 readByte ();
+ int16 readShort ();
+ int32 readInt ();
+ int64 readLong ();
+ void readBytes (uint8* bytes, size_t length);
+ float readFloat ();
+ double readDouble ();
+ utf8 readUTF ();
+
+ Shared readObject ();
+
+ template
+ Shared readField ()
+ {
+ return boost::static_pointer_cast(readField(getJavaName((const T*)NULL)));
+ }
+
+ Shared readField (utf8 javaname)
+ {
+ if (readBoolean()) {
+ return getStreamer(javaname)->createObject(*this);
+ } else {
+ return Shared();
+ }
+ }
+
+protected:
+ presents::InputStream* _in;
+ typedef std::vector ClassMap;
+ ClassMap _classMap;
+};
diff --git a/src/cpp/presents/ObjectOutputStream.cpp b/src/cpp/presents/ObjectOutputStream.cpp
new file mode 100644
index 000000000..10f58fae4
--- /dev/null
+++ b/src/cpp/presents/ObjectOutputStream.cpp
@@ -0,0 +1,81 @@
+#include "stable.h"
+
+#include "presents/io/OutputStream.h"
+#include "ObjectOutputStream.h"
+
+#include "Streamable.h"
+#include "Streamer.h"
+#include "Util.h"
+
+#pragma warning (disable: 4100) // unreferenced parameter
+
+using namespace presents;
+
+namespace {
+template
+static void writeInteger(OutputStream* out, T value)
+{
+ value = hostToPresents(value);
+ out->write((uint8*)&value, sizeof(value));
+}
+}
+
+void ObjectOutputStream::writeBoolean (bool value)
+{
+ writeInteger(_out, (uint8)(value ? 1 : 0));
+}
+
+void ObjectOutputStream::writeByte (int8 value)
+{
+ writeInteger(_out, value);
+}
+
+void ObjectOutputStream::writeLong (int64 value)
+{
+ writeInteger(_out, value);
+}
+
+void ObjectOutputStream::writeInt (int32 value)
+{
+ writeInteger(_out, value);
+}
+
+void ObjectOutputStream::writeShort (int16 value)
+{
+ writeInteger(_out, value);
+}
+
+void ObjectOutputStream::writeBytes (const uint8* bytes, size_t length)
+{
+ _out->write(bytes, length);
+}
+
+void ObjectOutputStream::writeDouble (double value)
+{
+ _out->write((uint8*) &value, 8);
+}
+
+void ObjectOutputStream::writeFloat (float value)
+{
+ _out->write((uint8*) &value, 4);
+}
+
+void ObjectOutputStream::writeUTF (const utf8& value)
+{
+ size_t bytesToWrite = value.size() * sizeof(uint8);
+ writeShort(bytesToWrite);
+ _out->write((uint8*)value.data(), value.size());
+}
+
+void ObjectOutputStream::writeBareObject (const Shared& object, Streamer* streamer)
+{
+ streamer->writeObject(object, *this);
+}
+
+void ObjectOutputStream::writeField (const Shared& object, const utf8& javaName)
+{
+ writeBoolean(object != NULL);
+ if (object != NULL) {
+ writeBareObject(object, getStreamer(javaName));
+ }
+}
diff --git a/src/cpp/presents/ObjectOutputStream.h b/src/cpp/presents/ObjectOutputStream.h
new file mode 100644
index 000000000..50d2da487
--- /dev/null
+++ b/src/cpp/presents/ObjectOutputStream.h
@@ -0,0 +1,89 @@
+//
+// $Id$
+
+#pragma once
+
+#include
+#include