private EncoderBase new_encoder (int size, SessionBase session, int version) {
        
        if (options.encoder == null) {
            if (version == V1Protocol.VERSION)
                return new V1Encoder (size, session);
            return new Encoder (size);
        }
        
        try {
            Constructor<? extends EncoderBase> econ;
            
            if (version == 0) {
                econ = options.encoder.getConstructor (int.class);
                return econ.newInstance (size);
            } else {
                econ = options.encoder.getConstructor (int.class, IMsgSource.class, int.class);
                return econ.newInstance (size, session, version);
            }
        } catch (SecurityException e) {
            throw new ZError.InstantiationException (e);
        } catch (NoSuchMethodException e) {
            throw new ZError.InstantiationException (e);
        } catch (InvocationTargetException e) {
            throw new ZError.InstantiationException (e);
        } catch (IllegalAccessException e) {
            throw new ZError.InstantiationException (e);
        } catch (InstantiationException e) {
            throw new ZError.InstantiationException (e);
        }
    }