bool
TraCIServerAPI_VehicleType::setVariable(const int cmd, const int variable, const int valueDataType,
                                        MSVehicleType& v, traci::TraCIServer& server,
                                        tcpip::Storage& inputStorage, tcpip::Storage& outputStorage) {
    switch (variable) {
        case VAR_LENGTH: {
            if (valueDataType != TYPE_DOUBLE) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting length requires a double.", outputStorage);
                return false;
            }
            double val = inputStorage.readDouble();
            if (val == 0.0 || fabs(val) == std::numeric_limits<double>::infinity()) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Invalid length.", outputStorage);
                return false;
            }
            v.setLength(val);
        }
        break;
        case VAR_MAXSPEED: {
            if (valueDataType != TYPE_DOUBLE) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting maximum speed requires a double.", outputStorage);
                return false;
            }
            double val = inputStorage.readDouble();
            if (val == 0.0 || fabs(val) == std::numeric_limits<double>::infinity()) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Invalid maximum speed.", outputStorage);
                return false;
            }
            v.setMaxSpeed(val);
        }
        break;
        case VAR_VEHICLECLASS: {
            if (valueDataType != TYPE_STRING) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting vehicle class requires a string.", outputStorage);
                return false;
            }
            v.setVClass(getVehicleClassID(inputStorage.readString()));
        }
        break;
        case VAR_SPEED_FACTOR: {
            if (valueDataType != TYPE_DOUBLE) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting speed factor requires a double.", outputStorage);
                return false;
            }
            v.setSpeedFactor(inputStorage.readDouble());
        }
        break;
        case VAR_SPEED_DEVIATION: {
            if (valueDataType != TYPE_DOUBLE) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting speed deviation requires a double.", outputStorage);
                return false;
            }
            v.setSpeedDeviation(inputStorage.readDouble());
        }
        break;
        case VAR_EMISSIONCLASS: {
            if (valueDataType != TYPE_STRING) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting emission class requires a string.", outputStorage);
                return false;
            }
            v.setEmissionClass(getVehicleEmissionTypeID(inputStorage.readString()));
        }
        break;
        case VAR_WIDTH: {
            if (valueDataType != TYPE_DOUBLE) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting width requires a double.", outputStorage);
                return false;
            }
            v.setWidth(inputStorage.readDouble());
        }
        break;
        case VAR_MINGAP: {
            if (valueDataType != TYPE_DOUBLE) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting minimum gap requires a double.", outputStorage);
                return false;
            }
            v.setMinGap(inputStorage.readDouble());
        }
        break;
        case VAR_SHAPECLASS: {
            if (valueDataType != TYPE_STRING) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting vehicle shape requires a string.", outputStorage);
                return false;
            }
            v.setShape(getVehicleShapeID(inputStorage.readString()));
        }
        break;
        case VAR_ACCEL: {
            if (valueDataType != TYPE_DOUBLE) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting acceleration requires a double.", outputStorage);
                return false;
            }
            v.getCarFollowModel().setMaxAccel(inputStorage.readDouble());
        }
        break;
        case VAR_DECEL: {
            if (valueDataType != TYPE_DOUBLE) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting deceleration requires a double.", outputStorage);
                return false;
            }
            v.getCarFollowModel().setMaxDecel(inputStorage.readDouble());
        }
        break;
        case VAR_IMPERFECTION: {
            if (valueDataType != TYPE_DOUBLE) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting driver imperfection requires a double.", outputStorage);
                return false;
            }
            v.getCarFollowModel().setImperfection(inputStorage.readDouble());
        }
        break;
        case VAR_TAU: {
            if (valueDataType != TYPE_DOUBLE) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "Setting headway time requires a double.", outputStorage);
                return false;
            }
            v.getCarFollowModel().setHeadwayTime(inputStorage.readDouble());
        }
        break;
        case VAR_COLOR: {
            if (valueDataType != TYPE_COLOR) {
                server.writeStatusCmd(cmd, RTYPE_ERR, "The color must be given using the according type.", outputStorage);
                return false;
            }
            SUMOReal r = (SUMOReal) inputStorage.readUnsignedByte() / 255.;
            SUMOReal g = (SUMOReal) inputStorage.readUnsignedByte() / 255.;
            SUMOReal b = (SUMOReal) inputStorage.readUnsignedByte() / 255.;
            inputStorage.readUnsignedByte(); // skip alpha level
            RGBColor col(r, g, b);
            v.setColor(col);
        }
        break;
        default:
            break;
    }
    return true;
}
bool
TraCIServerAPI_VehicleType::setVariable(const int cmd, const int variable,
                                        MSVehicleType& v, traci::TraCIServer& server,
                                        tcpip::Storage& inputStorage, tcpip::Storage& outputStorage) {
    switch (variable) {
        case VAR_LENGTH: {
            double value = 0;
            if (!server.readTypeCheckingDouble(inputStorage, value)) {
                return server.writeErrorStatusCmd(cmd, "Setting length requires a double.", outputStorage);
            }
            if (value == 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
                return server.writeErrorStatusCmd(cmd, "Invalid length.", outputStorage);
            }
            v.setLength(value);
        }
        break;
        case VAR_MAXSPEED: {
            double value = 0;
            if (!server.readTypeCheckingDouble(inputStorage, value)) {
                return server.writeErrorStatusCmd(cmd, "Setting maximum speed requires a double.", outputStorage);
            }
            if (value == 0.0 || fabs(value) == std::numeric_limits<double>::infinity()) {
                return server.writeErrorStatusCmd(cmd, "Invalid maximum speed.", outputStorage);
            }
            v.setMaxSpeed(value);
        }
        break;
        case VAR_VEHICLECLASS: {
            std::string vclass;
            if (!server.readTypeCheckingString(inputStorage, vclass)) {
                return server.writeErrorStatusCmd(cmd, "Setting vehicle class requires a string.", outputStorage);
            }
            v.setVClass(getVehicleClassID(vclass));
        }
        break;
        case VAR_SPEED_FACTOR: {
            double value = 0;
            if (!server.readTypeCheckingDouble(inputStorage, value)) {
                return server.writeErrorStatusCmd(cmd, "Setting speed factor requires a double.", outputStorage);
            }
            v.setSpeedFactor(value);
        }
        break;
        case VAR_SPEED_DEVIATION: {
            double value = 0;
            if (!server.readTypeCheckingDouble(inputStorage, value)) {
                return server.writeErrorStatusCmd(cmd, "Setting speed deviation requires a double.", outputStorage);
            }
            v.setSpeedDeviation(value);
        }
        break;
        case VAR_EMISSIONCLASS: {
            std::string eclass;
            if (!server.readTypeCheckingString(inputStorage, eclass)) {
                return server.writeErrorStatusCmd(cmd, "Setting emission class requires a string.", outputStorage);
            }
            v.setEmissionClass(getVehicleEmissionTypeID(eclass));
        }
        break;
        case VAR_WIDTH: {
            double value = 0;
            if (!server.readTypeCheckingDouble(inputStorage,  value)) {
                return server.writeErrorStatusCmd(cmd, "Setting width requires a double.", outputStorage);
            }
            v.setWidth(value);
        }
        break;
        case VAR_MINGAP: {
            double value = 0;
            if (!server.readTypeCheckingDouble(inputStorage, value)) {
                return server.writeErrorStatusCmd(cmd, "Setting minimum gap requires a double.", outputStorage);
            }
            v.setMinGap(value);
        }
        break;
        case VAR_SHAPECLASS: {
            std::string sclass;
            if (!server.readTypeCheckingString(inputStorage, sclass)) {
                return server.writeErrorStatusCmd(cmd, "Setting vehicle shape requires a string.", outputStorage);
            }
            v.setShape(getVehicleShapeID(sclass));
        }
        break;
        case VAR_ACCEL: {
            double value = 0;
            if (!server.readTypeCheckingDouble(inputStorage, value)) {
                return server.writeErrorStatusCmd(cmd, "Setting acceleration requires a double.", outputStorage);
            }
            v.getCarFollowModel().setMaxAccel(value);
        }
        break;
        case VAR_DECEL: {
            double value = 0;
            if (!server.readTypeCheckingDouble(inputStorage, value)) {
                return server.writeErrorStatusCmd(cmd, "Setting deceleration requires a double.", outputStorage);
            }
            v.getCarFollowModel().setMaxDecel(value);
        }
        break;
        case VAR_IMPERFECTION: {
            double value = 0;
            if (!server.readTypeCheckingDouble(inputStorage, value)) {
                return server.writeErrorStatusCmd(cmd, "Setting driver imperfection requires a double.", outputStorage);
            }
            v.getCarFollowModel().setImperfection(value);
        }
        break;
        case VAR_TAU: {
            double value = 0;
            if (!server.readTypeCheckingDouble(inputStorage, value)) {
                return server.writeErrorStatusCmd(cmd, "Setting headway time requires a double.", outputStorage);
            }
            v.getCarFollowModel().setHeadwayTime(value);
        }
        break;
        case VAR_COLOR: {
            RGBColor col;
            if (!server.readTypeCheckingColor(inputStorage, col)) {
                return server.writeErrorStatusCmd(cmd, "The color must be given using the according type.", outputStorage);
            }
            v.setColor(col);
        }
        break;
        default:
            break;
    }
    return true;
}