class CorbaHandlerUtils {

    public static CorbaObjectHandler createTypeHandler(ORB orb,
                                                       QName name,
                                                       QName idlType,
                                                       CorbaTypeMap typeMap) {
        CorbaObjectHandler handler = null;
        TypeCode tc = CorbaUtils.getTypeCode(orb, idlType, typeMap);
        try {
            while (tc.kind().value() == TCKind._tk_alias) {
                Alias alias = (Alias) CorbaUtils.getCorbaType(idlType, typeMap);
                if (alias == null) {
                    throw new CorbaBindingException("Couldn't find corba alias type: " + idlType);
                }
                tc = tc.content_type();
                idlType = alias.getBasetype();
            }
        } catch (Throwable ex) {
            throw new CorbaBindingException(ex);
        }
        if (CorbaUtils.isPrimitiveIdlType(idlType)) {
            handler = new CorbaPrimitiveHandler(name, idlType, tc, null);
        } else if (tc.kind().value() == TCKind._tk_any) {
            // Any is a special kind of primitive so it gets its own handler
            handler = new CorbaAnyHandler(name, idlType, tc, null);
            ((CorbaAnyHandler)handler).setTypeMap(typeMap);
        } else {
            CorbaType type = CorbaUtils.getCorbaType(idlType, typeMap);
            switch (tc.kind().value()) {
            case TCKind._tk_array:
                handler = new CorbaArrayHandler(name, idlType, tc, type);
                break;
            case TCKind._tk_enum:
                handler = new CorbaEnumHandler(name, idlType, tc, type);
                break;
            case TCKind._tk_except:
                handler = new CorbaExceptionHandler(name, idlType, tc, type);
                break;
            case TCKind._tk_fixed:
                handler = new CorbaFixedHandler(name, idlType, tc, type);
                break;
            case TCKind._tk_sequence:
                if (isOctets(type)) {
                    handler = new CorbaOctetSequenceHandler(name, idlType, tc, type);
                } else {
                    handler = new CorbaSequenceHandler(name, idlType, tc, type);
                }
                break;
            case TCKind._tk_struct:
                handler = new CorbaStructHandler(name, idlType, tc, type);
                break;
            case TCKind._tk_union:
                handler = new CorbaUnionHandler(name, idlType, tc, type);
                break;
            case TCKind._tk_string:
            case TCKind._tk_wstring:
                // These need to be here to catch the anonymous string types.
                handler = new CorbaPrimitiveHandler(name, idlType, tc, type);
                break;
            case TCKind._tk_objref:
                handler = new CorbaObjectReferenceHandler(name, idlType, tc, type);
                break;
            default:
                handler = new CorbaObjectHandler(name, idlType, tc, type);
            }
        }

        return handler;
    }

    private  CorbaHandlerUtils();

}