inline CG<Base>& CG<Base>::operator-=(const CG<Base> &right) {
    if (isParameter() && right.isParameter()) {
        *value_ -= *right.value_;

    } else {
        CodeHandler<Base>* handler;
        if (isParameter()) {
            handler = right.getCodeHandler();

        } else if (right.isParameter()) {
            if (right.isIdenticalZero()) {
                return *this; // nothing to do
            }

            handler = getCodeHandler();

        } else {
            CPPADCG_ASSERT_UNKNOWN(getCodeHandler() == right.getCodeHandler());
            handler = getCodeHandler();
        }

        std::unique_ptr<Base> value;
        if (isValueDefined() && right.isValueDefined()) {
            value.reset(new Base(getValue() - right.getValue()));
        }

        makeVariable(*handler, new OperationNode<Base>(CGOpCode::Sub,{argument(), right.argument()}), value);
    }

    return *this;
}
inline CG<Base>& CG<Base>::operator*=(const CG<Base> &right) {
    if (isParameter() && right.isParameter()) {
        *value_ *= *right.value_;

    } else {
        CodeHandler<Base>* handler;
        if (isParameter()) {
            if (isIdenticalZero()) {
                return *this; // nothing to do (does not consider that right might be infinity)
            } else if (isIdenticalOne()) {
                *this = right;
                return *this;
            }

            handler = right.getCodeHandler();

        } else if (right.isParameter()) {
            if (right.isIdenticalZero()) {
                makeParameter(Base(0.0)); // does not consider that left might be infinity
                return *this;
            } else if (right.isIdenticalOne()) {
                return *this; // nothing to do
            }

            handler = getCodeHandler();

        } else {
            CPPADCG_ASSERT_UNKNOWN(getCodeHandler() == right.getCodeHandler());
            handler = getCodeHandler();
        }

        std::unique_ptr<Base> value;
        if (isValueDefined() && right.isValueDefined()) {
            value.reset(new Base(getValue() * right.getValue()));
        }

        makeVariable(*handler, new OperationNode<Base>(CGOpCode::Mul,{argument(), right.argument()}), value);
    }

    return *this;
}