package krpc.client.services;

import com.google.protobuf.ByteString;

import krpc.client.Connection;
import krpc.client.Encoder;
import krpc.client.RemoteEnum;
import krpc.client.RemoteObject;
import krpc.client.RemoteStruct;
import krpc.client.RPCInfo;
import krpc.client.RPCException;
import krpc.client.Types;

// Generated code references its own deprecated members (e.g. when registering
// exception types), so suppress the deprecation warnings within this class.
@SuppressWarnings("deprecation")
public class TestService {

    public static TestService newInstance(Connection connection) {
        return new TestService(connection);
    }

    private Connection connection;

    private TestService(Connection connection) {
        this.connection = connection;
        addExceptionTypes(connection);
    }

    public static class CustomException extends krpc.client.RPCException {
        private static final long serialVersionUID = 653216682626171239L;

        public CustomException(String message) {
            super(message);
        }

        public CustomException(String message, Exception innerException) {
            super(message, innerException);
        }
    }

    /**
     * Deprecated exception documentation string.
     *
     * @deprecated Use CustomException instead.
     */
    @Deprecated
    public static class DeprecatedException extends krpc.client.RPCException {
        private static final long serialVersionUID = 483570852596919585L;

        public DeprecatedException(String message) {
            super(message);
        }

        public DeprecatedException(String message, Exception innerException) {
            super(message, innerException);
        }
    }

    private void addExceptionTypes(Connection connection) {
        connection.addExceptionType("TestService", "CustomException", CustomException.class);
        connection.addExceptionType("TestService", "DeprecatedException", DeprecatedException.class);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "AddMultipleValues", types = _Types.class)
    public String addMultipleValues(float x, int y, long z) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT)),
            Encoder.encode(y, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)),
            Encoder.encode(z, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "AddMultipleValues", _args);
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "AddToObjectList", types = _Types.class)
    public java.util.List<krpc.client.services.TestService.TestClass> addToObjectList(java.util.List<krpc.client.services.TestService.TestClass> l, String value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(l, krpc.client.Types.createList(krpc.client.Types.createClass("TestService", "TestClass"))),
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "AddToObjectList", _args);
        return (java.util.List<krpc.client.services.TestService.TestClass>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createClass("TestService", "TestClass")), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "BlockingProcedure", types = _Types.class)
    public int blockingProcedure(int n, int sum) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(n, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)),
            Encoder.encode(sum, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "BlockingProcedure", _args);
        return (int) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "BoolToString", types = _Types.class)
    public String boolToString(boolean value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.BOOL))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "BoolToString", _args);
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "BytesToHexString", types = _Types.class)
    public String bytesToHexString(byte[] value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.BYTES))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "BytesToHexString", _args);
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "Counter", types = _Types.class)
    public int counter(String id, int divisor) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(id, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)),
            Encoder.encode(divisor, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "Counter", _args);
        return (int) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), this.connection);
    }

    /**
     * Returns a struct whose IntField counts the number of times it has been called,
     * so that a stream on it changes on every update.
     */
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "CounterStruct", types = _Types.class)
    public krpc.client.services.TestService.TestStruct counterStruct(String id) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(id, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "CounterStruct", _args);
        return (krpc.client.services.TestService.TestStruct) Encoder.decode(_data.getValue(), krpc.client.Types.createStruct("TestService", "TestStruct"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "CreateTestObject", types = _Types.class)
    public krpc.client.services.TestService.TestClass createTestObject(String value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "CreateTestObject", _args);
        return (krpc.client.services.TestService.TestClass) Encoder.decode(_data.getValue(), krpc.client.Types.createClass("TestService", "TestClass"), this.connection);
    }

    /**
     * Deprecated procedure documentation string.
     *
     * @deprecated Use floatToString instead.
     */
    @Deprecated
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "DeprecatedProcedure", types = _Types.class)
    public String deprecatedProcedure(float value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "DeprecatedProcedure", _args);
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    /**
     * Deprecated procedure with no reason documentation string.
     */
    @Deprecated
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "DeprecatedProcedureNoMessage", types = _Types.class)
    public String deprecatedProcedureNoMessage(float value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "DeprecatedProcedureNoMessage", _args);
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "DictionaryDefault", types = _Types.class)
    public java.util.Map<Integer,Boolean> dictionaryDefault(java.util.Map<Integer,Boolean> x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.BOOL)))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "DictionaryDefault", _args);
        return (java.util.Map<Integer,Boolean>) Encoder.decode(_data.getValue(), krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.BOOL)), this.connection);
    }

    /**
     * Procedure whose defaults are the special values of double.
     */
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "DoubleSpecialDefaults", types = _Types.class)
    public java.util.List<Double> doubleSpecialDefaults(double nan, double infinity, double negativeInfinity, double maximum, double lowest) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(nan, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE)),
            Encoder.encode(infinity, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE)),
            Encoder.encode(negativeInfinity, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE)),
            Encoder.encode(maximum, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE)),
            Encoder.encode(lowest, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "DoubleSpecialDefaults", _args);
        return (java.util.List<Double>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE)), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "DoubleToString", types = _Types.class)
    public String doubleToString(double value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "DoubleToString", _args);
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    /**
     * The expression tree of a function, as text.
     */
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "DumpExpressionTree", types = _Types.class)
    public String dumpExpressionTree(krpc.client.services.KRPC.Expression expression) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(expression, krpc.client.Types.createClass("KRPC", "Expression"))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "DumpExpressionTree", _args);
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EchoDictionaryOfNullableObjects", types = _Types.class)
    public java.util.Map<String,krpc.client.services.TestService.TestClass> echoDictionaryOfNullableObjects(java.util.Map<String,krpc.client.services.TestService.TestClass> d) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(d, krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EchoDictionaryOfNullableObjects", _args);
        return (java.util.Map<String,krpc.client.services.TestService.TestClass>) Encoder.decode(_data.getValue(), krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EchoListOfNullableInts", types = _Types.class)
    public java.util.List<Integer> echoListOfNullableInts(java.util.List<Integer> l) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(l, krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EchoListOfNullableInts", _args);
        return (java.util.List<Integer>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EchoListOfNullableObjects", types = _Types.class)
    public java.util.List<krpc.client.services.TestService.TestClass> echoListOfNullableObjects(java.util.List<krpc.client.services.TestService.TestClass> l) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(l, krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EchoListOfNullableObjects", _args);
        return (java.util.List<krpc.client.services.TestService.TestClass>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EchoNestedListOfNullableObjects", types = _Types.class)
    public java.util.List<java.util.List<krpc.client.services.TestService.TestClass>> echoNestedListOfNullableObjects(java.util.List<java.util.List<krpc.client.services.TestService.TestClass>> l) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(l, krpc.client.Types.createList(krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass")))))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EchoNestedListOfNullableObjects", _args);
        return (java.util.List<java.util.List<krpc.client.services.TestService.TestClass>>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass")))), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EchoNestedNullableStruct", types = _Types.class)
    public krpc.client.services.TestService.TestNestedNullableStruct echoNestedNullableStruct(krpc.client.services.TestService.TestNestedNullableStruct value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createStruct("TestService", "TestNestedNullableStruct"))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EchoNestedNullableStruct", _args);
        return (krpc.client.services.TestService.TestNestedNullableStruct) Encoder.decode(_data.getValue(), krpc.client.Types.createStruct("TestService", "TestNestedNullableStruct"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EchoNullableInt", types = _Types.class)
    public Integer echoNullableInt(Integer value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EchoNullableInt", _args);
        if (_data.getIsNull()) {
          return null;
        }
        return (Integer) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EchoNullableList", types = _Types.class)
    public java.util.List<Integer> echoNullableList(java.util.List<Integer> l) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(l, krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EchoNullableList", _args);
        if (_data.getIsNull()) {
          return null;
        }
        return (java.util.List<Integer>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EchoNullableString", types = _Types.class)
    public String echoNullableString(String value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EchoNullableString", _args);
        if (_data.getIsNull()) {
          return null;
        }
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EchoTestObject", types = _Types.class)
    public krpc.client.services.TestService.TestClass echoTestObject(krpc.client.services.TestService.TestClass value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createClass("TestService", "TestClass"))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EchoTestObject", _args);
        if (_data.getIsNull()) {
          return null;
        }
        return (krpc.client.services.TestService.TestClass) Encoder.decode(_data.getValue(), krpc.client.Types.createClass("TestService", "TestClass"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EchoTupleWithANullableObject", types = _Types.class)
    public org.javatuples.Pair<Integer,krpc.client.services.TestService.TestClass> echoTupleWithANullableObject(org.javatuples.Pair<Integer,krpc.client.services.TestService.TestClass> t) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(t, krpc.client.Types.createTuple(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EchoTupleWithANullableObject", _args);
        return (org.javatuples.Pair<Integer,krpc.client.services.TestService.TestClass>) Encoder.decode(_data.getValue(), krpc.client.Types.createTuple(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EmptyListDefault", types = _Types.class)
    public java.util.List<String> emptyListDefault(java.util.List<String> x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EmptyListDefault", _args);
        return (java.util.List<String>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EnumDefaultArg", types = _Types.class)
    public krpc.client.services.TestService.TestEnum enumDefaultArg(krpc.client.services.TestService.TestEnum x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createEnumeration("TestService", "TestEnum"))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EnumDefaultArg", _args);
        return (krpc.client.services.TestService.TestEnum) Encoder.decode(_data.getValue(), krpc.client.Types.createEnumeration("TestService", "TestEnum"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EnumEcho", types = _Types.class)
    public krpc.client.services.TestService.TestEnum enumEcho(krpc.client.services.TestService.TestEnum x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createEnumeration("TestService", "TestEnum"))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EnumEcho", _args);
        return (krpc.client.services.TestService.TestEnum) Encoder.decode(_data.getValue(), krpc.client.Types.createEnumeration("TestService", "TestEnum"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EnumListDefault", types = _Types.class)
    public java.util.List<krpc.client.services.TestService.TestEnum> enumListDefault(java.util.List<krpc.client.services.TestService.TestEnum> x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createList(krpc.client.Types.createEnumeration("TestService", "TestEnum")))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EnumListDefault", _args);
        return (java.util.List<krpc.client.services.TestService.TestEnum>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createEnumeration("TestService", "TestEnum")), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "EnumReturn", types = _Types.class)
    public krpc.client.services.TestService.TestEnum enumReturn() throws RPCException {
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "EnumReturn");
        return (krpc.client.services.TestService.TestEnum) Encoder.decode(_data.getValue(), krpc.client.Types.createEnumeration("TestService", "TestEnum"), this.connection);
    }

    /**
     * Procedure whose defaults are the special values of float, plus a finite fraction
     * that no float can hold exactly.
     */
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "FloatSpecialDefaults", types = _Types.class)
    public java.util.List<Float> floatSpecialDefaults(float nan, float infinity, float negativeInfinity, float maximum, float lowest, float fraction) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(nan, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT)),
            Encoder.encode(infinity, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT)),
            Encoder.encode(negativeInfinity, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT)),
            Encoder.encode(maximum, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT)),
            Encoder.encode(lowest, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT)),
            Encoder.encode(fraction, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "FloatSpecialDefaults", _args);
        return (java.util.List<Float>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT)), this.connection);
    }

    /**
     * Procedure documentation string.
     */
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "FloatToString", types = _Types.class)
    public String floatToString(float value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "FloatToString", _args);
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "IncrementDictionary", types = _Types.class)
    public java.util.Map<String,Integer> incrementDictionary(java.util.Map<String,Integer> d) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(d, krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "IncrementDictionary", _args);
        return (java.util.Map<String,Integer>) Encoder.decode(_data.getValue(), krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "IncrementList", types = _Types.class)
    public java.util.List<Integer> incrementList(java.util.List<Integer> l) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(l, krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "IncrementList", _args);
        return (java.util.List<Integer>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "IncrementListOfStructs", types = _Types.class)
    public java.util.List<krpc.client.services.TestService.TestStruct> incrementListOfStructs(java.util.List<krpc.client.services.TestService.TestStruct> l) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(l, krpc.client.Types.createList(krpc.client.Types.createStruct("TestService", "TestStruct")))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "IncrementListOfStructs", _args);
        return (java.util.List<krpc.client.services.TestService.TestStruct>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createStruct("TestService", "TestStruct")), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "IncrementNestedCollection", types = _Types.class)
    public java.util.Map<String,java.util.List<Integer>> incrementNestedCollection(java.util.Map<String,java.util.List<Integer>> d) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(d, krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "IncrementNestedCollection", _args);
        return (java.util.Map<String,java.util.List<Integer>>) Encoder.decode(_data.getValue(), krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "IncrementSet", types = _Types.class)
    public java.util.Set<Integer> incrementSet(java.util.Set<Integer> h) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(h, krpc.client.Types.createSet(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "IncrementSet", _args);
        return (java.util.Set<Integer>) Encoder.decode(_data.getValue(), krpc.client.Types.createSet(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "IncrementTuple", types = _Types.class)
    public org.javatuples.Pair<Integer,Long> incrementTuple(org.javatuples.Pair<Integer,Long> t) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(t, krpc.client.Types.createTuple(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64)))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "IncrementTuple", _args);
        return (org.javatuples.Pair<Integer,Long>) Encoder.decode(_data.getValue(), krpc.client.Types.createTuple(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64)), this.connection);
    }

    /**
     * Procedure whose defaults are the extremes of int.
     */
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "Int32SpecialDefaults", types = _Types.class)
    public java.util.List<Integer> int32SpecialDefaults(int maximum, int minimum) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(maximum, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)),
            Encoder.encode(minimum, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "Int32SpecialDefaults", _args);
        return (java.util.List<Integer>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "Int32ToString", types = _Types.class)
    public String int32ToString(int value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "Int32ToString", _args);
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    /**
     * Procedure whose defaults are the extremes of long.
     */
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "Int64SpecialDefaults", types = _Types.class)
    public java.util.List<Long> int64SpecialDefaults(long maximum, long minimum) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(maximum, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64)),
            Encoder.encode(minimum, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "Int64SpecialDefaults", _args);
        return (java.util.List<Long>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64)), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "Int64ToString", types = _Types.class)
    public String int64ToString(long value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "Int64ToString", _args);
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "ListDefault", types = _Types.class)
    public java.util.List<Integer> listDefault(java.util.List<Integer> x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "ListDefault", _args);
        return (java.util.List<Integer>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "NestedStructEcho", types = _Types.class)
    public krpc.client.services.TestService.TestNestedStruct nestedStructEcho(krpc.client.services.TestService.TestNestedStruct x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createStruct("TestService", "TestNestedStruct"))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "NestedStructEcho", _args);
        return (krpc.client.services.TestService.TestNestedStruct) Encoder.decode(_data.getValue(), krpc.client.Types.createStruct("TestService", "TestNestedStruct"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "NotNullableObject", types = _Types.class)
    public krpc.client.services.TestService.TestClass notNullableObject(krpc.client.services.TestService.TestClass value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createClass("TestService", "TestClass"))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "NotNullableObject", _args);
        return (krpc.client.services.TestService.TestClass) Encoder.decode(_data.getValue(), krpc.client.Types.createClass("TestService", "TestClass"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "NullableStructEcho", types = _Types.class)
    public krpc.client.services.TestService.TestNullableStruct nullableStructEcho(krpc.client.services.TestService.TestNullableStruct x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createStruct("TestService", "TestNullableStruct"))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "NullableStructEcho", _args);
        return (krpc.client.services.TestService.TestNullableStruct) Encoder.decode(_data.getValue(), krpc.client.Types.createStruct("TestService", "TestNullableStruct"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "OnTimer", types = _Types.class)
    public krpc.client.Event onTimer(int milliseconds, int repeats) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(milliseconds, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT32)),
            Encoder.encode(repeats, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT32))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "OnTimer", _args);
        return (krpc.client.Event) Encoder.decode(_data.getValue(), krpc.client.Types.createMessage(krpc.schema.KRPC.Type.TypeCode.EVENT), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "OnTimerUsingLambda", types = _Types.class)
    public krpc.client.Event onTimerUsingLambda(int milliseconds) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(milliseconds, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT32))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "OnTimerUsingLambda", _args);
        return (krpc.client.Event) Encoder.decode(_data.getValue(), krpc.client.Types.createMessage(krpc.schema.KRPC.Type.TypeCode.EVENT), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "OptionalArguments", types = _Types.class)
    public String optionalArguments(String x, String y, String z, krpc.client.services.TestService.TestClass obj) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)),
            Encoder.encode(y, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)),
            Encoder.encode(z, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)),
            Encoder.encode(obj, krpc.client.Types.createClass("TestService", "TestClass"))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "OptionalArguments", _args);
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "RemoveEventAfter", types = _Types.class)
    public krpc.client.Event removeEventAfter(int milliseconds) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(milliseconds, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT32))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "RemoveEventAfter", _args);
        return (krpc.client.Event) Encoder.decode(_data.getValue(), krpc.client.Types.createMessage(krpc.schema.KRPC.Type.TypeCode.EVENT), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "ResetCustomExceptionLater", types = _Types.class)
    public void resetCustomExceptionLater() throws RPCException {
        this.connection.invoke("TestService", "ResetCustomExceptionLater");
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "ResetInvalidOperationExceptionLater", types = _Types.class)
    public void resetInvalidOperationExceptionLater() throws RPCException {
        this.connection.invoke("TestService", "ResetInvalidOperationExceptionLater");
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "ReturnNullWhenNotAllowed", types = _Types.class)
    public krpc.client.services.TestService.TestClass returnNullWhenNotAllowed() throws RPCException {
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "ReturnNullWhenNotAllowed");
        return (krpc.client.services.TestService.TestClass) Encoder.decode(_data.getValue(), krpc.client.Types.createClass("TestService", "TestClass"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "SetDefault", types = _Types.class)
    public java.util.Set<Integer> setDefault(java.util.Set<Integer> x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createSet(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "SetDefault", _args);
        return (java.util.Set<Integer>) Encoder.decode(_data.getValue(), krpc.client.Types.createSet(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "StringToInt32", types = _Types.class)
    public int stringToInt32(String value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "StringToInt32", _args);
        return (int) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "StructDefault", types = _Types.class)
    public krpc.client.services.TestService.TestStruct structDefault(krpc.client.services.TestService.TestStruct x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createStruct("TestService", "TestStruct"))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "StructDefault", _args);
        return (krpc.client.services.TestService.TestStruct) Encoder.decode(_data.getValue(), krpc.client.Types.createStruct("TestService", "TestStruct"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "StructEcho", types = _Types.class)
    public krpc.client.services.TestService.TestStruct structEcho(krpc.client.services.TestService.TestStruct x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createStruct("TestService", "TestStruct"))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "StructEcho", _args);
        return (krpc.client.services.TestService.TestStruct) Encoder.decode(_data.getValue(), krpc.client.Types.createStruct("TestService", "TestStruct"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "StructEchoNullable", types = _Types.class)
    public krpc.client.services.TestService.TestStruct structEchoNullable(krpc.client.services.TestService.TestStruct x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createStruct("TestService", "TestStruct"))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "StructEchoNullable", _args);
        if (_data.getIsNull()) {
          return null;
        }
        return (krpc.client.services.TestService.TestStruct) Encoder.decode(_data.getValue(), krpc.client.Types.createStruct("TestService", "TestStruct"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "ThrowArgumentException", types = _Types.class)
    public int throwArgumentException() throws RPCException {
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "ThrowArgumentException");
        return (int) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "ThrowArgumentNullException", types = _Types.class)
    public int throwArgumentNullException(String foo) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(foo, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "ThrowArgumentNullException", _args);
        return (int) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "ThrowArgumentOutOfRangeException", types = _Types.class)
    public int throwArgumentOutOfRangeException(int foo) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(foo, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "ThrowArgumentOutOfRangeException", _args);
        return (int) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "ThrowCustomException", types = _Types.class)
    public int throwCustomException() throws RPCException {
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "ThrowCustomException");
        return (int) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "ThrowCustomExceptionLater", types = _Types.class)
    public int throwCustomExceptionLater() throws RPCException {
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "ThrowCustomExceptionLater");
        return (int) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "ThrowInvalidOperationException", types = _Types.class)
    public int throwInvalidOperationException() throws RPCException {
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "ThrowInvalidOperationException");
        return (int) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "ThrowInvalidOperationExceptionLater", types = _Types.class)
    public int throwInvalidOperationExceptionLater() throws RPCException {
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "ThrowInvalidOperationExceptionLater");
        return (int) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "TupleDefault", types = _Types.class)
    public org.javatuples.Pair<Integer,Boolean> tupleDefault(org.javatuples.Pair<Integer,Boolean> x) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(x, krpc.client.Types.createTuple(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.BOOL)))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "TupleDefault", _args);
        return (org.javatuples.Pair<Integer,Boolean>) Encoder.decode(_data.getValue(), krpc.client.Types.createTuple(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.BOOL)), this.connection);
    }

    /**
     * Procedure whose default is the largest uint.
     */
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "Uint32SpecialDefaults", types = _Types.class)
    public java.util.List<Integer> uint32SpecialDefaults(int maximum) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(maximum, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT32))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "Uint32SpecialDefaults", _args);
        return (java.util.List<Integer>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT32)), this.connection);
    }

    /**
     * Procedure whose default is the largest ulong.
     */
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "Uint64SpecialDefaults", types = _Types.class)
    public java.util.List<Long> uint64SpecialDefaults(long maximum) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(maximum, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT64))
        };
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "Uint64SpecialDefaults", _args);
        return (java.util.List<Long>) Encoder.decode(_data.getValue(), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT64)), this.connection);
    }

    /**
     * Deprecated property documentation string.
     *
     * @deprecated Use stringProperty instead.
     */
    @Deprecated
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "get_DeprecatedProperty", types = _Types.class)
    public String getDeprecatedProperty() throws RPCException {
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "get_DeprecatedProperty");
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    /**
     * Deprecated property documentation string.
     *
     * @deprecated Use stringProperty instead.
     */
    @Deprecated
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "set_DeprecatedProperty", types = _Types.class)
    public void setDeprecatedProperty(String value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING))
        };
        this.connection.invoke("TestService", "set_DeprecatedProperty", _args);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "get_NullableObject", types = _Types.class)
    public krpc.client.services.TestService.TestClass getNullableObject() throws RPCException {
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "get_NullableObject");
        if (_data.getIsNull()) {
          return null;
        }
        return (krpc.client.services.TestService.TestClass) Encoder.decode(_data.getValue(), krpc.client.Types.createClass("TestService", "TestClass"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "set_NullableObject", types = _Types.class)
    public void setNullableObject(krpc.client.services.TestService.TestClass value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createClass("TestService", "TestClass"))
        };
        this.connection.invoke("TestService", "set_NullableObject", _args);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "get_ObjectProperty", types = _Types.class)
    public krpc.client.services.TestService.TestClass getObjectProperty() throws RPCException {
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "get_ObjectProperty");
        if (_data.getIsNull()) {
          return null;
        }
        return (krpc.client.services.TestService.TestClass) Encoder.decode(_data.getValue(), krpc.client.Types.createClass("TestService", "TestClass"), this.connection);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "set_ObjectProperty", types = _Types.class)
    public void setObjectProperty(krpc.client.services.TestService.TestClass value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createClass("TestService", "TestClass"))
        };
        this.connection.invoke("TestService", "set_ObjectProperty", _args);
    }

    /**
     * Property documentation string.
     */
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "get_StringProperty", types = _Types.class)
    public String getStringProperty() throws RPCException {
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "get_StringProperty");
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    /**
     * Property documentation string.
     */
    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "set_StringProperty", types = _Types.class)
    public void setStringProperty(String value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING))
        };
        this.connection.invoke("TestService", "set_StringProperty", _args);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "set_StringPropertyPrivateGet", types = _Types.class)
    public void setStringPropertyPrivateGet(String value) throws RPCException {
        ByteString[] _args = new ByteString[] {
            Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING))
        };
        this.connection.invoke("TestService", "set_StringPropertyPrivateGet", _args);
    }

    @SuppressWarnings({ "unchecked" })
    @RPCInfo(service = "TestService", procedure = "get_StringPropertyPrivateSet", types = _Types.class)
    public String getStringPropertyPrivateSet() throws RPCException {
        krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "get_StringPropertyPrivateSet");
        return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
    }

    /**
     * Deprecated enum documentation string.
     *
     * @deprecated Use TestEnum instead.
     */
    @Deprecated
    public enum DeprecatedEnum implements RemoteEnum {
        /**
         * Deprecated enum ValueA documentation string.
         */
        VALUE_A(0),

        /**
         * Deprecated enum ValueB documentation string.
         *
         * @deprecated Use DeprecatedEnum.valueA instead.
         */
        @Deprecated
        VALUE_B(1);

        private final int value;

        private DeprecatedEnum (int value) {
            this.value = value;
        }

        @Override
        public int getValue() {
            return value;
        }

        public static DeprecatedEnum fromValue(int value) {
            switch (value) {
            case 0:
                 return VALUE_A;
            case 1:
                 return VALUE_B;
            }
            return null;
        }
    }

    /**
     * Enum documentation string.
     */
    public enum TestEnum implements RemoteEnum {
        /**
         * Enum ValueA documentation string.
         */
        VALUE_A(0),

        /**
         * Enum ValueB documentation string.
         */
        VALUE_B(1),

        /**
         * Enum ValueC documentation string.
         */
        VALUE_C(2);

        private final int value;

        private TestEnum (int value) {
            this.value = value;
        }

        @Override
        public int getValue() {
            return value;
        }

        public static TestEnum fromValue(int value) {
            switch (value) {
            case 0:
                 return VALUE_A;
            case 1:
                 return VALUE_B;
            case 2:
                 return VALUE_C;
            }
            return null;
        }
    }

    /**
     * Deprecated struct documentation string.
     *
     * @deprecated Use TestStruct instead.
     */
    @Deprecated
    public static class DeprecatedStruct implements RemoteStruct, Comparable<DeprecatedStruct> {
        private final int value;
        private final int oldValue;

        public DeprecatedStruct(int value, int oldValue) {
            this.value = value;
            this.oldValue = oldValue;
        }

        /**
         * Deprecated struct Value documentation string.
         */
        public int getValue() {
            return value;
        }

        /**
         * Deprecated struct OldValue documentation string.
         *
         * @deprecated Use DeprecatedStruct.value instead.
         */
        @Deprecated
        public int getOldValue() {
            return oldValue;
        }

        private static final java.util.List<krpc.schema.KRPC.Type> FIELD_TYPES =
            java.util.Collections.unmodifiableList(java.util.Arrays.asList(
                krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),
                krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)
            ));

        /** The types of the fields, in the order they are encoded in. */
        public static java.util.List<krpc.schema.KRPC.Type> fieldTypes() {
            return FIELD_TYPES;
        }

        /** Build a DeprecatedStruct from the values of its fields. */
        @SuppressWarnings("unchecked")
        public static DeprecatedStruct fromFieldValues(Object[] values) {
            return new DeprecatedStruct(
                (int) values[0],
                (int) values[1]
            );
        }

        @Override
        public Object[] fieldValues() {
            return new Object[] {
                value,
                oldValue
            };
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof DeprecatedStruct)) {
                return false;
            }
            DeprecatedStruct other = (DeprecatedStruct) obj;
            return java.util.Objects.deepEquals(this.value, other.value)                && java.util.Objects.deepEquals(this.oldValue, other.oldValue);
        }

        @Override
        public int hashCode() {
            return java.util.Arrays.deepHashCode(new Object[] {value, oldValue});
        }

        /**
         * Compares this DeprecatedStruct with the given one, by its fields in turn, which is
         * how a tuple of the same values compares.
         */
        @Override
        public int compareTo(DeprecatedStruct other) {
            int result;
            result = RemoteStruct.compareFields(value, other.value);
            if (result != 0) {
                return result;
            }
            result = RemoteStruct.compareFields(oldValue, other.oldValue);
            if (result != 0) {
                return result;
            }
            return 0;
        }
    }

    /**
     * Nested nullable struct documentation string.
     */
    public static class TestNestedNullableStruct implements RemoteStruct, Comparable<TestNestedNullableStruct> {
        private final java.util.List<krpc.client.services.TestService.TestClass> listField;
        private final String stringField;

        public TestNestedNullableStruct(java.util.List<krpc.client.services.TestService.TestClass> listField, String stringField) {
            this.listField = listField;
            this.stringField = stringField;
        }

        public java.util.List<krpc.client.services.TestService.TestClass> getListField() {
            return listField;
        }

        public String getStringField() {
            return stringField;
        }

        private static final java.util.List<krpc.schema.KRPC.Type> FIELD_TYPES =
            java.util.Collections.unmodifiableList(java.util.Arrays.asList(
                krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))),
                krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)
            ));

        /** The types of the fields, in the order they are encoded in. */
        public static java.util.List<krpc.schema.KRPC.Type> fieldTypes() {
            return FIELD_TYPES;
        }

        /** Build a TestNestedNullableStruct from the values of its fields. */
        @SuppressWarnings("unchecked")
        public static TestNestedNullableStruct fromFieldValues(Object[] values) {
            return new TestNestedNullableStruct(
                (java.util.List<krpc.client.services.TestService.TestClass>) values[0],
                (String) values[1]
            );
        }

        @Override
        public Object[] fieldValues() {
            return new Object[] {
                listField,
                stringField
            };
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof TestNestedNullableStruct)) {
                return false;
            }
            TestNestedNullableStruct other = (TestNestedNullableStruct) obj;
            return java.util.Objects.deepEquals(this.listField, other.listField)                && java.util.Objects.deepEquals(this.stringField, other.stringField);
        }

        @Override
        public int hashCode() {
            return java.util.Arrays.deepHashCode(new Object[] {listField, stringField});
        }

        /**
         * Compares this TestNestedNullableStruct with the given one, by its fields in turn, which is
         * how a tuple of the same values compares.
         */
        @Override
        public int compareTo(TestNestedNullableStruct other) {
            int result;
            result = RemoteStruct.compareFields(listField, other.listField);
            if (result != 0) {
                return result;
            }
            result = RemoteStruct.compareFields(stringField, other.stringField);
            if (result != 0) {
                return result;
            }
            return 0;
        }
    }

    /**
     * Struct documentation string.
     */
    public static class TestStruct implements RemoteStruct, Comparable<TestStruct> {
        private final int intField;
        private final String stringField;
        private final krpc.client.services.TestService.TestEnum enumField;
        private final java.util.List<Integer> listField;

        public TestStruct(int intField, String stringField, krpc.client.services.TestService.TestEnum enumField, java.util.List<Integer> listField) {
            this.intField = intField;
            this.stringField = stringField;
            this.enumField = enumField;
            this.listField = listField;
        }

        /**
         * Struct IntField documentation string.
         */
        public int getIntField() {
            return intField;
        }

        public String getStringField() {
            return stringField;
        }

        public krpc.client.services.TestService.TestEnum getEnumField() {
            return enumField;
        }

        public java.util.List<Integer> getListField() {
            return listField;
        }

        private static final java.util.List<krpc.schema.KRPC.Type> FIELD_TYPES =
            java.util.Collections.unmodifiableList(java.util.Arrays.asList(
                krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),
                krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING),
                krpc.client.Types.createEnumeration("TestService", "TestEnum"),
                krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))
            ));

        /** The types of the fields, in the order they are encoded in. */
        public static java.util.List<krpc.schema.KRPC.Type> fieldTypes() {
            return FIELD_TYPES;
        }

        /** Build a TestStruct from the values of its fields. */
        @SuppressWarnings("unchecked")
        public static TestStruct fromFieldValues(Object[] values) {
            return new TestStruct(
                (int) values[0],
                (String) values[1],
                (krpc.client.services.TestService.TestEnum) values[2],
                (java.util.List<Integer>) values[3]
            );
        }

        @Override
        public Object[] fieldValues() {
            return new Object[] {
                intField,
                stringField,
                enumField,
                listField
            };
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof TestStruct)) {
                return false;
            }
            TestStruct other = (TestStruct) obj;
            return java.util.Objects.deepEquals(this.intField, other.intField)                && java.util.Objects.deepEquals(this.stringField, other.stringField)                && java.util.Objects.deepEquals(this.enumField, other.enumField)                && java.util.Objects.deepEquals(this.listField, other.listField);
        }

        @Override
        public int hashCode() {
            return java.util.Arrays.deepHashCode(new Object[] {intField, stringField, enumField, listField});
        }

        /**
         * Compares this TestStruct with the given one, by its fields in turn, which is
         * how a tuple of the same values compares.
         */
        @Override
        public int compareTo(TestStruct other) {
            int result;
            result = RemoteStruct.compareFields(intField, other.intField);
            if (result != 0) {
                return result;
            }
            result = RemoteStruct.compareFields(stringField, other.stringField);
            if (result != 0) {
                return result;
            }
            result = RemoteStruct.compareFields(enumField, other.enumField);
            if (result != 0) {
                return result;
            }
            result = RemoteStruct.compareFields(listField, other.listField);
            if (result != 0) {
                return result;
            }
            return 0;
        }
    }

    /**
     * Nested struct documentation string.
     */
    public static class TestNestedStruct implements RemoteStruct, Comparable<TestNestedStruct> {
        private final krpc.client.services.TestService.TestStruct structField;
        private final krpc.client.services.TestService.TestClass objectField;
        private final String stringField;

        public TestNestedStruct(krpc.client.services.TestService.TestStruct structField, krpc.client.services.TestService.TestClass objectField, String stringField) {
            this.structField = structField;
            this.objectField = objectField;
            this.stringField = stringField;
        }

        public krpc.client.services.TestService.TestStruct getStructField() {
            return structField;
        }

        public krpc.client.services.TestService.TestClass getObjectField() {
            return objectField;
        }

        public String getStringField() {
            return stringField;
        }

        private static final java.util.List<krpc.schema.KRPC.Type> FIELD_TYPES =
            java.util.Collections.unmodifiableList(java.util.Arrays.asList(
                krpc.client.Types.createStruct("TestService", "TestStruct"),
                krpc.client.Types.createClass("TestService", "TestClass"),
                krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)
            ));

        /** The types of the fields, in the order they are encoded in. */
        public static java.util.List<krpc.schema.KRPC.Type> fieldTypes() {
            return FIELD_TYPES;
        }

        /** Build a TestNestedStruct from the values of its fields. */
        @SuppressWarnings("unchecked")
        public static TestNestedStruct fromFieldValues(Object[] values) {
            return new TestNestedStruct(
                (krpc.client.services.TestService.TestStruct) values[0],
                (krpc.client.services.TestService.TestClass) values[1],
                (String) values[2]
            );
        }

        @Override
        public Object[] fieldValues() {
            return new Object[] {
                structField,
                objectField,
                stringField
            };
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof TestNestedStruct)) {
                return false;
            }
            TestNestedStruct other = (TestNestedStruct) obj;
            return java.util.Objects.deepEquals(this.structField, other.structField)                && java.util.Objects.deepEquals(this.objectField, other.objectField)                && java.util.Objects.deepEquals(this.stringField, other.stringField);
        }

        @Override
        public int hashCode() {
            return java.util.Arrays.deepHashCode(new Object[] {structField, objectField, stringField});
        }

        /**
         * Compares this TestNestedStruct with the given one, by its fields in turn, which is
         * how a tuple of the same values compares.
         */
        @Override
        public int compareTo(TestNestedStruct other) {
            int result;
            result = RemoteStruct.compareFields(structField, other.structField);
            if (result != 0) {
                return result;
            }
            result = RemoteStruct.compareFields(objectField, other.objectField);
            if (result != 0) {
                return result;
            }
            result = RemoteStruct.compareFields(stringField, other.stringField);
            if (result != 0) {
                return result;
            }
            return 0;
        }
    }

    /**
     * Nullable struct documentation string.
     */
    public static class TestNullableStruct implements RemoteStruct, Comparable<TestNullableStruct> {
        private final int intField;
        private final Integer nullableIntField;
        private final krpc.client.services.TestService.TestEnum nullableEnumField;
        private final String nullableStringField;
        private final krpc.client.services.TestService.TestClass nullableObjectField;

        public TestNullableStruct(int intField, Integer nullableIntField, krpc.client.services.TestService.TestEnum nullableEnumField, String nullableStringField, krpc.client.services.TestService.TestClass nullableObjectField) {
            this.intField = intField;
            this.nullableIntField = nullableIntField;
            this.nullableEnumField = nullableEnumField;
            this.nullableStringField = nullableStringField;
            this.nullableObjectField = nullableObjectField;
        }

        public int getIntField() {
            return intField;
        }

        public Integer getNullableIntField() {
            return nullableIntField;
        }

        public krpc.client.services.TestService.TestEnum getNullableEnumField() {
            return nullableEnumField;
        }

        public String getNullableStringField() {
            return nullableStringField;
        }

        public krpc.client.services.TestService.TestClass getNullableObjectField() {
            return nullableObjectField;
        }

        private static final java.util.List<krpc.schema.KRPC.Type> FIELD_TYPES =
            java.util.Collections.unmodifiableList(java.util.Arrays.asList(
                krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),
                krpc.client.Types.nullable(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)),
                krpc.client.Types.nullable(krpc.client.Types.createEnumeration("TestService", "TestEnum")),
                krpc.client.Types.nullable(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)),
                krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))
            ));

        /** The types of the fields, in the order they are encoded in. */
        public static java.util.List<krpc.schema.KRPC.Type> fieldTypes() {
            return FIELD_TYPES;
        }

        /** Build a TestNullableStruct from the values of its fields. */
        @SuppressWarnings("unchecked")
        public static TestNullableStruct fromFieldValues(Object[] values) {
            return new TestNullableStruct(
                (int) values[0],
                (Integer) values[1],
                (krpc.client.services.TestService.TestEnum) values[2],
                (String) values[3],
                (krpc.client.services.TestService.TestClass) values[4]
            );
        }

        @Override
        public Object[] fieldValues() {
            return new Object[] {
                intField,
                nullableIntField,
                nullableEnumField,
                nullableStringField,
                nullableObjectField
            };
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof TestNullableStruct)) {
                return false;
            }
            TestNullableStruct other = (TestNullableStruct) obj;
            return java.util.Objects.deepEquals(this.intField, other.intField)                && java.util.Objects.deepEquals(this.nullableIntField, other.nullableIntField)                && java.util.Objects.deepEquals(this.nullableEnumField, other.nullableEnumField)                && java.util.Objects.deepEquals(this.nullableStringField, other.nullableStringField)                && java.util.Objects.deepEquals(this.nullableObjectField, other.nullableObjectField);
        }

        @Override
        public int hashCode() {
            return java.util.Arrays.deepHashCode(new Object[] {intField, nullableIntField, nullableEnumField, nullableStringField, nullableObjectField});
        }

        /**
         * Compares this TestNullableStruct with the given one, by its fields in turn, which is
         * how a tuple of the same values compares.
         */
        @Override
        public int compareTo(TestNullableStruct other) {
            int result;
            result = RemoteStruct.compareFields(intField, other.intField);
            if (result != 0) {
                return result;
            }
            result = RemoteStruct.compareFields(nullableIntField, other.nullableIntField);
            if (result != 0) {
                return result;
            }
            result = RemoteStruct.compareFields(nullableEnumField, other.nullableEnumField);
            if (result != 0) {
                return result;
            }
            result = RemoteStruct.compareFields(nullableStringField, other.nullableStringField);
            if (result != 0) {
                return result;
            }
            result = RemoteStruct.compareFields(nullableObjectField, other.nullableObjectField);
            if (result != 0) {
                return result;
            }
            return 0;
        }
    }

    /**
     * Deprecated class documentation string.
     *
     * @deprecated Use TestClass instead.
     */
    @Deprecated
    public static class DeprecatedClass extends RemoteObject {

        private static final long serialVersionUID = 17653684528050254L;

        public DeprecatedClass(Connection connection, long id) {
            super(connection, id);
        }

        /**
         * Deprecated method documentation string.
         *
         * @deprecated Use TestClass.getValue instead.
         */
        @Deprecated
        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "DeprecatedClass_DeprecatedMethod", types = _Types.class)
        public String deprecatedMethod() throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(this, krpc.client.Types.createClass("TestService", "DeprecatedClass"))
            };
            krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "DeprecatedClass_DeprecatedMethod", _args);
            return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
        }
    }

    /**
     * Class documentation string.
     */
    public static class TestClass extends RemoteObject {

        private static final long serialVersionUID = 636122307493780328L;

        public TestClass(Connection connection, long id) {
            super(connection, id);
        }

        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_EchoNullableObject", types = _Types.class)
        public krpc.client.services.TestService.TestClass echoNullableObject(krpc.client.services.TestService.TestClass value) throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(this, krpc.client.Types.createClass("TestService", "TestClass")),
                Encoder.encode(value, krpc.client.Types.createClass("TestService", "TestClass"))
            };
            krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "TestClass_EchoNullableObject", _args);
            if (_data.getIsNull()) {
              return null;
            }
            return (krpc.client.services.TestService.TestClass) Encoder.decode(_data.getValue(), krpc.client.Types.createClass("TestService", "TestClass"), this.connection);
        }

        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_FloatToString", types = _Types.class)
        public String floatToString(float x) throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(this, krpc.client.Types.createClass("TestService", "TestClass")),
                Encoder.encode(x, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT))
            };
            krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "TestClass_FloatToString", _args);
            return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
        }

        /**
         * Method documentation string.
         */
        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_GetValue", types = _Types.class)
        public String getValue() throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(this, krpc.client.Types.createClass("TestService", "TestClass"))
            };
            krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "TestClass_GetValue", _args);
            return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
        }

        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_ObjectToString", types = _Types.class)
        public String objectToString(krpc.client.services.TestService.TestClass other) throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(this, krpc.client.Types.createClass("TestService", "TestClass")),
                Encoder.encode(other, krpc.client.Types.createClass("TestService", "TestClass"))
            };
            krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "TestClass_ObjectToString", _args);
            return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
        }

        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_OptionalArguments", types = _Types.class)
        public String optionalArguments(String x, String y, String z, krpc.client.services.TestService.TestClass obj) throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(this, krpc.client.Types.createClass("TestService", "TestClass")),
                Encoder.encode(x, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)),
                Encoder.encode(y, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)),
                Encoder.encode(z, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)),
                Encoder.encode(obj, krpc.client.Types.createClass("TestService", "TestClass"))
            };
            krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "TestClass_OptionalArguments", _args);
            return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
        }

        /**
         * Property documentation string.
         */
        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_get_IntProperty", types = _Types.class)
        public int getIntProperty() throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(this, krpc.client.Types.createClass("TestService", "TestClass"))
            };
            krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "TestClass_get_IntProperty", _args);
            return (int) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), this.connection);
        }

        /**
         * Property documentation string.
         */
        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_set_IntProperty", types = _Types.class)
        public void setIntProperty(int value) throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(this, krpc.client.Types.createClass("TestService", "TestClass")),
                Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))
            };
            this.connection.invoke("TestService", "TestClass_set_IntProperty", _args);
        }

        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_get_ObjectProperty", types = _Types.class)
        public krpc.client.services.TestService.TestClass getObjectProperty() throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(this, krpc.client.Types.createClass("TestService", "TestClass"))
            };
            krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "TestClass_get_ObjectProperty", _args);
            if (_data.getIsNull()) {
              return null;
            }
            return (krpc.client.services.TestService.TestClass) Encoder.decode(_data.getValue(), krpc.client.Types.createClass("TestService", "TestClass"), this.connection);
        }

        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_set_ObjectProperty", types = _Types.class)
        public void setObjectProperty(krpc.client.services.TestService.TestClass value) throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(this, krpc.client.Types.createClass("TestService", "TestClass")),
                Encoder.encode(value, krpc.client.Types.createClass("TestService", "TestClass"))
            };
            this.connection.invoke("TestService", "TestClass_set_ObjectProperty", _args);
        }

        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_set_StringPropertyPrivateGet", types = _Types.class)
        public void setStringPropertyPrivateGet(String value) throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(this, krpc.client.Types.createClass("TestService", "TestClass")),
                Encoder.encode(value, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING))
            };
            this.connection.invoke("TestService", "TestClass_set_StringPropertyPrivateGet", _args);
        }

        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_get_StringPropertyPrivateSet", types = _Types.class)
        public String getStringPropertyPrivateSet() throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(this, krpc.client.Types.createClass("TestService", "TestClass"))
            };
            krpc.schema.KRPC.ProcedureResult _data = this.connection.invoke("TestService", "TestClass_get_StringPropertyPrivateSet", _args);
            return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), this.connection);
        }

        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_static_StaticMethod", types = _Types.class)
        public static String staticMethod(Connection connection, String a, String b) throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(a, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)),
                Encoder.encode(b, krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING))
            };
            krpc.schema.KRPC.ProcedureResult _data = connection.invoke("TestService", "TestClass_static_StaticMethod", _args);
            return (String) Encoder.decode(_data.getValue(), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), connection);
        }

        @SuppressWarnings({ "unchecked" })
        @RPCInfo(service = "TestService", procedure = "TestClass_static_StaticNullableObject", types = _Types.class)
        public static krpc.client.services.TestService.TestClass staticNullableObject(Connection connection, krpc.client.services.TestService.TestClass value) throws RPCException
        {
            ByteString[] _args = new ByteString[] {
                Encoder.encode(value, krpc.client.Types.createClass("TestService", "TestClass"))
            };
            krpc.schema.KRPC.ProcedureResult _data = connection.invoke("TestService", "TestClass_static_StaticNullableObject", _args);
            if (_data.getIsNull()) {
              return null;
            }
            return (krpc.client.services.TestService.TestClass) Encoder.decode(_data.getValue(), krpc.client.Types.createClass("TestService", "TestClass"), connection);
        }
    }

    public static class _Types {
        // Procedure return and parameter types are held in lookup maps that are
        // populated by chunked initializer methods. Emitting them this way keeps
        // every generated method under the JVM's 64KB bytecode limit as a service
        // accumulates procedures.
        private static final java.util.Map<String, krpc.schema.KRPC.Type> RETURN_TYPES =
            new java.util.HashMap<String, krpc.schema.KRPC.Type>();
        private static final java.util.Map<String, krpc.schema.KRPC.Type[]> PARAMETER_TYPES =
            new java.util.HashMap<String, krpc.schema.KRPC.Type[]>();

        static {
            initTypes0();
            initTypes1();
        }

        private static void initTypes0() {
            RETURN_TYPES.put("AddMultipleValues", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("AddMultipleValues", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64) });
            RETURN_TYPES.put("AddToObjectList", krpc.client.Types.createList(krpc.client.Types.createClass("TestService", "TestClass")));
            PARAMETER_TYPES.put("AddToObjectList", new krpc.schema.KRPC.Type[] { krpc.client.Types.createList(krpc.client.Types.createClass("TestService", "TestClass")), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING) });
            RETURN_TYPES.put("BlockingProcedure", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32));
            PARAMETER_TYPES.put("BlockingProcedure", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32) });
            RETURN_TYPES.put("BoolToString", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("BoolToString", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.BOOL) });
            RETURN_TYPES.put("BytesToHexString", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("BytesToHexString", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.BYTES) });
            RETURN_TYPES.put("Counter", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32));
            PARAMETER_TYPES.put("Counter", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32) });
            RETURN_TYPES.put("CounterStruct", krpc.client.Types.createStruct("TestService", "TestStruct"));
            PARAMETER_TYPES.put("CounterStruct", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING) });
            RETURN_TYPES.put("CreateTestObject", krpc.client.Types.createClass("TestService", "TestClass"));
            PARAMETER_TYPES.put("CreateTestObject", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING) });
            RETURN_TYPES.put("DeprecatedProcedure", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("DeprecatedProcedure", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT) });
            RETURN_TYPES.put("DeprecatedProcedureNoMessage", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("DeprecatedProcedureNoMessage", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT) });
            RETURN_TYPES.put("DictionaryDefault", krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.BOOL)));
            PARAMETER_TYPES.put("DictionaryDefault", new krpc.schema.KRPC.Type[] { krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.BOOL)) });
            RETURN_TYPES.put("DoubleSpecialDefaults", krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE)));
            PARAMETER_TYPES.put("DoubleSpecialDefaults", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE) });
            RETURN_TYPES.put("DoubleToString", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("DoubleToString", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.DOUBLE) });
            RETURN_TYPES.put("DumpExpressionTree", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("DumpExpressionTree", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("KRPC", "Expression") });
            RETURN_TYPES.put("EchoDictionaryOfNullableObjects", krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))));
            PARAMETER_TYPES.put("EchoDictionaryOfNullableObjects", new krpc.schema.KRPC.Type[] { krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))) });
            RETURN_TYPES.put("EchoListOfNullableInts", krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))));
            PARAMETER_TYPES.put("EchoListOfNullableInts", new krpc.schema.KRPC.Type[] { krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))) });
            RETURN_TYPES.put("EchoListOfNullableObjects", krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))));
            PARAMETER_TYPES.put("EchoListOfNullableObjects", new krpc.schema.KRPC.Type[] { krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))) });
            RETURN_TYPES.put("EchoNestedListOfNullableObjects", krpc.client.Types.createList(krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass")))));
            PARAMETER_TYPES.put("EchoNestedListOfNullableObjects", new krpc.schema.KRPC.Type[] { krpc.client.Types.createList(krpc.client.Types.createList(krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass")))) });
            RETURN_TYPES.put("EchoNestedNullableStruct", krpc.client.Types.createStruct("TestService", "TestNestedNullableStruct"));
            PARAMETER_TYPES.put("EchoNestedNullableStruct", new krpc.schema.KRPC.Type[] { krpc.client.Types.createStruct("TestService", "TestNestedNullableStruct") });
            RETURN_TYPES.put("EchoNullableInt", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32));
            PARAMETER_TYPES.put("EchoNullableInt", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32) });
            RETURN_TYPES.put("EchoNullableList", krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)));
            PARAMETER_TYPES.put("EchoNullableList", new krpc.schema.KRPC.Type[] { krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)) });
            RETURN_TYPES.put("EchoNullableString", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("EchoNullableString", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING) });
            RETURN_TYPES.put("EchoTestObject", krpc.client.Types.createClass("TestService", "TestClass"));
            PARAMETER_TYPES.put("EchoTestObject", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("EchoTupleWithANullableObject", krpc.client.Types.createTuple(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))));
            PARAMETER_TYPES.put("EchoTupleWithANullableObject", new krpc.schema.KRPC.Type[] { krpc.client.Types.createTuple(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),krpc.client.Types.nullable(krpc.client.Types.createClass("TestService", "TestClass"))) });
            RETURN_TYPES.put("EmptyListDefault", krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)));
            PARAMETER_TYPES.put("EmptyListDefault", new krpc.schema.KRPC.Type[] { krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING)) });
            RETURN_TYPES.put("EnumDefaultArg", krpc.client.Types.createEnumeration("TestService", "TestEnum"));
            PARAMETER_TYPES.put("EnumDefaultArg", new krpc.schema.KRPC.Type[] { krpc.client.Types.createEnumeration("TestService", "TestEnum") });
            RETURN_TYPES.put("EnumEcho", krpc.client.Types.createEnumeration("TestService", "TestEnum"));
            PARAMETER_TYPES.put("EnumEcho", new krpc.schema.KRPC.Type[] { krpc.client.Types.createEnumeration("TestService", "TestEnum") });
            RETURN_TYPES.put("EnumListDefault", krpc.client.Types.createList(krpc.client.Types.createEnumeration("TestService", "TestEnum")));
            PARAMETER_TYPES.put("EnumListDefault", new krpc.schema.KRPC.Type[] { krpc.client.Types.createList(krpc.client.Types.createEnumeration("TestService", "TestEnum")) });
            RETURN_TYPES.put("EnumReturn", krpc.client.Types.createEnumeration("TestService", "TestEnum"));
            PARAMETER_TYPES.put("EnumReturn", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("FloatSpecialDefaults", krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT)));
            PARAMETER_TYPES.put("FloatSpecialDefaults", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT) });
            RETURN_TYPES.put("FloatToString", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("FloatToString", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT) });
            RETURN_TYPES.put("IncrementDictionary", krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)));
            PARAMETER_TYPES.put("IncrementDictionary", new krpc.schema.KRPC.Type[] { krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)) });
            RETURN_TYPES.put("IncrementList", krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)));
            PARAMETER_TYPES.put("IncrementList", new krpc.schema.KRPC.Type[] { krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)) });
            RETURN_TYPES.put("IncrementListOfStructs", krpc.client.Types.createList(krpc.client.Types.createStruct("TestService", "TestStruct")));
            PARAMETER_TYPES.put("IncrementListOfStructs", new krpc.schema.KRPC.Type[] { krpc.client.Types.createList(krpc.client.Types.createStruct("TestService", "TestStruct")) });
            RETURN_TYPES.put("IncrementNestedCollection", krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))));
            PARAMETER_TYPES.put("IncrementNestedCollection", new krpc.schema.KRPC.Type[] { krpc.client.Types.createDictionary(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32))) });
            RETURN_TYPES.put("IncrementSet", krpc.client.Types.createSet(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)));
            PARAMETER_TYPES.put("IncrementSet", new krpc.schema.KRPC.Type[] { krpc.client.Types.createSet(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)) });
            RETURN_TYPES.put("IncrementTuple", krpc.client.Types.createTuple(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64)));
            PARAMETER_TYPES.put("IncrementTuple", new krpc.schema.KRPC.Type[] { krpc.client.Types.createTuple(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64)) });
            RETURN_TYPES.put("Int32SpecialDefaults", krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)));
            PARAMETER_TYPES.put("Int32SpecialDefaults", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32) });
            RETURN_TYPES.put("Int32ToString", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("Int32ToString", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32) });
            RETURN_TYPES.put("Int64SpecialDefaults", krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64)));
            PARAMETER_TYPES.put("Int64SpecialDefaults", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64) });
            RETURN_TYPES.put("Int64ToString", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("Int64ToString", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT64) });
            RETURN_TYPES.put("ListDefault", krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)));
            PARAMETER_TYPES.put("ListDefault", new krpc.schema.KRPC.Type[] { krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)) });
            RETURN_TYPES.put("NestedStructEcho", krpc.client.Types.createStruct("TestService", "TestNestedStruct"));
            PARAMETER_TYPES.put("NestedStructEcho", new krpc.schema.KRPC.Type[] { krpc.client.Types.createStruct("TestService", "TestNestedStruct") });
            RETURN_TYPES.put("NotNullableObject", krpc.client.Types.createClass("TestService", "TestClass"));
            PARAMETER_TYPES.put("NotNullableObject", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("NullableStructEcho", krpc.client.Types.createStruct("TestService", "TestNullableStruct"));
            PARAMETER_TYPES.put("NullableStructEcho", new krpc.schema.KRPC.Type[] { krpc.client.Types.createStruct("TestService", "TestNullableStruct") });
            RETURN_TYPES.put("OnTimer", krpc.client.Types.createMessage(krpc.schema.KRPC.Type.TypeCode.EVENT));
            PARAMETER_TYPES.put("OnTimer", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT32), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT32) });
            RETURN_TYPES.put("OnTimerUsingLambda", krpc.client.Types.createMessage(krpc.schema.KRPC.Type.TypeCode.EVENT));
            PARAMETER_TYPES.put("OnTimerUsingLambda", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT32) });
            RETURN_TYPES.put("OptionalArguments", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("OptionalArguments", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("RemoveEventAfter", krpc.client.Types.createMessage(krpc.schema.KRPC.Type.TypeCode.EVENT));
            PARAMETER_TYPES.put("RemoveEventAfter", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT32) });
            RETURN_TYPES.put("ResetCustomExceptionLater", null);
            PARAMETER_TYPES.put("ResetCustomExceptionLater", new krpc.schema.KRPC.Type[] {  });
        }

        private static void initTypes1() {
            RETURN_TYPES.put("ResetInvalidOperationExceptionLater", null);
            PARAMETER_TYPES.put("ResetInvalidOperationExceptionLater", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("ReturnNullWhenNotAllowed", krpc.client.Types.createClass("TestService", "TestClass"));
            PARAMETER_TYPES.put("ReturnNullWhenNotAllowed", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("SetDefault", krpc.client.Types.createSet(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)));
            PARAMETER_TYPES.put("SetDefault", new krpc.schema.KRPC.Type[] { krpc.client.Types.createSet(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32)) });
            RETURN_TYPES.put("StringToInt32", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32));
            PARAMETER_TYPES.put("StringToInt32", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING) });
            RETURN_TYPES.put("StructDefault", krpc.client.Types.createStruct("TestService", "TestStruct"));
            PARAMETER_TYPES.put("StructDefault", new krpc.schema.KRPC.Type[] { krpc.client.Types.createStruct("TestService", "TestStruct") });
            RETURN_TYPES.put("StructEcho", krpc.client.Types.createStruct("TestService", "TestStruct"));
            PARAMETER_TYPES.put("StructEcho", new krpc.schema.KRPC.Type[] { krpc.client.Types.createStruct("TestService", "TestStruct") });
            RETURN_TYPES.put("StructEchoNullable", krpc.client.Types.createStruct("TestService", "TestStruct"));
            PARAMETER_TYPES.put("StructEchoNullable", new krpc.schema.KRPC.Type[] { krpc.client.Types.createStruct("TestService", "TestStruct") });
            RETURN_TYPES.put("ThrowArgumentException", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32));
            PARAMETER_TYPES.put("ThrowArgumentException", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("ThrowArgumentNullException", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32));
            PARAMETER_TYPES.put("ThrowArgumentNullException", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING) });
            RETURN_TYPES.put("ThrowArgumentOutOfRangeException", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32));
            PARAMETER_TYPES.put("ThrowArgumentOutOfRangeException", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32) });
            RETURN_TYPES.put("ThrowCustomException", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32));
            PARAMETER_TYPES.put("ThrowCustomException", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("ThrowCustomExceptionLater", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32));
            PARAMETER_TYPES.put("ThrowCustomExceptionLater", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("ThrowInvalidOperationException", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32));
            PARAMETER_TYPES.put("ThrowInvalidOperationException", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("ThrowInvalidOperationExceptionLater", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32));
            PARAMETER_TYPES.put("ThrowInvalidOperationExceptionLater", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("TupleDefault", krpc.client.Types.createTuple(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.BOOL)));
            PARAMETER_TYPES.put("TupleDefault", new krpc.schema.KRPC.Type[] { krpc.client.Types.createTuple(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32),krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.BOOL)) });
            RETURN_TYPES.put("Uint32SpecialDefaults", krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT32)));
            PARAMETER_TYPES.put("Uint32SpecialDefaults", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT32) });
            RETURN_TYPES.put("Uint64SpecialDefaults", krpc.client.Types.createList(krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT64)));
            PARAMETER_TYPES.put("Uint64SpecialDefaults", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.UINT64) });
            RETURN_TYPES.put("get_DeprecatedProperty", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("get_DeprecatedProperty", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("set_DeprecatedProperty", null);
            PARAMETER_TYPES.put("set_DeprecatedProperty", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING) });
            RETURN_TYPES.put("get_NullableObject", krpc.client.Types.createClass("TestService", "TestClass"));
            PARAMETER_TYPES.put("get_NullableObject", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("set_NullableObject", null);
            PARAMETER_TYPES.put("set_NullableObject", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("get_ObjectProperty", krpc.client.Types.createClass("TestService", "TestClass"));
            PARAMETER_TYPES.put("get_ObjectProperty", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("set_ObjectProperty", null);
            PARAMETER_TYPES.put("set_ObjectProperty", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("get_StringProperty", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("get_StringProperty", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("set_StringProperty", null);
            PARAMETER_TYPES.put("set_StringProperty", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING) });
            RETURN_TYPES.put("set_StringPropertyPrivateGet", null);
            PARAMETER_TYPES.put("set_StringPropertyPrivateGet", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING) });
            RETURN_TYPES.put("get_StringPropertyPrivateSet", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("get_StringPropertyPrivateSet", new krpc.schema.KRPC.Type[] {  });
            RETURN_TYPES.put("DeprecatedClass_DeprecatedMethod", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("DeprecatedClass_DeprecatedMethod", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "DeprecatedClass") });
            RETURN_TYPES.put("TestClass_EchoNullableObject", krpc.client.Types.createClass("TestService", "TestClass"));
            PARAMETER_TYPES.put("TestClass_EchoNullableObject", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass"), krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("TestClass_FloatToString", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("TestClass_FloatToString", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass"), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.FLOAT) });
            RETURN_TYPES.put("TestClass_GetValue", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("TestClass_GetValue", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("TestClass_ObjectToString", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("TestClass_ObjectToString", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass"), krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("TestClass_OptionalArguments", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("TestClass_OptionalArguments", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass"), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("TestClass_get_IntProperty", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32));
            PARAMETER_TYPES.put("TestClass_get_IntProperty", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("TestClass_set_IntProperty", null);
            PARAMETER_TYPES.put("TestClass_set_IntProperty", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass"), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.SINT32) });
            RETURN_TYPES.put("TestClass_get_ObjectProperty", krpc.client.Types.createClass("TestService", "TestClass"));
            PARAMETER_TYPES.put("TestClass_get_ObjectProperty", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("TestClass_set_ObjectProperty", null);
            PARAMETER_TYPES.put("TestClass_set_ObjectProperty", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass"), krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("TestClass_set_StringPropertyPrivateGet", null);
            PARAMETER_TYPES.put("TestClass_set_StringPropertyPrivateGet", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass"), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING) });
            RETURN_TYPES.put("TestClass_get_StringPropertyPrivateSet", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("TestClass_get_StringPropertyPrivateSet", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass") });
            RETURN_TYPES.put("TestClass_static_StaticMethod", krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING));
            PARAMETER_TYPES.put("TestClass_static_StaticMethod", new krpc.schema.KRPC.Type[] { krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING), krpc.client.Types.createValue(krpc.schema.KRPC.Type.TypeCode.STRING) });
            RETURN_TYPES.put("TestClass_static_StaticNullableObject", krpc.client.Types.createClass("TestService", "TestClass"));
            PARAMETER_TYPES.put("TestClass_static_StaticNullableObject", new krpc.schema.KRPC.Type[] { krpc.client.Types.createClass("TestService", "TestClass") });
        }

        public static krpc.schema.KRPC.Type getReturnType(String procedure) {
            if (!RETURN_TYPES.containsKey(procedure))
                throw new IllegalArgumentException("Procedure '" + procedure +"' not found");
            return RETURN_TYPES.get(procedure);
        }

        public static krpc.schema.KRPC.Type[] getParameterTypes(String procedure) {
            krpc.schema.KRPC.Type[] parameterTypes = PARAMETER_TYPES.get(procedure);
            if (parameterTypes == null)
                throw new IllegalArgumentException("Procedure '" + procedure +"' not found");
            return parameterTypes;
        }
    }
}
