def load_configuration(config_file, config_dir, service_file):
    """Build configuration objects.

    If all sanity checks against daemon and service check settings are passed
    then it builds a ConfigParser object which holds all our configuration
    and a dictionary data structure which holds Bird configuration per IP
    protocol version.

    Arguments:
        config_file (str): The file name which holds daemon settings
        config_dir (str): The directory name which has configuration files
        for each service check
        service_file (str): A file which contains configuration for a single
        service check

    Returns:
        A tuple with 1st element a ConfigParser object and 2nd element
        a dictionary.
    Raises:
        ValueError if a sanity check fails.

    """
    config_files = [config_file]
    config = configparser.ConfigParser()
    config.read_dict(DEFAULT_OPTIONS)

    if not os.path.isfile(config_file):
        raise ValueError("{f} configuration file either isn't readable or "
                         "doesn't exist".format(f=config_file))
    if service_file is not None:
        if not os.path.isfile(service_file):
            raise ValueError("{f} configuration file for a service check "
                             "doesn't exist".format(f=service_file))
        else:
            config_files.append(service_file)
    elif config_dir is not None:
        if not os.path.isdir(config_dir):
            raise ValueError("{d} directory with configuration files for "
                             "service checks doesn't exist"
                             .format(d=config_dir))
        else:
            config_files.extend(glob.glob(os.path.join(config_dir, '*.conf')))

    try:
        config.read(config_files)
    except configparser.Error as exc:
        raise ValueError(exc)

    configuration_check(config)
    bird_configuration = build_bird_configuration(config)
    create_bird_config_files(bird_configuration)

    return config, bird_configuration
Build configuration objects.

    If all sanity checks against daemon and service check settings are passed
    then it builds a ConfigParser object which holds all our configuration
    and a dictionary data structure which holds Bird configuration per IP
    protocol version.

    Arguments:
        config_file (str): The file name which holds daemon settings
        config_dir (str): The directory name which has configuration files
        for each service check
        service_file (str): A file which contains configuration for a single
        service check

    Returns:
        A tuple with 1st element a ConfigParser object and 2nd element
        a dictionary.
    Raises:
        ValueError if a sanity check fails.