diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/ConFactory_impl.java b/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/ConFactory_impl.java
index 5235d93..7445215 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/ConFactory_impl.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/ConFactory_impl.java
@@ -17,16 +17,36 @@
 
 package org.apache.yoko.orb.OCI.IIOP;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import org.apache.yoko.orb.OCI.IIOP.PLUGIN_ID;
+import org.apache.yoko.orb.CORBA.InputStream;
+import org.apache.yoko.orb.OB.Assert;
+import org.apache.yoko.orb.OB.IORDump;
+import org.apache.yoko.orb.OB.IORUtil;
+import org.apache.yoko.orb.OB.PROTOCOL_POLICY_ID;
+import org.apache.yoko.orb.OB.ProtocolPolicy;
+import org.apache.yoko.orb.OB.ProtocolPolicyHelper;
+import org.apache.yoko.orb.OCI.Buffer;
+import org.apache.yoko.orb.OCI.ConnectCB;
+import org.apache.yoko.orb.OCI.Connector;
 import org.omg.CORBA.ORBPackage.InvalidName;
+import org.omg.CORBA.Policy;
+import org.omg.IIOP.ProfileBody_1_0;
+import org.omg.IIOP.ProfileBody_1_0Helper;
 import org.omg.IOP.Codec;
 import org.omg.IOP.CodecFactory;
+import org.omg.IOP.CodecFactoryPackage.UnknownEncoding;
 import org.omg.IOP.ENCODING_CDR_ENCAPS;
 import org.omg.IOP.Encoding;
-import org.omg.IOP.CodecFactoryPackage.UnknownEncoding;
+import org.omg.IOP.IOR;
+import org.omg.IOP.TAG_ALTERNATE_IIOP_ADDRESS;
+import org.omg.IOP.TAG_INTERNET_IOP;
+import org.omg.IOP.TaggedComponent;
+import org.omg.IOP.TaggedComponentHelper;
+import org.omg.IOP.TaggedProfile;
 
 final class ConFactory_impl extends org.omg.CORBA.LocalObject implements
         org.apache.yoko.orb.OCI.ConFactory {
@@ -55,24 +75,20 @@
     }
 
     public int tag() {
-        return org.omg.IOP.TAG_INTERNET_IOP.value;
+        return TAG_INTERNET_IOP.value;
     }
 
-    public String describe_profile(org.omg.IOP.TaggedProfile profile) {
-        org.apache.yoko.orb.OB.Assert
-                ._OB_assert(profile.tag == org.omg.IOP.TAG_INTERNET_IOP.value);
+    public String describe_profile(TaggedProfile profile) {
+        Assert._OB_assert(profile.tag == TAG_INTERNET_IOP.value);
 
         //
         // Get the IIOP profile body
         //
         byte[] data = profile.profile_data;
-        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);
+        Buffer buf = new Buffer(data, data.length);
+        InputStream in = new InputStream(buf);
         in._OB_readEndian();
-        org.omg.IIOP.ProfileBody_1_0 body = org.omg.IIOP.ProfileBody_1_0Helper
-                .read(in);
+        ProfileBody_1_0 body = ProfileBody_1_0Helper.read(in);
 
         StringBuilder result = new StringBuilder();
 
@@ -89,8 +105,7 @@
             port = body.port;
         result.append("port: " + port + '\n');
         result.append("object_key: (" + body.object_key.length + ")\n");
-        org.apache.yoko.orb.OB.IORUtil.dump_octets(
-                body.object_key, 0, body.object_key.length, result);
+        IORUtil.dump_octets(body.object_key, 0, body.object_key.length, result);
 
         //
         // Print IIOP 1.1 information (components)
@@ -99,139 +114,115 @@
             int l = in.read_ulong();
 
             for (int i = 0; i < l; i++) {
-                org.omg.IOP.TaggedComponent component = org.omg.IOP.TaggedComponentHelper
-                        .read(in);
+                TaggedComponent component = TaggedComponentHelper.read(in);
 
-                org.apache.yoko.orb.OB.IORUtil
-                        .describe_component(component, result);
+                IORUtil.describe_component(component, result);
             }
         }
 
         return result.toString();
     }
 
-    public org.apache.yoko.orb.OCI.Connector[] create_connectors(
-            org.omg.IOP.IOR ior, org.omg.CORBA.Policy[] policies) {
+    private static final Connector[] EMPTY_CONNECTORS = new Connector[0];
+
+    public Connector[] create_connectors(IOR ior, Policy[] policies) {
         if (logger.isLoggable(Level.FINEST)) {
-            logger.finest("Creating connection for ior: " + org.apache.yoko.orb.OB.IORDump.PrintObjref(orb_, ior)); 
+            logger.finest("Creating connection for ior: " + IORDump.PrintObjref(orb_, ior));
         }
         
         //
         // Check whether policies are satisfied
         //
-        for (int i = 0; i < policies.length; i++) {
-            if (policies[i].policy_type() == org.apache.yoko.orb.OB.PROTOCOL_POLICY_ID.value) {
-                org.apache.yoko.orb.OB.ProtocolPolicy protocolPolicy = org.apache.yoko.orb.OB.ProtocolPolicyHelper
-                        .narrow(policies[i]);
+        for (Policy policy: policies) {
+            if (policy.policy_type() == PROTOCOL_POLICY_ID.value) {
+                ProtocolPolicy protocolPolicy = ProtocolPolicyHelper.narrow(policy);
                 if (!protocolPolicy.contains(PLUGIN_ID.value))
-                    return new org.apache.yoko.orb.OCI.Connector[0];
+                    return EMPTY_CONNECTORS;
             }
         }
 
         //
         // Create Connectors from profiles
         //
-        java.util.Vector seq = new java.util.Vector();
-        for (int i = 0; i < ior.profiles.length; i++) {
-            if (ior.profiles[i].tag == tag()) {
+        final List<Connector> connectors = new ArrayList<>();
+        for (TaggedProfile profile: ior.profiles) {
+            if (profile.tag != tag()) continue;
+
+            //
+            // Get the IIOP profile body
+            //
+            final byte[] data = profile.profile_data;
+            final Buffer buf = new Buffer(data, data.length);
+            final InputStream in = new InputStream(buf, 0, false);
+            in._OB_readEndian();
+            final ProfileBody_1_0 body = ProfileBody_1_0Helper.read(in);
+
+            //
+            // Create new connector for this profile
+            //
+            final int port = ((body.port < 0) ? (0xffff + (int) body.port + 1) : body.port);
+            ConnectCB[] cbs = info_._OB_getConnectCBSeq();
+            logger.fine("Creating connector to host=" + body.host +", port=" + port);
+            Codec codec = null;
+            try {
+                    codec = ((CodecFactory) orb_.resolve_initial_references("CodecFactory")).create_codec(CDR_1_2_ENCODING);
+            } catch (InvalidName e) {
+                logger.fine("Could not obtain codec factory using name 'CodecFactory'");
+            } catch (UnknownEncoding e) {
+                logger.fine("Could not obtain codec using encoding " + CDR_1_2_ENCODING);
+            }
+            connectors.add(createConnector(ior, policies, body.host, port, cbs, codec));
+
+            //
+            // If this is a 1.1 profile, check for
+            // TAG_ALTERNATE_IIOP_ADDRESS in the components
+            //
+            if (body.iiop_version.major > 1 || body.iiop_version.minor > 0) {
                 //
-                // Get the IIOP profile body
+                // Unmarshal the tagged components
                 //
-                byte[] data = ior.profiles[i].profile_data;
-                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);
-                in._OB_readEndian();
-                org.omg.IIOP.ProfileBody_1_0 body = org.omg.IIOP.ProfileBody_1_0Helper
-                        .read(in);
+                int len = in.read_ulong();
+                TaggedComponent[] components = new TaggedComponent[len];
+                for (int c = 0; c < len; c++)
+                    components[c] = TaggedComponentHelper.read(in);
 
                 //
-                // Create new connector for this profile
+                // Check for TAG_ALTERNATE_IIOP_ADDRESS
                 //
-                int port;
-                if (body.port < 0)
-                    port = 0xffff + (int) body.port + 1;
-                else
-                    port = (int) body.port;
-                org.apache.yoko.orb.OCI.ConnectCB[] cbs = info_
-                        ._OB_getConnectCBSeq();
-                logger.fine("Creating connector to host=" + body.host +", port=" + port);
-                Codec codec = null;
-                try {
-                        codec = ((CodecFactory) orb_.resolve_initial_references("CodecFactory")).create_codec(CDR_1_2_ENCODING);
-                } catch (InvalidName e) {
-                    logger.fine("Could not obtain codec factory using name 'CodecFactory'");
-                } catch (UnknownEncoding e) {
-                    logger.fine("Could not obtain codec using encoding " + CDR_1_2_ENCODING);
-                }
-                if (connectionHelper_ != null) {
-                    seq.addElement(new Connector_impl(ior, policies, body.host,
-                            port, keepAlive_, cbs, listenMap_,
-                            connectionHelper_, codec));
-                } else {
-                    seq.addElement(new Connector_impl(ior, policies, body.host,
-                            port, keepAlive_, cbs, listenMap_,
-                            extendedConnectionHelper_, codec));
-                }
-                //
-                // If this is a 1.1 profile, check for
-                // TAG_ALTERNATE_IIOP_ADDRESS in the components
-                //
-                if (body.iiop_version.major > 1 || body.iiop_version.minor > 0) {
-                    //
-                    // Unmarshal the tagged components
-                    //
-                    int len = in.read_ulong();
-                    org.omg.IOP.TaggedComponent[] components = new org.omg.IOP.TaggedComponent[len];
-                    for (int c = 0; c < len; c++)
-                        components[c] = org.omg.IOP.TaggedComponentHelper
-                                .read(in);
+                for (TaggedComponent tc: components) {
+                    if (tc.tag == TAG_ALTERNATE_IIOP_ADDRESS.value) {
+                        final Buffer cbuf = new Buffer(tc.component_data, tc.component_data.length);
+                        final InputStream cin = new InputStream(cbuf, 0, false);
+                        cin._OB_readEndian();
+                        final String host = cin.read_string();
+                        final short s = cin.read_ushort();
+                        final int cport = ((s < 0) ? (0xffff + (int) s + 1) : s);
 
-                    //
-                    // Check for TAG_ALTERNATE_IIOP_ADDRESS
-                    //
-                    for (int c = 0; c < components.length; c++)
-                        if (components[c].tag == org.omg.IOP.TAG_ALTERNATE_IIOP_ADDRESS.value) {
-                            byte[] cdata = components[c].component_data;
-                            int clen = components[c].component_data.length;
-                            org.apache.yoko.orb.OCI.Buffer cbuf = new org.apache.yoko.orb.OCI.Buffer(
-                                    cdata, clen);
-                            org.apache.yoko.orb.CORBA.InputStream cin = new org.apache.yoko.orb.CORBA.InputStream(
-                                    cbuf, 0, false);
-                            cin._OB_readEndian();
-                            String host = cin.read_string();
-                            short s = cin.read_ushort();
-                            int cport;
-                            if (s < 0)
-                                cport = 0xffff + (int) s + 1;
-                            else
-                                cport = (int) s;
-
-                            //
-                            // Create new connector for this component
-                            //
-                            org.apache.yoko.orb.OCI.ConnectCB[] ccbs = info_
-                                    ._OB_getConnectCBSeq();
-                            logger.fine("Creating alternate connector to host=" + host +", port=" + cport);
-                            seq.addElement(new Connector_impl(ior, policies, host, cport,
-                                    keepAlive_, ccbs, listenMap_, connectionHelper_, codec));
-                        }
+                        //
+                        // Create new connector for this component
+                        //
+                        ConnectCB[] ccbs = info_._OB_getConnectCBSeq();
+                        logger.fine("Creating alternate connector to host=" + host + ", port=" + cport);
+                        connectors.add(createConnector(ior, policies, host, cport, ccbs, codec));
+                    }
                 }
             }
         }
 
-        org.apache.yoko.orb.OCI.Connector[] result = new org.apache.yoko.orb.OCI.Connector[seq
-                .size()];
-        seq.copyInto(result);
-        return result;
+        return connectors.toArray(EMPTY_CONNECTORS);
     }
 
-    public boolean equivalent(org.omg.IOP.IOR ior1, org.omg.IOP.IOR ior2) {
+    private Connector createConnector(IOR ior, Policy[] policies, String host, int port, ConnectCB[] cbs, Codec codec) {
+        return ((connectionHelper_ != null) ?
+                new Connector_impl(ior, policies, host, port, keepAlive_, cbs, listenMap_, connectionHelper_, codec) :
+                new Connector_impl(ior, policies, host, port, keepAlive_, cbs, listenMap_, extendedConnectionHelper_, codec));
+    }
+
+    public boolean equivalent(IOR ior1, IOR ior2) {
         return Util.equivalent(ior1, ior2);
     }
 
-    public int hash(org.omg.IOP.IOR ior, int max) {
+    public int hash(IOR ior, int max) {
         return Util.hash(ior, max);
     }
 
