diff --git a/.gitignore b/.gitignore
index b3b54fa1bfc1d1d1c86d781f963f5b4be743c1b5..a8e501f0032529b7fb206ad50fb5c5a84ec099a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ java/dist
 java/privateprops
 java/.project
 java/.classpath
+*.pyc
 .project
 .classpath
 **/.*.swp
diff --git a/java/build.properties b/java/build.properties
index e7fc61f58e49c8abd77c45acfc9bd1d372609720..8c6fc149f768d847b59e7027cffd5e871b7ef777 100644
--- a/java/build.properties
+++ b/java/build.properties
@@ -2,5 +2,5 @@ language=java
 resolve.status=beta
 resource.path=
 #resource.path=${shared.repository}/Humanoids;${shared.repository}/3dmodels;${shared.repository}/HMI/HmiElckerlyc/resources;${shared.repository}/logbackconfig;${shared.repository}/shaders;
-run.jvmargs= -Xms128m -Xmx512m  -Xss5M -Dlogback.configurationFile=LogbackConfigs/warnlogstdout.xml
+run.jvmargs= -Xms128m -Xmx512m  -Xss5M
 rebuild.list=
diff --git a/java/build.xml b/java/build.xml
index 8397147d95c9be78db04b4f2656a293a5f315e49..7be237d759bae3f89d5d1ba435c967fa1c3eb6d6 100644
--- a/java/build.xml
+++ b/java/build.xml
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project name="IpaacaJava"  default="run">
-   <import file="../../SoaShared/ant/build.xml" />    
+   <import file="../../soashared/ant/build.xml" />
 </project>
diff --git a/java/ivy.xml b/java/ivy.xml
index 3e95c71b4ec4ceab74d4230badf7e9a61bcd78df..fd0007f6e8809662be9819b3bf4212834649c97f 100644
--- a/java/ivy.xml
+++ b/java/ivy.xml
@@ -1,10 +1,12 @@
 <ivy-module version="2.0">
-   <info organisation="Herwin" module="scrapbook"/>
+   <info organisation="ipaaca" module="ipaaca"/>
    <configurations>
       <include file="${ivy.settings.dir}/configurations.xml"/>
    </configurations>
    <dependencies>
       <dependency org="slf4j"   name="slf4j-api"              rev="latest.release"  />
       <dependency org="google"  name="guava"                  rev="latest.release"  />
+      <dependency org="google"  name="protobuf-java"                  rev="latest.release"  />
+      <dependency org="rsb"  name="rsb"                  rev="latest.release"  />
    </dependencies>
 </ivy-module>
diff --git a/java/lib.local/protobuf-java-2.4.1.jar b/java/lib.local/protobuf-java-2.4.1.jar
deleted file mode 100644
index 910b225a49bc6883b3b6c20deaf9afa1dd83772c..0000000000000000000000000000000000000000
Binary files a/java/lib.local/protobuf-java-2.4.1.jar and /dev/null differ
diff --git a/java/lib.local/rsb-0.5.0.jar b/java/lib.local/rsb-0.5.0.jar
deleted file mode 100644
index 0a9e6aaf6a895b483940e4dd5930f766be721e14..0000000000000000000000000000000000000000
Binary files a/java/lib.local/rsb-0.5.0.jar and /dev/null differ
diff --git a/java/manifest.mf b/java/manifest.mf
index d3217ada5b75bedc9bd56acc290b397ec6ba68b8..5f1307134cd9ebfa637c79613ae1249c903beaf7 100644
--- a/java/manifest.mf
+++ b/java/manifest.mf
@@ -6,5 +6,5 @@ Specification-Title:    ipaaca
 Specification-Version:  0.1
 Specification-Vendor:   ipaaca
 Implementation-Title:   ipaaca
-Implementation-Version: November 23 2011  07:07 PM
+Implementation-Version: February 21 2012  05:23 PM
 Implementation-Vendor:  ipaaca
diff --git a/java/rsb.cfg b/java/rsb.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..c7d8582067278e6e725cd5309d4b280bb5ccb6b6
--- /dev/null
+++ b/java/rsb.cfg
@@ -0,0 +1,5 @@
+[transport.spread]
+host = localhost # default type is string
+port = 4803 # types can be specified in angle brackets
+enabled = true
+
diff --git a/java/src/ipaaca/IUConverter.java b/java/src/ipaaca/IUConverter.java
index 5d0508fe112141c572081d5477909867d4354f3e..c45a81c8fb74430406b731bd8ec32e278537b610 100644
--- a/java/src/ipaaca/IUConverter.java
+++ b/java/src/ipaaca/IUConverter.java
@@ -70,7 +70,7 @@ public class IUConverter implements Converter<ByteBuffer>
                 .addAllPayload(payloadItems)
                 .addAllLinks(links)
                 .build();
-        return new WireContents<ByteBuffer>(ByteBuffer.wrap(iu.toByteArray()),"ipaaca-remotepushiu");        
+        return new WireContents<ByteBuffer>(ByteBuffer.wrap(iu.toByteArray()),"ipaaca-iu");        
     }
 
     @Override
diff --git a/java/src/ipaaca/Initializer.java b/java/src/ipaaca/Initializer.java
index 82832435f8660cb8b63486781fe3fc98bf840284..afe105e60cf14a2913ad0023a14bb361e0e95b7c 100644
--- a/java/src/ipaaca/Initializer.java
+++ b/java/src/ipaaca/Initializer.java
@@ -27,14 +27,15 @@ public final class Initializer {
 	    DefaultConverterRepository.getDefaultConverterRepository().addConverter(new IntConverter());
 	    DefaultConverterRepository.getDefaultConverterRepository()
 		  .addConverter(new ProtocolBufferConverter<IUCommission>(IUCommission.getDefaultInstance()));
-	    DefaultConverterRepository.getDefaultConverterRepository()
-            .addConverter(new ProtocolBufferConverter<IUPayloadUpdate>(IUPayloadUpdate.getDefaultInstance()));
-	    DefaultConverterRepository.getDefaultConverterRepository()
-            .addConverter(new ProtocolBufferConverter<IULinkUpdate>(IULinkUpdate.getDefaultInstance()));
+	    
 	    DefaultConverterRepository.getDefaultConverterRepository().addConverter(
-	            new IUConverter(new ConverterSignature("ipaaca-remotepushiu", RemotePushIU.class)));
+	            new IUConverter(new ConverterSignature("ipaaca-iu", RemotePushIU.class)));
 	    DefaultConverterRepository.getDefaultConverterRepository().addConverter(
                 new IUConverter(new ConverterSignature("ipaaca-localiu", LocalIU.class)));
+	    DefaultConverterRepository.getDefaultConverterRepository().addConverter(
+                new PayloadConverter());
+	    DefaultConverterRepository.getDefaultConverterRepository().addConverter(
+                new LinkUpdateConverter());
 	    	    
 	}
 }
diff --git a/java/src/ipaaca/Ipaaca.java b/java/src/ipaaca/Ipaaca.java
index 8cb1eb06448bc96e9ba1b993adc7d916c6cd0fe4..b6d42575b7faa42a63bc832d0f4403e43e75f82e 100644
--- a/java/src/ipaaca/Ipaaca.java
+++ b/java/src/ipaaca/Ipaaca.java
@@ -1,5 +1,5 @@
 // Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: proto/ipaaca.proto
+// source: ipaaca.proto
 
 package ipaaca;
 
@@ -6278,30 +6278,30 @@ public final class Ipaaca {
       descriptor;
   static {
     java.lang.String[] descriptorData = {
-      "\n\022proto/ipaaca.proto\022\006ipaaca\"\033\n\nIntMessa" +
-      "ge\022\r\n\005value\030\001 \002(\021\"(\n\007LinkSet\022\014\n\004type\030\001 \002" +
-      "(\t\022\017\n\007targets\030\002 \003(\t\"<\n\013PayloadItem\022\013\n\003ke" +
-      "y\030\001 \002(\t\022\r\n\005value\030\002 \002(\t\022\021\n\004type\030\003 \002(\t:\003st" +
-      "r\"\310\002\n\002IU\022\013\n\003uid\030\001 \002(\t\022\020\n\010revision\030\002 \002(\r\022" +
-      "\027\n\010category\030\003 \002(\t:\005undef\022\031\n\014payload_type" +
-      "\030\004 \002(\t:\003MAP\022\022\n\nowner_name\030\005 \002(\t\022\030\n\tcommi" +
-      "tted\030\006 \002(\010:\005false\0220\n\013access_mode\030\007 \002(\0162\025" +
-      ".ipaaca.IU.AccessMode:\004PUSH\022\030\n\tread_only" +
-      "\030\010 \002(\010:\005false\022$\n\007payload\030\t \003(\0132\023.ipaaca.",
-      "PayloadItem\022\036\n\005links\030\n \003(\0132\017.ipaaca.Link" +
-      "Set\"/\n\nAccessMode\022\010\n\004PUSH\020\000\022\n\n\006REMOTE\020\001\022" +
-      "\013\n\007MESSAGE\020\002\"\236\001\n\017IUPayloadUpdate\022\013\n\003uid\030" +
-      "\001 \002(\t\022\020\n\010revision\030\002 \002(\r\022&\n\tnew_items\030\003 \003" +
-      "(\0132\023.ipaaca.PayloadItem\022\026\n\016keys_to_remov" +
-      "e\030\004 \003(\t\022\027\n\010is_delta\030\005 \002(\010:\005false\022\023\n\013writ" +
-      "er_name\030\006 \002(\t\"-\n\014IURetraction\022\013\n\003uid\030\001 \002" +
-      "(\t\022\020\n\010revision\030\002 \002(\r\"B\n\014IUCommission\022\013\n\003" +
-      "uid\030\001 \002(\t\022\020\n\010revision\030\002 \002(\r\022\023\n\013writer_na" +
-      "me\030\003 \002(\t\"\251\001\n\014IULinkUpdate\022\013\n\003uid\030\001 \002(\t\022\020",
-      "\n\010revision\030\002 \002(\r\022\"\n\tnew_links\030\003 \003(\0132\017.ip" +
-      "aaca.LinkSet\022(\n\017links_to_remove\030\004 \003(\0132\017." +
-      "ipaaca.LinkSet\022\027\n\010is_delta\030\005 \002(\010:\005false\022" +
-      "\023\n\013writer_name\030\006 \002(\t"
+      "\n\014ipaaca.proto\022\006ipaaca\"\033\n\nIntMessage\022\r\n\005" +
+      "value\030\001 \002(\021\"(\n\007LinkSet\022\014\n\004type\030\001 \002(\t\022\017\n\007" +
+      "targets\030\002 \003(\t\"<\n\013PayloadItem\022\013\n\003key\030\001 \002(" +
+      "\t\022\r\n\005value\030\002 \002(\t\022\021\n\004type\030\003 \002(\t:\003str\"\310\002\n\002" +
+      "IU\022\013\n\003uid\030\001 \002(\t\022\020\n\010revision\030\002 \002(\r\022\027\n\010cat" +
+      "egory\030\003 \002(\t:\005undef\022\031\n\014payload_type\030\004 \002(\t" +
+      ":\003MAP\022\022\n\nowner_name\030\005 \002(\t\022\030\n\tcommitted\030\006" +
+      " \002(\010:\005false\0220\n\013access_mode\030\007 \002(\0162\025.ipaac" +
+      "a.IU.AccessMode:\004PUSH\022\030\n\tread_only\030\010 \002(\010" +
+      ":\005false\022$\n\007payload\030\t \003(\0132\023.ipaaca.Payloa",
+      "dItem\022\036\n\005links\030\n \003(\0132\017.ipaaca.LinkSet\"/\n" +
+      "\nAccessMode\022\010\n\004PUSH\020\000\022\n\n\006REMOTE\020\001\022\013\n\007MES" +
+      "SAGE\020\002\"\236\001\n\017IUPayloadUpdate\022\013\n\003uid\030\001 \002(\t\022" +
+      "\020\n\010revision\030\002 \002(\r\022&\n\tnew_items\030\003 \003(\0132\023.i" +
+      "paaca.PayloadItem\022\026\n\016keys_to_remove\030\004 \003(" +
+      "\t\022\027\n\010is_delta\030\005 \002(\010:\005false\022\023\n\013writer_nam" +
+      "e\030\006 \002(\t\"-\n\014IURetraction\022\013\n\003uid\030\001 \002(\t\022\020\n\010" +
+      "revision\030\002 \002(\r\"B\n\014IUCommission\022\013\n\003uid\030\001 " +
+      "\002(\t\022\020\n\010revision\030\002 \002(\r\022\023\n\013writer_name\030\003 \002" +
+      "(\t\"\251\001\n\014IULinkUpdate\022\013\n\003uid\030\001 \002(\t\022\020\n\010revi",
+      "sion\030\002 \002(\r\022\"\n\tnew_links\030\003 \003(\0132\017.ipaaca.L" +
+      "inkSet\022(\n\017links_to_remove\030\004 \003(\0132\017.ipaaca" +
+      ".LinkSet\022\027\n\010is_delta\030\005 \002(\010:\005false\022\023\n\013wri" +
+      "ter_name\030\006 \002(\t"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
       new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
diff --git a/java/src/ipaaca/LinkUpdateConverter.java b/java/src/ipaaca/LinkUpdateConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa506d01eb16ac0f7ba54bd3e6c691d844bb9d2e
--- /dev/null
+++ b/java/src/ipaaca/LinkUpdateConverter.java
@@ -0,0 +1,47 @@
+package ipaaca;
+
+import ipaaca.Ipaaca.IULinkUpdate;
+
+import java.nio.ByteBuffer;
+
+import rsb.converter.ConversionException;
+import rsb.converter.Converter;
+import rsb.converter.ConverterSignature;
+import rsb.converter.UserData;
+import rsb.converter.WireContents;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+
+public class LinkUpdateConverter implements Converter<ByteBuffer>
+{
+    private static final String LINKUPDATE_WIRESCHEMA = "ipaaca-iu-link-update";
+
+    @Override
+    public UserData<?> deserialize(String wireSchema, ByteBuffer buffer) throws ConversionException
+    {
+        IULinkUpdate pl;
+        try
+        {
+            pl = IULinkUpdate.newBuilder().mergeFrom(buffer.array()).build();
+        }
+        catch (InvalidProtocolBufferException e)
+        {
+            throw new RuntimeException(e);
+        }
+        return new UserData<IULinkUpdate>(pl, IULinkUpdate.class);   
+    }
+
+    @Override
+    public ConverterSignature getSignature()
+    {
+        return new ConverterSignature(LINKUPDATE_WIRESCHEMA,IULinkUpdate.class);
+    }
+
+    @Override
+    public WireContents<ByteBuffer> serialize(Class<?> typeInfo, Object obj) throws ConversionException
+    {
+        IULinkUpdate pl = (IULinkUpdate)obj;
+        return new WireContents<ByteBuffer>(ByteBuffer.wrap(pl.toByteArray()),LINKUPDATE_WIRESCHEMA);        
+    }
+
+}
diff --git a/java/src/ipaaca/LocalIU.java b/java/src/ipaaca/LocalIU.java
index 5752c0beabdf0ea5eb57c88fad04971c13a312ad..a73d882dbb34f606dcc374472031b18db6f300a4 100644
--- a/java/src/ipaaca/LocalIU.java
+++ b/java/src/ipaaca/LocalIU.java
@@ -74,7 +74,10 @@ public class LocalIU extends AbstractIU
             {
                 increaseRevisionNumber();
                 committed = true;
-                outputBuffer.sendIUCommission(this, writerName);
+                if(outputBuffer!=null)
+                {    
+                    outputBuffer.sendIUCommission(this, writerName);                
+                }
             }
         }
     }
diff --git a/java/src/ipaaca/PayloadConverter.java b/java/src/ipaaca/PayloadConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..6e32b40b42f6ccb11632c3cbf67cdc0b1b9445c9
--- /dev/null
+++ b/java/src/ipaaca/PayloadConverter.java
@@ -0,0 +1,47 @@
+package ipaaca;
+
+import ipaaca.Ipaaca.IUPayloadUpdate;
+
+import java.nio.ByteBuffer;
+
+import rsb.converter.ConversionException;
+import rsb.converter.Converter;
+import rsb.converter.ConverterSignature;
+import rsb.converter.UserData;
+import rsb.converter.WireContents;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+
+public class PayloadConverter implements Converter<ByteBuffer>
+{
+    private static final String PAYLOAD_WIRESCHEMA = "ipaaca-iu-payload-update";
+
+    @Override
+    public UserData<?> deserialize(String wireSchema, ByteBuffer buffer) throws ConversionException
+    {
+        IUPayloadUpdate pl;
+        try
+        {
+            pl = IUPayloadUpdate.newBuilder().mergeFrom(buffer.array()).build();
+        }
+        catch (InvalidProtocolBufferException e)
+        {
+            throw new RuntimeException(e);
+        }
+        return new UserData<IUPayloadUpdate>(pl, IUPayloadUpdate.class);   
+    }
+
+    @Override
+    public ConverterSignature getSignature()
+    {
+        return new ConverterSignature(PAYLOAD_WIRESCHEMA,IUPayloadUpdate.class);
+    }
+
+    @Override
+    public WireContents<ByteBuffer> serialize(Class<?> typeInfo, Object obj) throws ConversionException
+    {
+        IUPayloadUpdate pl = (IUPayloadUpdate)obj;
+        return new WireContents<ByteBuffer>(ByteBuffer.wrap(pl.toByteArray()),PAYLOAD_WIRESCHEMA);        
+    }
+
+}
diff --git a/java/src/ipaaca/RemotePushIU.java b/java/src/ipaaca/RemotePushIU.java
index b80eba87d2049678c444d3b36946ae79add0a197..a0b5392c55eb9885f1b48cc36da02e199e27fe77 100644
--- a/java/src/ipaaca/RemotePushIU.java
+++ b/java/src/ipaaca/RemotePushIU.java
@@ -367,7 +367,7 @@ public class RemotePushIU extends AbstractIU
     // else:
     // self._revision = new_revision
     @Override
-    public void modifyLinks(boolean isDelta, SetMultimap<String, String> linksToAdd, SetMultimap<String, String> linksToRemove, String writerName)
+    void modifyLinks(boolean isDelta, SetMultimap<String, String> linksToAdd, SetMultimap<String, String> linksToRemove, String writerName)
     {
         if (isCommitted())
         {
diff --git a/java/src/ipaacademo/PythonCall.java b/java/src/ipaacademo/PythonCall.java
new file mode 100644
index 0000000000000000000000000000000000000000..09c709343b97b30016d3d310953cd2bd606400fa
--- /dev/null
+++ b/java/src/ipaacademo/PythonCall.java
@@ -0,0 +1,54 @@
+package ipaacademo;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class PythonCall
+{
+
+    /**
+     * @param args
+     * @throws IOException
+     */
+    public static void main(String[] args) throws IOException
+    {
+        String program = "print 'Hello world'";
+        Process p = Runtime.getRuntime().exec(new String[]{"python","-c", program});
+        
+        InputStream in = p.getInputStream();
+        BufferedInputStream buf = new BufferedInputStream(in);
+        InputStreamReader inread = new InputStreamReader(buf);
+        BufferedReader bufferedreader = new BufferedReader(inread);
+        // Read the ls output
+        String line;
+        while ((line = bufferedreader.readLine()) != null)
+        {
+            System.out.println(line);
+        }
+
+        try
+        {
+            if (p.waitFor() != 0)
+            {
+                System.err.println("exit value = " + p.exitValue());
+            }
+        }
+        catch (InterruptedException e)
+        {
+            System.err.println(e);
+        }
+
+        in = p.getErrorStream();
+        buf = new BufferedInputStream(in);
+        inread = new InputStreamReader(buf);
+        bufferedreader = new BufferedReader(inread);
+        // Read the ls output
+        while ((line = bufferedreader.readLine()) != null)
+        {
+            System.out.println(line);
+        }
+    }
+}
diff --git a/java/src/ipaacademo/TextPrinter.java b/java/src/ipaacademo/TextPrinter.java
new file mode 100644
index 0000000000000000000000000000000000000000..25f6ce8ab7dc334959ee4ddf58e2c08cacbddf8a
--- /dev/null
+++ b/java/src/ipaacademo/TextPrinter.java
@@ -0,0 +1,131 @@
+package ipaacademo;
+
+import java.util.Set;
+
+import ipaaca.AbstractIU;
+import ipaaca.Initializer;
+import ipaaca.InputBuffer;
+import ipaaca.LocalIU;
+import ipaaca.OutputBuffer;
+import ipaaca.RemotePushIU;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+
+import com.google.common.collect.ImmutableSet;
+
+public class TextPrinter
+{
+    static
+    {
+        Initializer.initializeIpaacaRsb();
+    }
+    
+    private static final String CATEGORY = "TEXT";
+    private static final double RATE = 0.5;
+    private UpdateThread updateThread;
+    
+    public TextPrinter()
+    {
+        Set<String> categories = new ImmutableSet.Builder<String>().add(CATEGORY).build();    
+        JLabel label = new JLabel("");
+        
+        updateThread = new UpdateThread(new InputBuffer("TextPrinter", categories),label);
+        
+        JFrame frame = new JFrame("IPAACA TextPrinter Demo");
+        frame.add(label);
+        frame.setSize(1000,300);
+        frame.setVisible(true);   
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+    }
+    
+    public void start()
+    {
+        updateThread.start();
+    }
+    
+    private static class UpdateThread extends Thread
+    {
+        private InputBuffer inBuffer;
+        private JLabel label;
+        
+        public UpdateThread(InputBuffer inBuffer, JLabel label)
+        {
+            this.inBuffer = inBuffer;
+            this.label = label;
+        }
+        
+        @Override
+        public void run()
+        {
+            long startTime = System.currentTimeMillis();
+            while(true)
+            {
+                double duration = (System.currentTimeMillis()-startTime)/1000d;
+                
+                RemotePushIU iuFirst = null;
+                for (RemotePushIU iu : inBuffer.getIUs())
+                {
+                    if(iu.getLinks("PREDECESSOR").isEmpty())
+                    {
+                        iuFirst = iu;
+                        break;
+                    }
+                }
+                
+                int numChars = (int)(duration/RATE);
+                
+                AbstractIU iu = iuFirst;
+                String str = "";
+                for(int i=0;i<numChars;i++)
+                {
+                    str += iu.getPayload().get("CONTENT");
+                    Set<String> successor = iu.getLinks("SUCCESSOR");
+                    if(successor!=null && !successor.isEmpty())
+                    {
+                        iu = inBuffer.getIU(successor.iterator().next());
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+                label.setText(str);
+                
+                try
+                {
+                    Thread.sleep(200);
+                }
+                catch (InterruptedException e)
+                {
+                    Thread.interrupted();
+                }
+            }
+        }
+        
+    }
+    
+    public static void main(String args[])
+    {
+        TextPrinter tp = new TextPrinter();        
+        
+        
+        OutputBuffer outBuffer = new OutputBuffer("componentX");
+        String[] inputString = {"h","e","l","l","o"," ","w","o","r","l","d","!"};
+        LocalIU predIU = null;        
+        for(String str:inputString)
+        {
+            LocalIU localIU = new LocalIU();
+            localIU.setCategory(CATEGORY);
+            outBuffer.add(localIU);
+            localIU.getPayload().put("CONTENT", str);            
+            if(predIU!=null)
+            {
+                localIU.setLinks("PREDECESSOR", ImmutableSet.of(predIU.getUid()));
+                predIU.setLinks("SUCCESSOR",ImmutableSet.of(localIU.getUid()));
+            }
+            predIU = localIU;
+        }
+        tp.start();        
+    }
+}
diff --git a/java/test/src/ipaaca/ComponentCommunicationIntegrationTest.java b/java/test/src/ipaaca/ComponentCommunicationIntegrationTest.java
index cb05c0eafccc2824a5648718d1ade71936f2b381..3041995cc752d11420d5852868c64dd1eeff0e78 100644
--- a/java/test/src/ipaaca/ComponentCommunicationIntegrationTest.java
+++ b/java/test/src/ipaaca/ComponentCommunicationIntegrationTest.java
@@ -109,8 +109,7 @@ public class ComponentCommunicationIntegrationTest
         localIU = new LocalIU();
         localIU.setCategory(CATEGORY);
         localIU.getPayload().put("key1", "item1");
-        localIU.addLinks("INIT", ImmutableSet.of("init1","init2"));
-        outBuffer.add(localIU);
+        localIU.addLinks("INIT", ImmutableSet.of("init1","init2"));        
     }
     
     @After
@@ -123,6 +122,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testAddedIU() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);        
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         assertNotNull(iuIn);
@@ -130,11 +130,12 @@ public class ComponentCommunicationIntegrationTest
         assertThat(localIU.getLinks("INIT"),containsInAnyOrder("init1","init2"));
         assertEquals(1,component2EventHandler.getNumberOfAddEvents(iuIn.getUid()));
         assertEquals(0,component1EventHandler.getNumberOfAddEvents(localIU.getUid()));
-    }
+    }    
     
     @Test
     public void testIUCommit() throws InterruptedException
     {
+        outBuffer.add(localIU);
         localIU.commit();
         Thread.sleep(200);
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
@@ -143,9 +144,22 @@ public class ComponentCommunicationIntegrationTest
         assertEquals(1,component2EventHandler.getNumberOfCommitEvents(iuIn.getUid()));        
     }
     
+    @Test
+    public void testIUCommitBeforePublish() throws InterruptedException
+    {
+        localIU.commit();
+        outBuffer.add(localIU);        
+        Thread.sleep(200);
+        AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
+        assertTrue(iuIn.isCommitted());
+        assertEquals(0,component1EventHandler.getNumberOfCommitEvents(localIU.getUid()));
+        assertEquals(0,component2EventHandler.getNumberOfCommitEvents(iuIn.getUid()));        
+    }
+    
     @Test
     public void testIUCommitFromInputBuffer() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         
@@ -160,6 +174,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testIUUpdate() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);        
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         assertNull(iuIn.getPayload().get("key2"));
@@ -174,6 +189,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testSetPayload() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);        
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         
@@ -191,6 +207,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testSetPayloadRemote() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);        
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         
@@ -208,6 +225,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testIUUpdateFromInputBuffer() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);        
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         
@@ -222,6 +240,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testIUpdateRemove() throws InterruptedException
     {   
+        outBuffer.add(localIU);
         Thread.sleep(200);    
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         assertEquals("item1",iuIn.getPayload().get("key1"));
@@ -236,6 +255,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testIUpdateRemoveFromInputBuffer() throws InterruptedException
     {   
+        outBuffer.add(localIU);
         Thread.sleep(200);    
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         assertEquals("item1",iuIn.getPayload().get("key1"));
@@ -250,6 +270,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testSetLinksLocal() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         localIU.setLinks("SAME_LEVEL",ImmutableSet.of("iu5","iu6"));        
@@ -261,6 +282,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testSetLinksRemote() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         iuIn.setLinks("SAME_LEVEL",ImmutableSet.of("iu5","iu6"));        
@@ -272,6 +294,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testSetLinksRemoteOverwrite() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         localIU.setLinks("SAME_LEVEL",ImmutableSet.of("iu5","iu6"));        
@@ -288,6 +311,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testAddLinksLocal() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         localIU.setLinks("SAME_LEVEL",ImmutableSet.of("iu4"));
@@ -300,6 +324,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testAddLinksRemote() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         iuIn.addLinks("SAME_LEVEL",ImmutableSet.of("iu5","iu6"));        
@@ -311,6 +336,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testRemoveLinksLocal() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);   
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         localIU.setLinks("SAME_LEVEL",ImmutableSet.of("iu5","iu6","iu7"));
@@ -323,6 +349,7 @@ public class ComponentCommunicationIntegrationTest
     @Test
     public void testRemoveLinksRemote() throws InterruptedException
     {
+        outBuffer.add(localIU);
         Thread.sleep(200);   
         AbstractIU iuIn = inBuffer.getIU(localIU.getUid());
         iuIn.setLinks("SAME_LEVEL",ImmutableSet.of("iu5","iu6","iu7"));
@@ -331,4 +358,6 @@ public class ComponentCommunicationIntegrationTest
         assertThat(localIU.getLinks("SAME_LEVEL"),containsInAnyOrder("iu7"));
         assertThat(iuIn.getLinks("SAME_LEVEL"),containsInAnyOrder("iu7"));
     }
+    
+    
 }
diff --git a/java/test/src/ipaaca/IUTestUtil.java b/java/test/src/ipaaca/IUTestUtil.java
index f47149c014c614df59ae5fe41941455551dfd96c..aca1b2d442fb361174b4a5364e4608a2a8b49206 100644
--- a/java/test/src/ipaaca/IUTestUtil.java
+++ b/java/test/src/ipaaca/IUTestUtil.java
@@ -1,5 +1,4 @@
 package ipaaca;
-import static org.junit.Assert.*;
 import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
diff --git a/java/test/src/ipaaca/JavaPythonTest.java b/java/test/src/ipaaca/JavaPythonTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..18e6150298fceb58d3e30aeac3f08de0870e0656
--- /dev/null
+++ b/java/test/src/ipaaca/JavaPythonTest.java
@@ -0,0 +1,187 @@
+package ipaaca;
+
+import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
+import static org.junit.Assert.*;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+public class JavaPythonTest
+{
+
+    static
+    {
+        Initializer.initializeIpaacaRsb();
+    }
+
+    private InputBuffer inBuffer;
+
+    private static final String PYTHON_PREAMBLE = "import sys\n" 
+            + "sys.path.insert(0, '../python/build/')\n"
+            + "sys.path.insert(0, '../python/lib/')\n" 
+            + "import ipaaca, time\n";
+
+    @Before
+    public void setup()
+    {
+        Set<String> categories = new ImmutableSet.Builder<String>().add("JavaPythonTest").build();
+        inBuffer = new InputBuffer("javaside", categories);
+    }
+
+    private void printRuntimeErrors(Process p) throws IOException
+    {
+
+        InputStream in = p.getInputStream();
+        BufferedInputStream buf = new BufferedInputStream(in);
+        InputStreamReader inread = new InputStreamReader(buf);
+        BufferedReader bufferedreader = new BufferedReader(inread);
+        // Read the ls output
+        String line;
+        while ((line = bufferedreader.readLine()) != null)
+        {
+            System.out.println(line);
+        }
+
+        try
+        {
+            if (p.waitFor() != 0)
+            {
+                System.err.println("exit value = " + p.exitValue());
+            }
+        }
+        catch (InterruptedException e)
+        {
+            System.err.println(e);
+        }
+
+        in = p.getErrorStream();
+        buf = new BufferedInputStream(in);
+        inread = new InputStreamReader(buf);
+        bufferedreader = new BufferedReader(inread);
+        // Read the ls output
+        while ((line = bufferedreader.readLine()) != null)
+        {
+            System.out.println(line);
+        }
+    }
+
+    private boolean runPythonProgram(String pypr) throws IOException
+    {
+        Process p = Runtime.getRuntime().exec(new String[] { "python", "-c", pypr });
+        printRuntimeErrors(p);
+        return p.exitValue()==0;
+    }
+
+    @Test
+    public void testSetPayloadInPythonOutputBuffer() throws IOException, InterruptedException
+    {
+
+        String pypr = PYTHON_PREAMBLE 
+                + "ob = ipaaca.OutputBuffer('pythonside')\n" 
+                + "iu = ipaaca.IU('JavaPythonTest')\n"
+                + "iu.payload = {'data':'Hello from Python!'}\n" 
+                + "time.sleep(0.1)\n" 
+                + "ob.add(iu)\n";
+        assertTrue(runPythonProgram(pypr));
+
+        Thread.sleep(200);
+        assertEquals(1, inBuffer.getIUs().size());
+        AbstractIU iu = inBuffer.getIUs().iterator().next();
+        assertEquals("Hello from Python!", iu.getPayload().get("data"));
+    }
+    
+    @Test
+    public void testSetPayloadInPythonOutputBufferAfterPublishing() throws IOException, InterruptedException
+    {
+
+        String pypr = PYTHON_PREAMBLE 
+                + "ob = ipaaca.OutputBuffer('pythonside')\n" 
+                + "iu = ipaaca.IU('JavaPythonTest')\n"                
+                + "ob.add(iu)\n"
+                + "time.sleep(0.1)\n"
+                + "iu.payload = {'data':'Hello from Python!'}\n";
+                
+        assertTrue(runPythonProgram(pypr));
+
+        Thread.sleep(200);
+        assertEquals(1, inBuffer.getIUs().size());
+        AbstractIU iu = inBuffer.getIUs().iterator().next();
+        assertEquals("Hello from Python!", iu.getPayload().get("data"));
+    }
+    
+    @Test
+    public void testAddLinkThenPublishInPython() throws IOException, InterruptedException
+    {
+        String pypr = PYTHON_PREAMBLE 
+                +"ob = ipaaca.OutputBuffer('pythonside')\n"
+                +"iu = ipaaca.IU('JavaPythonTest')\n"
+                +"iu.add_links('testtype',['dummy1','dummy2'])\n"
+                + "time.sleep(0.1)\n" 
+                + "ob.add(iu)\n";
+        assertTrue(runPythonProgram(pypr));
+        Thread.sleep(200);
+        assertEquals(1, inBuffer.getIUs().size());
+        AbstractIU iu = inBuffer.getIUs().iterator().next();
+        assertThat(iu.getLinks("testtype"),containsInAnyOrder("dummy1","dummy2"));       
+        
+    }
+    
+    @Test
+    public void testPublishThenAddLinkInPython() throws IOException, InterruptedException
+    {
+        String pypr = PYTHON_PREAMBLE 
+                +"ob = ipaaca.OutputBuffer('pythonside')\n"
+                +"iu = ipaaca.IU('JavaPythonTest')\n"
+                + "ob.add(iu)\n"
+                + "time.sleep(0.1)\n"        
+                +"iu.add_links('testtype',['dummy1','dummy2'])\n";
+                
+        assertTrue(runPythonProgram(pypr));
+        Thread.sleep(200);
+        assertEquals(1, inBuffer.getIUs().size());
+        AbstractIU iu = inBuffer.getIUs().iterator().next();
+        assertThat(iu.getLinks("testtype"),containsInAnyOrder("dummy1","dummy2"));        
+    }
+    
+    @Test
+    public void testCommitPublishedIUFromPython()throws IOException, InterruptedException
+    {
+        String pypr = PYTHON_PREAMBLE 
+                +"ob = ipaaca.OutputBuffer('pythonside')\n"
+                +"iu = ipaaca.IU('JavaPythonTest')\n"
+                + "ob.add(iu)\n"
+                + "time.sleep(0.1)\n"
+                + "iu.commit()\n";
+        assertTrue(runPythonProgram(pypr));
+        Thread.sleep(200);
+        assertEquals(1, inBuffer.getIUs().size());
+        AbstractIU iu = inBuffer.getIUs().iterator().next();
+        assertTrue(iu.isCommitted());
+    }
+    
+    @Test
+    public void testCommitThenPublishIUFromPython()throws IOException, InterruptedException
+    {
+        String pypr = PYTHON_PREAMBLE 
+                +"ob = ipaaca.OutputBuffer('pythonside')\n"
+                +"iu = ipaaca.IU('JavaPythonTest')\n"
+                +"iu.commit()\n"
+                +"time.sleep(0.1)\n"
+                +"ob.add(iu)\n";
+                
+        assertTrue(runPythonProgram(pypr));
+        Thread.sleep(200);
+        assertEquals(1, inBuffer.getIUs().size());
+        AbstractIU iu = inBuffer.getIUs().iterator().next();
+        assertTrue(iu.isCommitted());
+    }
+}
diff --git a/python/ivy.xml b/python/ivy.xml
index f7824bbed5b31631967f692c017cede769d81172..b24cc6a006dbef42152a7da7e37b10ddfed0ad81 100644
--- a/python/ivy.xml
+++ b/python/ivy.xml
@@ -1,6 +1,7 @@
 <ivy-module version="2.0">
-   <info organisation="HMI" module="IpaacaPython" />
+   <info organisation="ipaaca" module="IpaacaPython" />
    <dependencies>
-      <dependency org="junit" name="junit" rev="latest.release"/>
+      <dependency org="google" name="protobuf" rev="latest.release"/>
+      <dependency org="rsb" name="rsb" rev="latest.release"/>
    </dependencies>
 </ivy-module>
diff --git a/python/src/ipaaca.py b/python/src/ipaaca.py
index 9f639ccb270164241210c330f2eb8f17ee6d0f03..32140e6a3c41893e2348aa2dbcb77544cfc4032b 100755
--- a/python/src/ipaaca.py
+++ b/python/src/ipaaca.py
@@ -320,6 +320,7 @@ class IU(IUInterface):#{{{
 			raise IUCommittedError(self)
 		with self.revision_lock:
 			# set item locally
+			# FIXME: Is it actually set locally?
 			self._increase_revision_number()
 			if self.is_published:
 				# send update to remote holders
@@ -341,7 +342,8 @@ class IU(IUInterface):#{{{
 			if not self._committed:
 				self._increase_revision_number()
 				self._committed = True
-				self.buffer._send_iu_commission(self, writer_name=writer_name)
+				if self.buffer is not None:
+					self.buffer._send_iu_commission(self, writer_name=writer_name)
 	
 	def commit(self):
 		"""Commit to this IU."""
diff --git a/python/test/ivy.xml b/python/test/ivy.xml
new file mode 100644
index 0000000000000000000000000000000000000000..139b8ef60d3b91283c441bd257454b6ede6c0fc7
--- /dev/null
+++ b/python/test/ivy.xml
@@ -0,0 +1,6 @@
+<ivy-module version="2.0">
+   <info organisation="ipaaca" module="IpaacaPythonTest"/>
+   <dependencies>
+	<dependency org="hamcrest" name="hamcrest" rev="latest.release"/>
+   </dependencies>
+</ivy-module>
diff --git a/python/test/src/testipaaca.py b/python/test/src/testipaaca.py
index a2a3c9391e9237e33ed8bb6844d5ffa97bc50f45..c7a443fd4ece847b3220c6f8f2ae4c5c436ef833 100755
--- a/python/test/src/testipaaca.py
+++ b/python/test/src/testipaaca.py
@@ -1,11 +1,12 @@
 #!/usr/bin/env python
 
+import sys
 import time
+import unittest
+
+import hamcrest as hc
 import ipaaca
-import sys
 
-import unittest
-	
 def handle_iu_event(iu, event_type, local):
 	#print('(IU event '+event_type+' '+str(iu.uid)+')')
 	pass
@@ -23,12 +24,48 @@ class IpaacaIUStoreTestCase(unittest.TestCase):
 	def tearDown(self):
 		pass
 	def testInputBufferContents(self):
-		self.assertIn(self.sensor_iu.uid, self.ib.iu_store)
+		hc.assert_that(self.ib.iu_store, hc.has_key(self.sensor_iu.uid))
 		self.assertEqual(len(self.ib.iu_store), 1)
 	def testOutputBufferContents(self):
-		self.assertIn(self.sensor_iu.uid, self.ob.iu_store)
+		hc.assert_that(self.ib.iu_store, hc.has_key(self.sensor_iu.uid))
 		self.assertEqual(len(self.ob.iu_store), 1)
 
+class IpaacaPayloadTestCase(unittest.TestCase):
+	def setUp(self):
+		self.ib = ipaaca.InputBuffer('TestIn', ['sensorcategory', 'decisioncategory'])
+		self.ob = ipaaca.OutputBuffer('TestOut')
+		self.sensor_iu = ipaaca.IU('sensorcategory')
+		self.sensor_iu.payload = {'data': 'sensordata'}
+		self.ob.add(self.sensor_iu)
+		
+	def testPayloadContent(self):
+		time.sleep(0.1)
+		iu_received = self.ib.iu_store.get(self.sensor_iu.uid)
+		self.assertEqual(iu_received.payload["data"], 'sensordata')
+
+
+class IpaacaCommitTestCases(unittest.TestCase):
+
+	def setUp(self):
+		self.ib = ipaaca.InputBuffer('TestIn', ['sensorcategory'])
+		self.ob = ipaaca.OutputBuffer('TestOut')
+		self.iu = ipaaca.IU('sensorcategory')
+
+	def testCommitBeforePublish(self):
+		self.iu.commit()
+		self.ob.add(self.iu)
+		time.sleep(0.1)
+		received_iu = self.ib.iu_store[self.iu.uid]
+		self.assertTrue(received_iu.committed)
+
+	def testCommitAfterPublish(self):
+		self.ob.add(self.iu)
+		self.iu.commit()
+		time.sleep(0.1)
+		received_iu = self.ib.iu_store[self.iu.uid]
+		self.assertTrue(received_iu.committed)
+
+
 class IpaacaLinksTestCase(unittest.TestCase):
 	def setUp(self):
 		self.ib = ipaaca.InputBuffer('TestIn', ['sensorcategory', 'decisioncategory'])
@@ -46,10 +83,10 @@ class IpaacaLinksTestCase(unittest.TestCase):
 		self.ob.add(self.decision_iu)
 		time.sleep(0.1)
 		# test received version
-		self.assertIn(self.decision_iu.uid, self.ib.iu_store)
+		hc.assert_that(self.ib.iu_store, hc.has_key(self.decision_iu.uid))
 		received_iu = self.ib.iu_store[self.decision_iu.uid]
 		grinlinks = received_iu.get_links('grin')
-		self.assertIn(self.sensor_iu.uid, grinlinks)
+		hc.assert_that(grinlinks, hc.has_item(self.sensor_iu.uid))
 		self.assertEqual(len(grinlinks), 1)
 	def testSetAndRemoveSingleLink(self):
 		time.sleep(0.1)
@@ -61,7 +98,7 @@ class IpaacaLinksTestCase(unittest.TestCase):
 		self.decision_iu.remove_links('grin', [self.sensor_iu.uid])
 		time.sleep(0.1)
 		# test received version
-		self.assertIn(self.decision_iu.uid, self.ib.iu_store)
+		hc.assert_that(self.ib.iu_store, hc.has_key(self.decision_iu.uid))
 		received_iu = self.ib.iu_store[self.decision_iu.uid]
 		grinlinks = received_iu.get_links('grin')
 		self.assertEqual(len(grinlinks), 0)