Improvements to JaCObs Jackson serializer/deserializer
  - deserialization of channel proxies is now using public Jackson APIs only.
  - Channel garbage collection implemented.
  - HashSets replaced by LinkedHashSets in order to make the serialized form more deterministic.
diff --git a/src/main/java/org/apache/ode/jacob/CompositeProcess.java b/src/main/java/org/apache/ode/jacob/CompositeProcess.java
index c1e5843..785fed0 100644
--- a/src/main/java/org/apache/ode/jacob/CompositeProcess.java
+++ b/src/main/java/org/apache/ode/jacob/CompositeProcess.java
@@ -20,13 +20,13 @@
 
 import java.lang.reflect.Method;
 import java.util.Collections;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Set;
 
 
 @SuppressWarnings("serial")
 public final class CompositeProcess extends ChannelListener {
-    private Set<ChannelListener> processes = new HashSet<ChannelListener>();
+    private Set<ChannelListener> processes = new LinkedHashSet<ChannelListener>();
 
     public CompositeProcess() {
     }
diff --git a/src/main/java/org/apache/ode/jacob/ReceiveProcess.java b/src/main/java/org/apache/ode/jacob/ReceiveProcess.java
index eccfd09..70f9191 100644
--- a/src/main/java/org/apache/ode/jacob/ReceiveProcess.java
+++ b/src/main/java/org/apache/ode/jacob/ReceiveProcess.java
@@ -20,7 +20,7 @@
 
 import java.lang.reflect.Method;
 import java.util.Collections;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Set;
 
 
@@ -53,7 +53,7 @@
 
     public Set<Method> getImplementedMethods() {
         if (_implementedMethods == null) {
-            Set<Method> implementedMethods = new HashSet<Method>();
+            Set<Method> implementedMethods = new LinkedHashSet<Method>();
             ClassUtil.getImplementedMethods(implementedMethods, receiver.getClass());
             _implementedMethods = Collections.unmodifiableSet(implementedMethods);
         }
diff --git a/src/main/java/org/apache/ode/jacob/soup/jackson/ChannelProxySerializer.java b/src/main/java/org/apache/ode/jacob/soup/jackson/ChannelProxySerializer.java
index 0817461..a3cee06 100644
--- a/src/main/java/org/apache/ode/jacob/soup/jackson/ChannelProxySerializer.java
+++ b/src/main/java/org/apache/ode/jacob/soup/jackson/ChannelProxySerializer.java
@@ -19,6 +19,8 @@
 package org.apache.ode.jacob.soup.jackson;
 
 import java.io.IOException;
+import java.util.LinkedHashSet;
+import java.util.Set;
 
 import org.apache.ode.jacob.Channel;
 import org.apache.ode.jacob.ChannelProxy;
@@ -34,6 +36,8 @@
 
 public class ChannelProxySerializer extends StdSerializer<ChannelProxy>{
 
+    private final Set<Integer> serializedChannels = new LinkedHashSet<Integer>();
+    
     protected ChannelProxySerializer() {
         super(ChannelProxy.class);
     }
@@ -61,8 +65,16 @@
             SerializerProvider provider) throws JsonGenerationException, IOException {
         CommChannel commChannel = (CommChannel) ChannelFactory.getBackend((Channel)value);
         ClassNameIdResolver idResolver = new ClassNameIdResolver(provider.constructType(commChannel.getType()), provider.getTypeFactory());
+        Integer cid = (Integer)commChannel.getId();
         jgen.writeStringField("channelType", idResolver.idFromBaseType());
-        jgen.writeNumberField("channelId", (Integer)commChannel.getId());
+        jgen.writeNumberField("channelId", cid);
+
+        // save channel id for garbage collection
+        serializedChannels.add(cid);
+    }
+
+    public Set<Integer> getSerializedChannels() {
+        return serializedChannels;
     }
 
 }
diff --git a/src/main/java/org/apache/ode/jacob/soup/jackson/ContinuationValueInstantiator.java b/src/main/java/org/apache/ode/jacob/soup/jackson/ContinuationValueInstantiator.java
deleted file mode 100644
index d770ad1..0000000
--- a/src/main/java/org/apache/ode/jacob/soup/jackson/ContinuationValueInstantiator.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.ode.jacob.soup.jackson;
-
-import java.lang.reflect.Method;
-
-import org.apache.ode.jacob.JacobObject;
-import org.apache.ode.jacob.soup.Continuation;
-
-import com.fasterxml.jackson.databind.DeserializationConfig;
-import com.fasterxml.jackson.databind.deser.CreatorProperty;
-import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
-import com.fasterxml.jackson.databind.deser.ValueInstantiator;
-
-public class ContinuationValueInstantiator extends ValueInstantiator {
-
-    @Override
-    public String getValueTypeDesc() {
-        return Continuation.class.getName();
-    }
-
-    @Override
-    public boolean canCreateFromObjectWith() {
-        return true;
-    }
-
-    @Override
-    public SettableBeanProperty[] getFromObjectArguments(
-            DeserializationConfig config) {
-        return  new CreatorProperty[] {
-                new CreatorProperty("_closure", config.constructType(JacobObject.class), null, null, null, 0, null),
-                new CreatorProperty("_method", config.constructType(Method.class), null, null, null, 1, null),
-                new CreatorProperty("_args", config.constructType(Object[].class), null, null, null, 2, null)};
-
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/org/apache/ode/jacob/soup/jackson/JacksonExecutionQueueImpl.java b/src/main/java/org/apache/ode/jacob/soup/jackson/JacksonExecutionQueueImpl.java
index e0892df..fb08f10 100644
--- a/src/main/java/org/apache/ode/jacob/soup/jackson/JacksonExecutionQueueImpl.java
+++ b/src/main/java/org/apache/ode/jacob/soup/jackson/JacksonExecutionQueueImpl.java
@@ -19,14 +19,19 @@
 package org.apache.ode.jacob.soup.jackson;
 
 import java.io.IOException;
+import java.io.Serializable;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
 
 import org.apache.ode.jacob.Channel;
 import org.apache.ode.jacob.ChannelProxy;
 import org.apache.ode.jacob.soup.Continuation;
 import org.apache.ode.jacob.vpu.ExecutionQueueImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
 import com.fasterxml.jackson.annotation.PropertyAccessor;
@@ -35,11 +40,16 @@
 import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.core.Version;
+import com.fasterxml.jackson.databind.BeanDescription;
+import com.fasterxml.jackson.databind.DeserializationConfig;
 import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
 import com.fasterxml.jackson.databind.MapperFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
 import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
 import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
 import com.fasterxml.jackson.databind.module.SimpleModule;
@@ -51,20 +61,40 @@
  */
 public class JacksonExecutionQueueImpl extends ExecutionQueueImpl {
 
+    private static final Logger LOG = LoggerFactory.getLogger(JacksonExecutionQueueImpl.class);
+    
 	public JacksonExecutionQueueImpl() {
 		super(null);
 	}
 	
     public static void configureMapper(ObjectMapper om) {
         
-        SimpleModule sm = new SimpleModule("jacobmodule");
-        sm.addSerializer(ChannelProxy.class, new ChannelProxySerializer());
+        SimpleModule sm = new SimpleModule("jacob", Version.unknownVersion());
+        
+        final ChannelProxySerializer cps = new ChannelProxySerializer();
+        
+        sm.addSerializer(ChannelProxy.class, cps);
         sm.addSerializer(Continuation.class, new ContinuationSerializer());
-        sm.addSerializer(JacksonExecutionQueueImpl.class, new ExecutionQueueImplSerializer());
+        sm.addSerializer(JacksonExecutionQueueImpl.class, new ExecutionQueueImplSerializer(cps));
         sm.addDeserializer(JacksonExecutionQueueImpl.class, new ExecutionQueueImplDeserializer());
         sm.addDeserializer(Continuation.class, new ContinuationDeserializer());
         sm.addDeserializer(Channel.class, new ChannelProxyDeserializer());
         
+        sm.setDeserializerModifier(new BeanDeserializerModifier() {
+
+            public JsonDeserializer<?> modifyDeserializer(
+                    DeserializationConfig config, BeanDescription beanDesc,
+                    JsonDeserializer<?> deserializer) {
+                
+                // use channel proxy deserializer for channels.
+                if (Channel.class.isAssignableFrom(beanDesc.getBeanClass()) && beanDesc.getBeanClass().isInterface()) {
+                    return new ChannelProxyDeserializer();
+                }
+
+                return super.modifyDeserializer(config, beanDesc, deserializer);
+            }
+        });
+        
         om.registerModule(sm);
         om.disable(MapperFeature.AUTO_DETECT_CREATORS);
         om.disable(MapperFeature.AUTO_DETECT_GETTERS);
@@ -82,8 +112,11 @@
 	
     public static class ExecutionQueueImplSerializer extends StdSerializer<JacksonExecutionQueueImpl> {
 
-        public ExecutionQueueImplSerializer() {
+        private ChannelProxySerializer channelProxySerializer;
+
+        public ExecutionQueueImplSerializer(ChannelProxySerializer cps) {
             super(JacksonExecutionQueueImpl.class);
+            this.channelProxySerializer = cps;
         }
         
         @Override
@@ -108,11 +141,44 @@
         private void serializeContents(JacksonExecutionQueueImpl value, JsonGenerator jgen,
                 SerializerProvider provider) throws JsonGenerationException, IOException {
 
-        	jgen.writeNumberField("objIdCounter", value._objIdCounter);
+            channelProxySerializer.getSerializedChannels().clear();
+            
+        	// write metadata
+            jgen.writeNumberField("objIdCounter", value._objIdCounter);
             jgen.writeNumberField("currentCycle", value._currentCycle);
             
+            // write continuations
             jgen.writeObjectField("continuations", value._reactions.toArray(new Continuation[] {}));
+            
+            
+            // channel garbage collection
+            //   - traverse whole object graph and record referenced channel proxies.
+            //     - first, regularily serialize continuations.
+            //     - second, serialize channels to a null serializer in order to record channel references
+            //       without writing them to the stream.
+            //   - remove unused channels.
+            //   - serialize remaining channels.
+
+            // write channels to null serializer
+            JsonGenerator nullgen = new NullJsonGenerator(null, 0, jgen.getCodec());
+            nullgen.writeObjectField("channels", value._channels.values().toArray(new ChannelFrame[] {}));
+
+            // remove unreferenced channels (and keep those which have been exported using export()).
+            Set<Integer> referencedChannels = channelProxySerializer.getSerializedChannels();
+            for (Iterator<ChannelFrame> i = value._channels.values().iterator(); i.hasNext();) {
+                ChannelFrame cframe = i.next();
+                if (referencedChannels.contains(cframe.getId()) || cframe.getRefCount() > 0) {
+                    // skip
+                } else {
+                    LOG.debug("GC Channel: {}", cframe);
+                    i.remove();
+                }
+            }
+
+            // write channels
             jgen.writeObjectField("channels", value._channels.values().toArray(new ChannelFrame[] {}));
+            
+            // write global data
             jgen.writeObjectField("global", value._gdata);
         }
     }
@@ -152,13 +218,12 @@
                     for (ChannelFrame f : frames) {
                         soup._channels.put(f.getId(), f);
                     }
+                } else if ("global".equals(fieldname)) {
+                    soup._gdata = jp.readValueAs(Serializable.class);
                 }
 
             }
 
-            // Garbage collection
-            // TODO
-
             return soup;
         }
 
diff --git a/src/main/java/org/apache/ode/jacob/soup/jackson/JacobJacksonAnnotationIntrospector.java b/src/main/java/org/apache/ode/jacob/soup/jackson/JacobJacksonAnnotationIntrospector.java
index 0cb3a73..ba8b7b1 100644
--- a/src/main/java/org/apache/ode/jacob/soup/jackson/JacobJacksonAnnotationIntrospector.java
+++ b/src/main/java/org/apache/ode/jacob/soup/jackson/JacobJacksonAnnotationIntrospector.java
@@ -15,5 +15,5 @@
     public ObjectIdInfo findObjectIdInfo(Annotated ann) {

         return new ObjectIdInfo("@id", Object.class, ObjectIdGenerators.IntSequenceGenerator.class);

     }

-    

+

 }

diff --git a/src/main/java/org/apache/ode/jacob/soup/jackson/JacobTypeResolverBuilder.java b/src/main/java/org/apache/ode/jacob/soup/jackson/JacobTypeResolverBuilder.java
index b477fcd..8a14a71 100644
--- a/src/main/java/org/apache/ode/jacob/soup/jackson/JacobTypeResolverBuilder.java
+++ b/src/main/java/org/apache/ode/jacob/soup/jackson/JacobTypeResolverBuilder.java
@@ -40,7 +40,6 @@
 import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder;
 import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase;
 import com.fasterxml.jackson.databind.type.TypeFactory;
-import com.fasterxml.jackson.databind.util.ClassUtil;
 
 public class JacobTypeResolverBuilder extends StdTypeResolverBuilder {
 
@@ -65,7 +64,15 @@
         
         return useForType(baseType) ? super.buildTypeSerializer(config, baseType, subtypes) : null;
     }
+
     
+    @Override
+    public TypeDeserializer buildTypeDeserializer(DeserializationConfig config,
+            JavaType baseType, Collection<NamedType> subtypes) {
+        
+        return (useForType(baseType)) ? super.buildTypeDeserializer(config, baseType, subtypes) : null;
+    }
+
     private boolean useForType(JavaType t) {
         if (JacobObject.class.isAssignableFrom(t.getRawClass())) {
             return true;
@@ -82,18 +89,6 @@
         return false;
     }
 
-    @Override
-    public TypeDeserializer buildTypeDeserializer(DeserializationConfig config,
-            JavaType baseType, Collection<NamedType> subtypes) {
-        
-        if (useForType(baseType)) {
-            // set Channel as the default impl.
-            defaultImpl(Channel.class);
-            return super.buildTypeDeserializer(config, baseType, subtypes);
-        }
-        
-        return null;
-    }
 
     public static class ChannelAwareTypeIdResolver extends TypeIdResolverBase {
 
@@ -119,18 +114,7 @@
         }
 
         public JavaType typeFromId(String id) {
-            try {
-                Class<?> cls =  ClassUtil.findClass(id);
-                if (Channel.class.isAssignableFrom(cls) && cls.isInterface()) {
-                    // return null to force Jackson to use default deserializer (which is the ChannelProxyDeserializer)
-                    return null;
-                }
-                return _typeFactory.constructSpecializedType(_baseType, cls);
-            } catch (ClassNotFoundException e) {
-                throw new IllegalArgumentException("Invalid type id '"+id+"' (for id type 'Id.class'): no such class found");
-            } catch (Exception e) {
-                throw new IllegalArgumentException("Invalid type id '"+id+"' (for id type 'Id.class'): "+e.getMessage(), e);
-            }
+            return delegate.typeFromId(id);
         }
 
         public Id getMechanism() {
diff --git a/src/main/java/org/apache/ode/jacob/soup/jackson/NullJsonGenerator.java b/src/main/java/org/apache/ode/jacob/soup/jackson/NullJsonGenerator.java
new file mode 100644
index 0000000..08cd96a
--- /dev/null
+++ b/src/main/java/org/apache/ode/jacob/soup/jackson/NullJsonGenerator.java
@@ -0,0 +1,118 @@
+package org.apache.ode.jacob.soup.jackson;

+

+import java.io.IOException;

+import java.math.BigDecimal;

+import java.math.BigInteger;

+

+import com.fasterxml.jackson.core.Base64Variant;

+import com.fasterxml.jackson.core.JsonGenerationException;

+import com.fasterxml.jackson.core.ObjectCodec;

+import com.fasterxml.jackson.core.io.IOContext;

+import com.fasterxml.jackson.core.json.JsonGeneratorImpl;

+

+/**

+ * No-op Json generator.

+ * 

+ * @author vanto

+ *

+ */

+public class NullJsonGenerator extends JsonGeneratorImpl {

+

+    public NullJsonGenerator(IOContext ctxt, int features, ObjectCodec codec) {

+        super(ctxt, features, codec);

+    }

+

+    public void flush() throws IOException {

+    }

+

+    protected void _releaseBuffers() {

+    }

+

+    protected void _verifyValueWrite(String typeMsg) throws IOException,

+            JsonGenerationException {

+    }

+

+    public void writeStartArray() throws IOException, JsonGenerationException {

+    }

+

+    public void writeEndArray() throws IOException, JsonGenerationException {

+    }

+

+    public void writeStartObject() throws IOException, JsonGenerationException {

+    }

+

+    public void writeEndObject() throws IOException, JsonGenerationException {

+    }

+

+    public void writeFieldName(String name) throws IOException,

+            JsonGenerationException {

+    }

+

+    public void writeString(String text) throws IOException,

+            JsonGenerationException {

+    }

+

+    public void writeString(char[] text, int offset, int len)

+            throws IOException, JsonGenerationException {

+    }

+

+    public void writeRawUTF8String(byte[] text, int offset, int length)

+            throws IOException, JsonGenerationException {

+    }

+

+    public void writeUTF8String(byte[] text, int offset, int length)

+            throws IOException, JsonGenerationException {

+    }

+

+    public void writeRaw(String text) throws IOException,

+            JsonGenerationException {

+    }

+

+    public void writeRaw(String text, int offset, int len) throws IOException,

+            JsonGenerationException {

+    }

+

+    public void writeRaw(char[] text, int offset, int len) throws IOException,

+            JsonGenerationException {

+    }

+

+    public void writeRaw(char c) throws IOException, JsonGenerationException {

+    }

+

+    public void writeBinary(Base64Variant b64variant, byte[] data, int offset,

+            int len) throws IOException, JsonGenerationException {

+    }

+

+    public void writeNumber(int v) throws IOException, JsonGenerationException {

+    }

+

+    public void writeNumber(long v) throws IOException, JsonGenerationException {

+    }

+

+    public void writeNumber(BigInteger v) throws IOException,

+            JsonGenerationException {

+    }

+

+    public void writeNumber(double d) throws IOException,

+            JsonGenerationException {

+    }

+

+    public void writeNumber(float f) throws IOException,

+            JsonGenerationException {

+    }

+

+    public void writeNumber(BigDecimal dec) throws IOException,

+            JsonGenerationException {

+    }

+

+    public void writeNumber(String encodedValue) throws IOException,

+            JsonGenerationException, UnsupportedOperationException {

+    }

+

+    public void writeBoolean(boolean state) throws IOException,

+            JsonGenerationException {

+    }

+

+    public void writeNull() throws IOException, JsonGenerationException {

+    }

+}

diff --git a/src/main/java/org/apache/ode/jacob/vpu/ExecutionQueueImpl.java b/src/main/java/org/apache/ode/jacob/vpu/ExecutionQueueImpl.java
index fff2ae1..a6c0837 100644
--- a/src/main/java/org/apache/ode/jacob/vpu/ExecutionQueueImpl.java
+++ b/src/main/java/org/apache/ode/jacob/vpu/ExecutionQueueImpl.java
@@ -30,9 +30,10 @@
 import java.io.PrintStream;
 import java.io.Serializable;
 import java.lang.reflect.Method;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.Set;
@@ -80,9 +81,9 @@
      * forward progress; this scenario would occur if a maximum processign
      * time-per-instance policy were in effect.
      */
-    protected Set<Continuation> _reactions = new HashSet<Continuation>();
+    protected Set<Continuation> _reactions = new LinkedHashSet<Continuation>();
 
-    protected Map<Integer, ChannelFrame> _channels = new HashMap<Integer, ChannelFrame>();
+    protected Map<Integer, ChannelFrame> _channels = new LinkedHashMap<Integer, ChannelFrame>();
 
     /**
      * The "expected" cycle counter, use to detect database serialization
@@ -96,7 +97,7 @@
 
     protected Serializable _gdata;
 
-    private Map<Object, LinkedList<IndexedObject>> _index = new HashMap<Object, LinkedList<IndexedObject>>();
+    private Map<Object, LinkedList<IndexedObject>> _index = new LinkedHashMap<Object, LinkedList<IndexedObject>>();
 
     public ExecutionQueueImpl(ClassLoader classLoader) {
         _classLoader = classLoader;
@@ -454,9 +455,9 @@
 
         boolean replicatedRecv;
 
-        Set<ObjectFrame> objFrames = new HashSet<ObjectFrame>();
+        Set<ObjectFrame> objFrames = new LinkedHashSet<ObjectFrame>();
 
-        Set<MessageFrame> msgFrames = new HashSet<MessageFrame>();
+        Set<MessageFrame> msgFrames = new LinkedHashSet<MessageFrame>();
 
         public String description;
 
@@ -473,6 +474,18 @@
         public Integer getId() {
             return Integer.valueOf(id);
         }
+        
+        public int getRefCount() {
+            return refCount;
+        }
+        
+        public Set<ObjectFrame> getObjFrames() {
+            return objFrames;
+        }
+
+        public Set<MessageFrame> getMsgFrames() {
+            return msgFrames;
+        }
 
         public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
             type = (Class<?>)in.readObject();
@@ -535,7 +548,7 @@
     @SuppressWarnings("serial")
     protected static class CommGroupFrame implements Serializable {
         boolean replicated;
-        public Set<CommFrame> commFrames = new HashSet<CommFrame>();
+        public Set<CommFrame> commFrames = new LinkedHashSet<CommFrame>();
 
         // default constructor for deserialization
         public CommGroupFrame() {}
@@ -593,14 +606,13 @@
         }
     }
 
-    private static class MessageFrame extends CommFrame implements Externalizable {
+    protected static class MessageFrame extends CommFrame implements Externalizable {
         private static final long serialVersionUID = -1112437852498126297L;
 
         String method;
         Object[] args;
 
         // Used for deserialization
-        @SuppressWarnings("unused")
         public MessageFrame() {
         }
 
diff --git a/src/test/java/org/apache/ode/jacob/examples/helloworld/HelloWorld.java b/src/test/java/org/apache/ode/jacob/examples/helloworld/HelloWorld.java
index 524d350..053d049 100644
--- a/src/test/java/org/apache/ode/jacob/examples/helloworld/HelloWorld.java
+++ b/src/test/java/org/apache/ode/jacob/examples/helloworld/HelloWorld.java
@@ -30,6 +30,8 @@
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.smile.SmileFactory;
+import com.fasterxml.jackson.dataformat.smile.SmileGenerator;
 
 /**
  * Simple Hello World example to showcase different
@@ -254,13 +256,23 @@
     public static void main(String args[]) throws Exception {
         // enable logging
         //BasicConfigurator.configure();
-        long start = System.currentTimeMillis();
-        ObjectMapper mapper = new ObjectMapper(); 
+        
+        SmileFactory sf = null; 
+        // // enable smile:
+        // sf = new SmileFactory();
+        // sf.enable(SmileGenerator.Feature.CHECK_SHARED_STRING_VALUES);
+        // sf.enable(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT);
+        
+        ObjectMapper mapper = new ObjectMapper(sf); 
+        
+        
         JacksonExecutionQueueImpl.configureMapper(mapper);
 
         JacobVPU vpu = new JacobVPU();
         JacksonExecutionQueueImpl queue = new JacksonExecutionQueueImpl();
         vpu.setContext(queue);
+
+        long start = System.currentTimeMillis();
         vpu.inject(new HelloWorld());
         while (vpu.execute()) {
             queue = loadAndRestoreQueue(mapper, (JacksonExecutionQueueImpl)vpu.getContext());
@@ -268,8 +280,8 @@
             System.out.println(vpu.isComplete() ? "<0>" : ".");
             //vpu.dumpState();
         }
-        vpu.dumpState();
         System.out.println("Runtime in ms: " + (System.currentTimeMillis() - start));
+        vpu.dumpState();
     }
 
     public static JacksonExecutionQueueImpl loadAndRestoreQueue(ObjectMapper mapper, JacksonExecutionQueueImpl in) throws Exception {