Verify that the variable is in the ``make.conf`` and has the provided
    settings. If value is set, contains and excludes will be ignored.

    name
        The variable name. This will automatically be converted to upper
        case since variables in ``make.conf`` are in upper case

    value
        Enforce that the value of the variable is set to the provided value

    contains
        Enforce that the value of the variable contains the provided value

    excludes
        Enforce that the value of the variable does not contain the provided
        value.

def present(name, value=None, contains=None, excludes=None):
    '''
    Verify that the variable is in the ``make.conf`` and has the provided
    settings. If value is set, contains and excludes will be ignored.

    name
        The variable name. This will automatically be converted to upper
        case since variables in ``make.conf`` are in upper case

    value
        Enforce that the value of the variable is set to the provided value

    contains
        Enforce that the value of the variable contains the provided value

    excludes
        Enforce that the value of the variable does not contain the provided
        value.
    '''
    ret = {'changes': {},
           'comment': '',
           'name': name,
           'result': True}

    # Make name all Uppers since make.conf uses all Upper vars
    upper_name = name.upper()

    old_value = __salt__['makeconf.get_var'](upper_name)

    # If only checking if variable is present allows for setting the
    # variable outside of salt states, but the state can still ensure
    # that is exists
    if value is None and contains is None and excludes is None:
        # variable is present
        if old_value is not None:
            msg = 'Variable {0} is already present in make.conf'
            ret['comment'] = msg.format(name)
        else:
            if __opts__['test']:
                msg = 'Variable {0} is to be set in make.conf'
                ret['comment'] = msg.format(name)
                ret['result'] = None
            else:
                changes = __salt__['makeconf.set_var'](upper_name, '')

                # If failed to be set
                if changes[upper_name]['new'] is None:
                    msg = 'Variable {0} failed to be set in make.conf'
                    ret['comment'] = msg.format(name)
                    ret['result'] = False
                else:
                    msg = 'Variable {0} set in make.conf'
                    ret['comment'] = msg.format(name)

    elif value is not None:
        # variable is present and is set to value
        if old_value is not None and old_value == value:
            msg = 'Variable {0} is already "{1}" in make.conf'
            ret['comment'] = msg.format(name, value)
        else:
            if __opts__['test']:
                msg = 'Variable {0} is to be set to "{1}" in make.conf'
                ret['comment'] = msg.format(name, value)
                ret['result'] = None
            else:
                changes = __salt__['makeconf.set_var'](upper_name, value)

                # If failed to be set
                new_value = __salt__['makeconf.get_var'](upper_name)
                if new_value is None or new_value != value:
                    msg = 'Variable {0} failed to be set in make.conf'
                    ret['comment'] = msg.format(name)
                    ret['result'] = False
                else:
                    msg = 'Variable {0} is set in make.conf'
                    ret['changes'] = changes
                    ret['comment'] = msg.format(name)

    elif contains is not None or excludes is not None:
        # Make these into sets to easily compare things
        contains_set = _make_set(contains)
        excludes_set = _make_set(excludes)
        old_value_set = _make_set(old_value)
        if contains_set.intersection(excludes_set):
            msg = 'Variable {0} cannot contain and exclude the same value'
            ret['comment'] = msg.format(name)
            ret['result'] = False
        else:
            to_append = set()
            to_trim = set()
            if contains is not None:
                to_append = contains_set.difference(old_value_set)
            if excludes is not None:
                to_trim = excludes_set.intersection(old_value_set)
            if not to_append and not to_trim:
                msg = 'Variable {0} is correct in make.conf'
                ret['comment'] = msg.format(name)
            else:
                if __opts__['test']:
                    msg = 'Variable {0} is set to'.format(name)
                    if to_append:
                        msg += ' append "{0}"'.format(list(to_append))
                    if to_trim:
                        msg += ' trim "{0}"'.format(list(to_trim))
                    msg += ' in make.conf'
                    ret['comment'] = msg
                    ret['result'] = None
                else:
                    for value in to_append:
                        __salt__['makeconf.append_var'](upper_name, value)
                    for value in to_trim:
                        __salt__['makeconf.trim_var'](upper_name, value)
                    new_value = __salt__['makeconf.get_var'](upper_name)

                    # TODO verify appends and trims worked
                    ret['changes'] = {upper_name: {'old': old_value,
                                                  'new': new_value}}
                    msg = 'Variable {0} is correct in make.conf'
                    ret['comment'] = msg.format(name)

    # Now finally return
    return ret