AbstractExpression*
AbstractExpression::buildExpressionTree_recurse(json_spirit::Object &obj)
{
    // build a tree recursively from the bottom upwards.
    // when the expression node is instantiated, its type,
    // value and child types will have been discovered.

    ExpressionType peek_type = EXPRESSION_TYPE_INVALID;
    ValueType value_type = VALUE_TYPE_INVALID;
    AbstractExpression *left_child = NULL;
    AbstractExpression *right_child = NULL;
    std::vector<AbstractExpression*>* argsVector = NULL;

    // read the expression type
    json_spirit::Value expressionTypeValue = json_spirit::find_value(obj,
                                                                     "TYPE");
    if (expressionTypeValue == json_spirit::Value::null) {
        throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION,
                                      "AbstractExpression::"
                                      "buildExpressionTree_recurse:"
                                      " Couldn't find TYPE value");
    }
    assert(stringToExpression(expressionTypeValue.get_str()) != EXPRESSION_TYPE_INVALID);
    peek_type = stringToExpression(expressionTypeValue.get_str());

    // and the value type
    json_spirit::Value valueTypeValue = json_spirit::find_value(obj,
                                                                "VALUE_TYPE");
    if (valueTypeValue == json_spirit::Value::null) {
        throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION,
                                      "AbstractExpression::"
                                      "buildExpressionTree_recurse:"
                                      " Couldn't find VALUE_TYPE value");
    }
    std::string valueTypeString = valueTypeValue.get_str();
    value_type = stringToValue(valueTypeString);

    assert(value_type != VALUE_TYPE_INVALID);

    // add the value size
    json_spirit::Value valueSizeValue = json_spirit::find_value(obj,
                                                                "VALUE_SIZE");
    if (valueSizeValue == json_spirit::Value::null) {
        throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION,
                                      "AbstractExpression::"
                                      "buildExpressionTree_recurse:"
                                      " Couldn't find VALUE_SIZE value");
    }
    int valueSize = valueSizeValue.get_int();

    // recurse to children
    try {
        json_spirit::Value leftValue = json_spirit::find_value(obj, "LEFT");
        if (!(leftValue == json_spirit::Value::null)) {
            left_child = AbstractExpression::buildExpressionTree_recurse(leftValue.get_obj());
        }

        json_spirit::Value rightValue = json_spirit::find_value( obj, "RIGHT");
        if (!(rightValue == json_spirit::Value::null)) {
            right_child = AbstractExpression::buildExpressionTree_recurse(rightValue.get_obj());
        }

        // NULL argsVector corresponds to a missing ARGS value
        // vs. an empty argsVector which corresponds to an empty array ARGS value.
        // Different expression types could assert either a NULL or non-NULL argsVector initializer.
        json_spirit::Value argsValue = json_spirit::find_value(obj, "ARGS");
        if (!(argsValue == json_spirit::Value::null)) {
            argsVector = new std::vector<AbstractExpression*>();

            json_spirit::Array argsArray = argsValue.get_array();
            for (int ii = 0; ii < argsArray.size(); ii++) {
                json_spirit::Value argValue = argsArray[ii];
                AbstractExpression* argExpr = AbstractExpression::buildExpressionTree_recurse(argValue.get_obj());
                argsVector->push_back(argExpr);
            }
        }
        // invoke the factory. obviously it has to handle null children.
        // pass it the serialization stream in case a subclass has more
        // to read. yes, the per-class data really does follow the
        // child serializations.
        return ExpressionUtil::expressionFactory(obj, peek_type, value_type, valueSize,
                                                 left_child, right_child, argsVector);
    }
    catch (const SerializableEEException &ex) {
        delete left_child;
        delete right_child;
        delete argsVector;
        throw;
    }
}
AbstractExpression*
AbstractExpression::buildExpressionTree_recurse(json_spirit::Object &obj)
{
    // build a tree recursively from the bottom upwards.
    // when the expression node is instantiated, its type,
    // value and child types will have been discovered.

    ExpressionType peek_type = EXPRESSION_TYPE_INVALID;
    ValueType value_type = VALUE_TYPE_INVALID;
    AbstractExpression *left_child = NULL;
    AbstractExpression *right_child = NULL;

    // read the expression type
    json_spirit::Value expressionTypeValue = json_spirit::find_value(obj,
                                                                     "TYPE");
    if (expressionTypeValue == json_spirit::Value::null) {
        throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION,
                                      "AbstractExpression::"
                                      "buildExpressionTree_recurse:"
                                      " Couldn't find TYPE value");
    }
    assert(stringToExpression(expressionTypeValue.get_str()) != EXPRESSION_TYPE_INVALID);
    peek_type = stringToExpression(expressionTypeValue.get_str());

    // and the value type
    json_spirit::Value valueTypeValue = json_spirit::find_value(obj,
                                                                "VALUE_TYPE");
    if (valueTypeValue == json_spirit::Value::null) {
        throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION,
                                      "AbstractExpression::"
                                      "buildExpressionTree_recurse:"
                                      " Couldn't find VALUE_TYPE value");
    }
    std::string valueTypeString = valueTypeValue.get_str();
    value_type = stringToValue(valueTypeString);

    // this should be relatively safe, though it ignores overflow.
    if ((value_type == VALUE_TYPE_TINYINT)  ||
        (value_type == VALUE_TYPE_SMALLINT) ||
        (value_type == VALUE_TYPE_INTEGER))
    {
        value_type = VALUE_TYPE_BIGINT;
    }

    assert(value_type != VALUE_TYPE_INVALID);

    // add the value size
    json_spirit::Value valueSizeValue = json_spirit::find_value(obj,
                                                                "VALUE_SIZE");
    if (valueSizeValue == json_spirit::Value::null) {
        throw SerializableEEException(VOLT_EE_EXCEPTION_TYPE_EEEXCEPTION,
                                      "AbstractExpression::"
                                      "buildExpressionTree_recurse:"
                                      " Couldn't find VALUE_SIZE value");
    }
    int valueSize = valueSizeValue.get_int();

    // recurse to children
    try {
        json_spirit::Value leftValue = json_spirit::find_value(obj, "LEFT");
        if (!(leftValue == json_spirit::Value::null)) {
            left_child = AbstractExpression::buildExpressionTree_recurse(leftValue.get_obj());
        } else {
            left_child = NULL;
        }

        json_spirit::Value rightValue = json_spirit::find_value( obj, "RIGHT");
        if (!(rightValue == json_spirit::Value::null)) {
            right_child = AbstractExpression::buildExpressionTree_recurse(rightValue.get_obj());
        } else {
            right_child = NULL;
        }

        // invoke the factory. obviously it has to handle null children.
        // pass it the serialization stream in case a subclass has more
        // to read. yes, the per-class data really does follow the
        // child serializations.
        return expressionFactory(obj,
                                 peek_type, value_type, valueSize,
                                 left_child, right_child);
    }
    catch (SerializableEEException &ex) {
        delete left_child;
        delete right_child;
        throw;
    }
}