Correct format of data for UserExceptionInfo service context
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/InputStream.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/InputStream.java
index bf546da..a7f4184 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/InputStream.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/InputStream.java
@@ -31,6 +31,7 @@
 import org.apache.yoko.orb.OB.Assert;
 import org.apache.yoko.orb.OB.MinorCodes;
 import org.apache.yoko.orb.OB.OB_Extras;
+import org.apache.yoko.orb.OCI.GiopVersion;
 import org.omg.CORBA.CompletionStatus;
 import org.omg.CORBA.MARSHAL;
 import org.omg.CORBA.portable.IDLEntity;
@@ -47,7 +48,7 @@
 
     boolean swap_;
 
-    private int GIOPVersion_ = org.apache.yoko.orb.OB.OB_Extras.DEFAULT_GIOP_VERSION;
+    private GiopVersion giopVersion_ = org.apache.yoko.orb.OB.OB_Extras.DEFAULT_GIOP_VERSION;
 
     private int origPos_;
 
@@ -584,9 +585,9 @@
             // as ushort or ulong, depending on their maximum length
             // listed in the code set registry.
             //
-            switch (GIOPVersion_) {
+            switch (giopVersion_) {
 
-                case 0x0101 : {
+                case GIOP1_1: {
                     if (converter.getFrom().max_bytes <= 2)
                         value = (char) read_ushort();
                     else
@@ -614,12 +615,12 @@
         // UTF-16
         //
         else {
-            switch (GIOPVersion_) {
+            switch (giopVersion_) {
 
             //
             // Orbix2000/ORBacus/E compatible GIOP 1.0 marshaling
             //
-                case 0x0100 : {
+                case GIOP1_0: {
                     buf_.pos_ += (buf_.pos_ & 0x1);
 
                     if (buf_.pos_ + 2 > buf_.len_)
@@ -632,7 +633,7 @@
                     return (char) ((buf_.data_[buf_.pos_++] << 8) | (buf_.data_[buf_.pos_++] & 0xff));
                 }
 
-                case 0x0101 : {
+                case GIOP1_1: {
                     return (char) read_ushort();
                 }
 
@@ -664,8 +665,8 @@
 
             int wcLen = 2;
 
-            switch (GIOPVersion_) {
-                case 0x0100 :
+            switch (giopVersion_) {
+                case GIOP1_0:
                     //
                     // we should not require a reader for GIOP 1.0
                     // wchars since this would mean we are using UTF-16.
@@ -675,7 +676,7 @@
                     org.apache.yoko.orb.OB.Assert._OB_assert(false);
                     break;
 
-                case 0x0101 :
+                case GIOP1_1:
                     //
                     // align on two-byte boundary
                     // 
@@ -708,8 +709,8 @@
             //
             // no reader is required then
             //
-            switch (GIOPVersion_) {
-                case 0x0100 :
+            switch (giopVersion_) {
+                case GIOP1_0:
                     //
                     // UCS-2 is the native wchar codeset for both Orbacus
                     // and Orbix/E so conversion should not be necessary
@@ -734,7 +735,7 @@
                     //
                     return (char) ((buf_.data_[buf_.pos_++] << 8) | (buf_.data_[buf_.pos_++] & 0xff));
 
-                case 0x0101 :
+                case GIOP1_1:
                     //
                     // read according to the endian of the message
                     //
@@ -806,10 +807,10 @@
         //
         // For GIOP 1.1 the length must not be 0.
         //
-        switch (GIOPVersion_) {
+        switch (giopVersion_) {
 
-            case 0x0100 :
-            case 0x0101 : {
+            case GIOP1_0:
+            case GIOP1_1: {
                 if (len == 0)
                     throw new org.omg.CORBA.MARSHAL(
                             org.apache.yoko.orb.OB.MinorCodes.describeMarshal(org.apache.yoko.orb.OB.MinorCodes.MinorReadWStringZeroLength),
@@ -912,10 +913,10 @@
         if (logger.isLoggable(Level.FINE))
             logger.fine(String.format("Reading wstring of length 0x%x", len));
 
-        switch (GIOPVersion_) {
+        switch (giopVersion_) {
 
-            case 0x0100 :
-            case 0x0101 : {
+            case GIOP1_0:
+            case GIOP1_1: {
                 //
                 // it is not legal in GIOP 1.0/1.1 for a string to be 0 in
                 // length... it MUST have a null terminator
@@ -1820,27 +1821,27 @@
     // ------------------------------------------------------------------
 
     public InputStream(org.apache.yoko.orb.OCI.Buffer buf, int offs, boolean swap, org.apache.yoko.orb.OB.CodeConverters codeConverters,
-            int GIOPVersion) {
+            GiopVersion giopVersion) {
         buf_ = buf;
         buf_.pos(offs);
         swap_ = swap;
         origPos_ = offs;
         origSwap_ = swap;
 
-        _OB_codeConverters(codeConverters, GIOPVersion);
+        _OB_codeConverters(codeConverters, giopVersion);
     }
 
     public InputStream(org.apache.yoko.orb.OCI.Buffer buf, int offs, boolean swap) {
-        this(buf, offs, swap, null, 0);
+        this(buf, offs, swap, null, null);
     }
 
     public InputStream(org.apache.yoko.orb.OCI.Buffer buf) {
-        this(buf, 0, false, null, 0);
+        this(buf, 0, false, null, null);
     }
 
-    public void _OB_codeConverters(org.apache.yoko.orb.OB.CodeConverters converters, int GIOPVersion) {
-        if (GIOPVersion != 0)
-            GIOPVersion_ = GIOPVersion;
+    public void _OB_codeConverters(org.apache.yoko.orb.OB.CodeConverters converters, GiopVersion giopVersion) {
+        if (giopVersion != null)
+            giopVersion_ = giopVersion;
 
         charReaderRequired_ = false;
         charConversionRequired_ = false;
@@ -1892,7 +1893,7 @@
         byte[] data = new byte[buf_.len_];
         System.arraycopy(buf_.data_, 0, data, 0, buf_.len_);
         org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(data, data.length);
-        result = new InputStream(buf, origPos_, origSwap_, codeConverters_, GIOPVersion_);
+        result = new InputStream(buf, origPos_, origSwap_, codeConverters_, giopVersion_);
         result.orbInstance_ = orbInstance_;
 
         return result;
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/ObjectImpl.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/ObjectImpl.java
index 3e29a03..780a695 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/ObjectImpl.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/ObjectImpl.java
@@ -17,6 +17,9 @@
 
 package org.apache.yoko.orb.CORBA;
 
+import static org.apache.yoko.orb.OCI.GiopVersion.GIOP1_2;
+
+import org.apache.yoko.orb.OCI.GiopVersion;
 import org.apache.yoko.util.osgi.ProviderLocator;
 
 //
@@ -173,7 +176,7 @@
         org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                 32);
         org.apache.yoko.orb.CORBA.OutputStream out = new org.apache.yoko.orb.CORBA.OutputStream(
-                buf, null, 258);
+                buf, null, GIOP1_2);
 
         //
         // Put the exception into the output stream
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/OutputStream.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/OutputStream.java
index 662b280..c9f627f 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/OutputStream.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/OutputStream.java
@@ -20,6 +20,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.apache.yoko.orb.OCI.GiopVersion;
 import org.omg.CORBA.portable.ValueOutputStream;
 
 final public class OutputStream extends org.omg.CORBA_2_3.portable.OutputStream implements ValueOutputStream {
@@ -29,7 +30,7 @@
 
     public org.apache.yoko.orb.OCI.Buffer buf_;
 
-    private int GIOPVersion_ = org.apache.yoko.orb.OB.OB_Extras.DEFAULT_GIOP_VERSION;
+    private GiopVersion giopVersion_ = org.apache.yoko.orb.OB.OB_Extras.DEFAULT_GIOP_VERSION;
 
     private org.apache.yoko.orb.OB.CodeConverters codeConverters_;
 
@@ -507,8 +508,8 @@
             // as ushort or ulong, depending on their maximum length
             // listed in the code set registry.
             //
-            switch (GIOPVersion_) {
-            case 0x0101: {
+            switch (giopVersion_) {
+            case GIOP1_1: {
                 if (converter.getTo().max_bytes <= 2)
                     write_ushort((short) value);
                 else
@@ -529,19 +530,17 @@
         // UTF-16
         //
         else {
-            switch (GIOPVersion_) {
-            case 0x0100:
-            case 0x0101: {
+            switch (giopVersion_) {
+            case GIOP1_0:
+            case GIOP1_1:
                 write_ushort((short) value);
-            }
                 break;
 
-            default: {
+            default:
                 addCapacity(3);
                 buf_.data_[buf_.pos_++] = 2;
                 buf_.data_[buf_.pos_++] = (byte) (value >> 8);
                 buf_.data_[buf_.pos_++] = (byte) value;
-            }
                 break;
             }
         }
@@ -569,8 +568,8 @@
             // as ushort or ulong, depending on their maximum length
             // listed in the code set registry.
             //
-            switch (GIOPVersion_) {
-            case 0x0100: {
+            switch (giopVersion_) {
+            case GIOP1_0: {
                 //
                 // we don't support special writers for GIOP 1.0 if
                 // conversion is required or if a writer is required
@@ -579,7 +578,7 @@
             }
                 break;
 
-            case 0x0101: {
+            case GIOP1_1: {
                 //
                 // get the length of the character
                 //
@@ -627,8 +626,8 @@
                 break;
             }
         } else {
-            switch (GIOPVersion_) {
-            case 0x0100: {
+            switch (giopVersion_) {
+            case GIOP1_0: {
                 //
                 // Orbix2000/Orbacus/E compatible 1.0 marshal
                 //
@@ -646,7 +645,7 @@
             }
                 break;
 
-            case 0x0101: {
+            case GIOP1_1: {
                 write_ushort((short) value);
             }
                 break;
@@ -688,9 +687,9 @@
         // and contents include a terminating null. The terminating null
         // character for a wstring is also a wide character.
         //
-        switch (GIOPVersion_) {
-        case 0x0100:
-        case 0x0101: {
+        switch (giopVersion_) {
+        case GIOP1_0:
+        case GIOP1_1: {
             write_ulong(len + 1);
             write_wchar_array(arr, 0, len);
             write_wchar((char) 0);
@@ -771,24 +770,26 @@
         // strings requiring a writer/converter (or not) since they can
         // be handled by the write_wchar() method
         //
-        if (GIOPVersion_ == 0x0100 || GIOPVersion_ == 0x0101) {
-            //
-            // write the length of the string
-            //
-            write_ulong(len + 1);
+        switch (giopVersion_) {
+            case GIOP1_0:
+            case GIOP1_1:
+                //
+                // write the length of the string
+                //
+                write_ulong(len + 1);
 
-            //
-            // now write all the characters
-            //
-            for (int i = 0; i < len; i++)
-                write_wchar(arr[i], true);
+                //
+                // now write all the characters
+                //
+                for (int i = 0; i < len; i++)
+                    write_wchar(arr[i], true);
 
-            //
-            // and the null terminator
-            //
-            write_wchar((char) 0, true);
-
-            return;
+                //
+                // and the null terminator
+                //
+                write_wchar((char) 0, true);
+                return;
+            default:
         }
 
         //
@@ -888,7 +889,7 @@
 //      }
 
         InputStream in = new InputStream(buf, 0, false, codeConverters_,
-                GIOPVersion_);
+                giopVersion_);
         in._OB_ORBInstance(orbInstance_);
         return in;
     }
@@ -1859,15 +1860,15 @@
     // ------------------------------------------------------------------
 
     public OutputStream(org.apache.yoko.orb.OCI.Buffer buf) {
-        this(buf, null, 0);
+        this(buf, null, null);
     }
 
     public OutputStream(org.apache.yoko.orb.OCI.Buffer buf,
-            org.apache.yoko.orb.OB.CodeConverters converters, int GIOPVersion) {
+            org.apache.yoko.orb.OB.CodeConverters converters, GiopVersion giopVersion) {
         buf_ = buf;
 
-        if (GIOPVersion != 0)
-            GIOPVersion_ = GIOPVersion;
+        if (giopVersion != null)
+            giopVersion_ = giopVersion;
 
         charWriterRequired_ = false;
         charConversionRequired_ = false;
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Downcall.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Downcall.java
index eef3adb..cda88f5 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Downcall.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Downcall.java
@@ -17,9 +17,13 @@
 
 package org.apache.yoko.orb.OB;
 
+import static org.apache.yoko.orb.OB.CodeSetDatabase.UTF16;
+import static org.apache.yoko.orb.OCI.GiopVersion.GIOP1_2;
+
 import java.util.Vector;
 
 import org.apache.yoko.orb.OCI.Buffer;
+import org.apache.yoko.orb.OCI.GiopVersion;
 import org.omg.CORBA.MARSHAL;
 import org.omg.CORBA.SystemException;
 import org.omg.CORBA.UNKNOWN;
@@ -456,8 +460,7 @@
             in_ = in;
             in_._OB_ORBInstance(orbInstance_);
             CodeConverters codeConverters = client_.codeConverters();
-            in_._OB_codeConverters(codeConverters, (profileInfo_.major << 8)
-                    | profileInfo_.minor);
+            in_._OB_codeConverters(codeConverters, GiopVersion.get(profileInfo_.major, profileInfo_.minor));
         }
     }
 
@@ -478,8 +481,7 @@
         in_ = in;
         in_._OB_ORBInstance(orbInstance_);
         CodeConverters codeConverters = client_.codeConverters();
-        in_._OB_codeConverters(codeConverters, (profileInfo_.major << 8)
-                | profileInfo_.minor);
+        in_._OB_codeConverters(codeConverters, GiopVersion.get(profileInfo_.major, profileInfo_.minor));
     }
 
     public void setUserException(org.apache.yoko.orb.CORBA.InputStream in) {
@@ -564,9 +566,12 @@
             for (ServiceContext sc : replySCL_) {
                 if (sc.context_id == UnknownExceptionInfo.value) {
                     final byte[] data = sc.context_data;
+                    CodeConverters codeConverters = new CodeConverters();
+                    codeConverters.outputWcharConverter = CodeSetDatabase.instance().getConverter(UTF16, UTF16);
                     Buffer buf = new Buffer(data, data.length);
                     try (org.apache.yoko.orb.CORBA.InputStream in =
-                            new org.apache.yoko.orb.CORBA.InputStream(buf, 0, false)) {
+                            new org.apache.yoko.orb.CORBA.InputStream(buf, 0, false, codeConverters, GIOP1_2)) {
+                        in._OB_readEndian();
                         Throwable t = (Throwable) in.read_value();
                         UnknownException x = new UnknownException(t);
                         x.completed = ex.completed;
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/DowncallStub.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/DowncallStub.java
index 813e96e..9f720af 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/DowncallStub.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/DowncallStub.java
@@ -17,10 +17,13 @@
 
 package org.apache.yoko.orb.OB;
  
+import static org.apache.yoko.orb.OCI.GiopVersion.GIOP1_2;
+
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.yoko.orb.OB.RETRY_ALWAYS;
+import org.apache.yoko.orb.OCI.GiopVersion;
 
 //
 // DowncallStub is equivalent to the C++ class OB::MarshalStubImpl
@@ -514,7 +517,7 @@
         Client client = getClientProfilePair(info);
 
         out.value = new org.apache.yoko.orb.CORBA.OutputStream(buf, client
-                .codeConverters(), 258);
+                .codeConverters(), GIOP1_2);
 
         sclHolder.value = client.getAMIRouterSCL();
 
@@ -555,7 +558,7 @@
         Client client = getClientProfilePair(info);
 
         out.value = new org.apache.yoko.orb.CORBA.OutputStream(buf, client
-                .codeConverters(), 258);
+                .codeConverters(), GIOP1_2);
         org.omg.IOP.ServiceContext[] scl = client.getAMIRouterSCL();
 
         GIOPOutgoingMessage outgoing = new GIOPOutgoingMessage(orbInstance_,
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPClient.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPClient.java
index 82190d3..bee1f0d 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPClient.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPClient.java
@@ -17,6 +17,8 @@
 
 package org.apache.yoko.orb.OB;
 
+import org.apache.yoko.orb.OCI.GiopVersion;
+
 final class GIOPClient extends Client {
     protected ORBInstance orbInstance_; // The ORB instance
 
@@ -538,8 +540,7 @@
                     12);
             buf.pos(12);
             out.value = new org.apache.yoko.orb.CORBA.OutputStream(buf,
-                    codeConverters(), (profileInfo.major << 8)
-                            | profileInfo.minor);
+                    codeConverters(), GiopVersion.get(profileInfo.major, profileInfo.minor));
 
             //
             // Create GIOP outgoing message
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java
index a095a6f..2cd687b 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java
@@ -19,6 +19,7 @@
 
 import org.apache.yoko.orb.CORBA.InputStream;
 import org.apache.yoko.orb.OB.Logger;
+import org.apache.yoko.orb.OCI.GiopVersion;
 import org.omg.IOP.ServiceContext;
 import org.omg.SendingContext.CodeBase;
 
@@ -478,8 +479,7 @@
         //
         readCodeConverters(scl.value);
         if (codeConverters_ != null)
-            in._OB_codeConverters(codeConverters_, (version.major << 8)
-                    | version.minor);
+            in._OB_codeConverters(codeConverters_, GiopVersion.get(version.major, version.minor));
 
         //
         // read in the peer's sending context runtime object
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/OB_Extras.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/OB_Extras.java
index 76d5bcb..478196d 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/OB_Extras.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/OB_Extras.java
@@ -17,6 +17,10 @@
 
 package org.apache.yoko.orb.OB;
 
+import static org.apache.yoko.orb.OCI.GiopVersion.GIOP1_0;
+
+import org.apache.yoko.orb.OCI.GiopVersion;
+
 public interface OB_Extras {
     //
     // Whether or not we are building a server capable of the
@@ -27,5 +31,5 @@
     //
     // the default GIOP Version to set for the streams
     //
-    public final int DEFAULT_GIOP_VERSION = 0x0100;
+    public final GiopVersion DEFAULT_GIOP_VERSION = GIOP1_0;
 }
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java
index 3f2e343..c77629f 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java
@@ -17,6 +17,9 @@
 
 package org.apache.yoko.orb.OB;
 
+import static org.apache.yoko.orb.OB.CodeSetDatabase.UTF16;
+import static org.apache.yoko.orb.OCI.GiopVersion.GIOP1_2;
+
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Vector;
@@ -24,11 +27,13 @@
 import java.util.logging.Logger;
 
 import org.apache.yoko.orb.CORBA.OutputStream;
-import org.apache.yoko.orb.OB.DispatchRequest;
-import org.apache.yoko.orb.OB.DispatchStrategy;
 import org.apache.yoko.orb.OCI.Buffer;
+import org.apache.yoko.orb.OCI.GiopVersion;
+import org.apache.yoko.util.cmsf.CmsfThreadLocal;
+import org.apache.yoko.util.cmsf.CmsfThreadLocal.CmsfOverride;
 import org.omg.CORBA.INTERNAL;
 import org.omg.CORBA.portable.UnknownException;
+import org.omg.IOP.ExceptionDetailMessage;
 import org.omg.IOP.ServiceContext;
 import org.omg.IOP.UnknownExceptionInfo;
 
@@ -197,8 +202,7 @@
                 offset);
         buf.pos(offset);
         out_ = new org.apache.yoko.orb.CORBA.OutputStream(buf, in_
-                ._OB_codeConverters(), (profileInfo_.major << 8)
-                | profileInfo_.minor);
+                ._OB_codeConverters(), GiopVersion.get(profileInfo_.major, profileInfo_.minor));
     }
 
     public org.apache.yoko.orb.CORBA.InputStream preUnmarshal()
@@ -311,8 +315,7 @@
         } else {
             org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer();
             out_ = new org.apache.yoko.orb.CORBA.OutputStream(buf, in_
-                    ._OB_codeConverters(), (profileInfo_.major << 8)
-                    | profileInfo_.minor);
+                    ._OB_codeConverters(), GiopVersion.get(profileInfo_.major, profileInfo_.minor));
         }
         out_._OB_ORBInstance(this.orbInstance());
         return out_;
@@ -439,8 +442,8 @@
             addUnsentConnectionServiceContexts();
             userEx_ = false;
             if (ex instanceof UnknownException) {
-                // need to create an exception info service context
-                replySCL_.add(createUnknownExceptionInfoServiceContext((UnknownException)ex));
+                // need to create service contexts for underlying exception
+                createUnknownExceptionServiceContexts((UnknownException)ex, replySCL_);
             }
             ServiceContext[] scl = new ServiceContext[replySCL_.size()];
             replySCL_.copyInto(scl);
@@ -448,13 +451,18 @@
         }
     }
 
-    private static ServiceContext createUnknownExceptionInfoServiceContext(UnknownException ex) {
-        Throwable t = ex.originalEx;
-        Buffer buf = new Buffer();
-        try (OutputStream os = new OutputStream(buf)) {
-            os.write_value(t, Throwable.class);
-            ServiceContext sc = new ServiceContext(UnknownExceptionInfo.value, Arrays.copyOf(buf.data(), buf.length()));
-            return sc;
+    private static void createUnknownExceptionServiceContexts(UnknownException ex, Vector<ServiceContext> scl) {
+        final Throwable t = ex.originalEx;
+        try (CmsfOverride o = CmsfThreadLocal.override()) {
+            CodeConverters codeConverters = new CodeConverters();
+            codeConverters.outputWcharConverter = CodeSetDatabase.instance().getConverter(UTF16, UTF16);
+            Buffer buf = new Buffer();
+            try (OutputStream os = new OutputStream(buf, codeConverters, GIOP1_2)) {
+                os._OB_writeEndian();
+                os.write_value(t, Throwable.class);
+                ServiceContext sc = new ServiceContext(UnknownExceptionInfo.value, Arrays.copyOf(buf.data(), buf.length()));
+                scl.add(sc);
+            }
         } catch (IOException e) {
             throw (INTERNAL)(new INTERNAL(e.getMessage())).initCause(e);
         }
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OBMessaging/ExceptionHolder_impl.java b/yoko-core/src/main/java/org/apache/yoko/orb/OBMessaging/ExceptionHolder_impl.java
index a7e7c4d..982725f 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OBMessaging/ExceptionHolder_impl.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OBMessaging/ExceptionHolder_impl.java
@@ -16,6 +16,9 @@
  */
 
 package org.apache.yoko.orb.OBMessaging;
+import static org.apache.yoko.orb.OCI.GiopVersion.GIOP1_2;
+
+import org.apache.yoko.orb.OCI.GiopVersion;
 import org.apache.yoko.util.osgi.ProviderLocator;
 import org.omg.CORBA.Any;
 
@@ -305,7 +308,7 @@
         org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                 marshaled_exception, marshaled_exception.length);
         org.apache.yoko.orb.CORBA.InputStream in = new org.apache.yoko.orb.CORBA.InputStream(
-                buf, 0, false, null, 258);
+                buf, 0, false, null, GIOP1_2);
 
         return in;
     }
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OCI/GiopVersion.java b/yoko-core/src/main/java/org/apache/yoko/orb/OCI/GiopVersion.java
new file mode 100644
index 0000000..77d793a
--- /dev/null
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OCI/GiopVersion.java
@@ -0,0 +1,23 @@
+package org.apache.yoko.orb.OCI;
+
+public enum GiopVersion {
+    GIOP1_0(1,0), GIOP1_1(1,1), GIOP1_2(1,2);
+
+    public final byte major;
+    public final byte minor;
+
+    private GiopVersion(int major, int minor) {
+        this.major = (byte)(major & 0xff);
+        this.minor = (byte)(minor & 0xff);
+    }
+
+    public static GiopVersion get(byte major, byte minor) {
+        if (major < 1) return GIOP1_0;
+        if (major > 1) return GIOP1_2;
+        switch (minor) {
+            case 0: return GIOP1_0;
+            case 1: return GIOP1_1;
+            default: return GIOP1_2;
+        }
+    }
+}
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/AccFactory_impl.java b/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/AccFactory_impl.java
index 3194c79..0f0b1f3 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/AccFactory_impl.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/AccFactory_impl.java
@@ -190,7 +190,7 @@
                 org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                         data, data.length);
                 org.apache.yoko.orb.CORBA.InputStream in = new org.apache.yoko.orb.CORBA.InputStream(
-                        buf, 0, false, null, 0);
+                        buf, 0, false, null, null);
                 in._OB_readEndian();
                 org.omg.IIOP.ProfileBody_1_0 body = org.omg.IIOP.ProfileBody_1_0Helper
                         .read(in);
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/Util.java b/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/Util.java
index 07ceeed..4057148 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/Util.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/Util.java
@@ -94,7 +94,7 @@
         org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                 ior.profiles[profile].profile_data,
                 ior.profiles[profile].profile_data.length);
-        InputStream in = new InputStream(buf, 0, false, null, 0);
+        InputStream in = new InputStream(buf, 0, false, null, null);
         in._OB_readEndian();
         org.omg.IIOP.ProfileBody_1_0 body = org.omg.IIOP.ProfileBody_1_0Helper
                 .read(in);
@@ -184,7 +184,7 @@
                 byte[] data = ior.profiles[i].profile_data;
                 org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                         data, data.length);
-                InputStream in = new InputStream(buf, 0, false, null, 0);
+                InputStream in = new InputStream(buf, 0, false, null, null);
                 in._OB_readEndian();
                 org.omg.IIOP.ProfileBody_1_0 body = org.omg.IIOP.ProfileBody_1_0Helper
                         .read(in);
@@ -223,7 +223,7 @@
                                 org.apache.yoko.orb.OCI.Buffer b = new org.apache.yoko.orb.OCI.Buffer(
                                         d, d.length);
                                 InputStream s = new InputStream(b, 0, false,
-                                        null, 0);
+                                        null, null);
                                 s._OB_readEndian();
                                 String altHost = s.read_string();
                                 short altPort = s.read_ushort();
@@ -334,7 +334,7 @@
                 byte[] data = ior1.profiles[p1].profile_data;
                 org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                         data, data.length);
-                InputStream in = new InputStream(buf, 0, false, null, 0);
+                InputStream in = new InputStream(buf, 0, false, null, null);
                 in._OB_readEndian();
                 bodies1[b1++] = org.omg.IIOP.ProfileBody_1_0Helper.read(in);
             }
@@ -351,7 +351,7 @@
                 byte[] data = ior2.profiles[p2].profile_data;
                 org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                         data, data.length);
-                InputStream in = new InputStream(buf, 0, false, null, 0);
+                InputStream in = new InputStream(buf, 0, false, null, null);
                 in._OB_readEndian();
                 bodies2[b2++] = org.omg.IIOP.ProfileBody_1_0Helper.read(in);
             }
@@ -466,7 +466,7 @@
                 byte[] data = ior.profiles[i].profile_data;
                 org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
                         data, data.length);
-                InputStream in = new InputStream(buf, 0, false, null, 0);
+                InputStream in = new InputStream(buf, 0, false, null, null);
                 in._OB_readEndian();
                 org.omg.IIOP.ProfileBody_1_0 body = org.omg.IIOP.ProfileBody_1_0Helper
                         .read(in);
diff --git a/yoko-core/src/test/java/org/apache/yoko/RMIExceptionHandlingTest.java b/yoko-core/src/test/java/org/apache/yoko/RMIExceptionHandlingTest.java
index 17e8916..b24f4ff 100644
--- a/yoko-core/src/test/java/org/apache/yoko/RMIExceptionHandlingTest.java
+++ b/yoko-core/src/test/java/org/apache/yoko/RMIExceptionHandlingTest.java
@@ -7,7 +7,6 @@
 
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.omg.CORBA.ORB;
 import org.omg.PortableServer.POA;
@@ -26,13 +25,23 @@
     private static ORB serverOrb;
     private static ORB clientOrb;
     private static String ior;
+    private static MyAppException mae = null;
+    private static MyRuntimeException mre = null;
 
     private static ORB initOrb(Properties props, String... args) {
         return ORB.init(args, props);
     }
 
+    private static void initExceptions() {
+        if (mae == null) mae = new MyAppException();
+        if (mre == null) mre = new MyRuntimeException();
+    }
+
     @BeforeClass
     public static void createServerORB() throws Exception {
+        initExceptions();
+        ThrowerImpl.myAppException = mae;
+        ThrowerImpl.myRuntimeException = mre;
         serverOrb = initOrb(new Properties() {{
             put("org.omg.PortableInterceptor.ORBInitializerClass." + MyClientRequestInterceptor.class.getName(),"");
             put("org.omg.PortableInterceptor.ORBInitializerClass." + MyServerRequestInterceptor.class.getName(),"");
@@ -41,7 +50,7 @@
         poa.the_POAManager().activate();
 
         _ThrowerImpl_Tie tie = new _ThrowerImpl_Tie();
-        tie.setTarget(new ThrowerImpl());
+        tie.setTarget(new ThrowerImpl(serverOrb));
 
         poa.activate_object(tie);
         ior = serverOrb.object_to_string(tie.thisObject());
@@ -83,4 +92,27 @@
         Thrower thrower = (Thrower) PortableRemoteObject.narrow(o, Thrower.class);
         return thrower;
     }
+
+    public static void main(String...args) throws Exception {
+        if (0 == args.length) {
+            System.out.println("Starting server");
+            mae = new MyAppException();
+            mre = new MyRuntimeException();
+            createServerORB();
+            System.out.println(serverOrb.getClass().getName());
+            serverOrb.run();
+        } else {
+            System.out.println("Starting client");
+            ior = args[0];
+            createClientORB();
+            System.out.println(clientOrb.getClass().getName());
+
+            RMIExceptionHandlingTest test = new RMIExceptionHandlingTest();
+            try {
+                test.testRuntimeException();
+                throw new Exception("no exception seen");
+            } catch (MyRuntimeException e) {
+            }
+        }
+    }
 }
diff --git a/yoko-core/src/test/java/test/rmi/exceptionhandling/ThrowerImpl.java b/yoko-core/src/test/java/test/rmi/exceptionhandling/ThrowerImpl.java
index 63c1cb8..4d2ee9e 100644
--- a/yoko-core/src/test/java/test/rmi/exceptionhandling/ThrowerImpl.java
+++ b/yoko-core/src/test/java/test/rmi/exceptionhandling/ThrowerImpl.java
@@ -2,14 +2,24 @@
 
 import java.rmi.RemoteException;
 
+import org.omg.CORBA.ORB;
+
 public class ThrowerImpl implements Thrower {
+    public static MyRuntimeException myRuntimeException;
+    public static MyAppException myAppException;
+    final ORB orb;
+
+    public ThrowerImpl(ORB orb) {
+        this.orb = orb;
+    }
+
     @Override
     public void throwAppException() throws RemoteException, MyAppException {
-        throw new MyAppException();
+        throw myAppException;
     }
 
     @Override
     public void throwRuntimeException() throws RemoteException {
-        throw new MyRuntimeException();
+        throw myRuntimeException;
     }
 }
\ No newline at end of file
diff --git a/yoko-spec-corba/src/main/java/org/omg/IOP/ExceptionDetailMessage.java b/yoko-spec-corba/src/main/java/org/omg/IOP/ExceptionDetailMessage.java
new file mode 100644
index 0000000..e91718b
--- /dev/null
+++ b/yoko-spec-corba/src/main/java/org/omg/IOP/ExceptionDetailMessage.java
@@ -0,0 +1,26 @@
+/*
+ *  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.omg.IOP;
+
+//
+//IDL:omg.org/IOP/ExceptionDetailMessage:1.0
+//
+/***/
+
+public interface ExceptionDetailMessage {
+    int value = (int)(14L);
+}