def fetch_data(files, folder):
    """Downloads files to folder and checks their md5 checksums

    Parameters
    ----------
    files : dictionary
        For each file in `files` the value should be (url, md5). The file will
        be downloaded from url if the file does not already exist or if the
        file exists but the md5 checksum does not match.
    folder : str
        The directory where to save the file, the directory will be created if
        it does not already exist.

    Raises
    ------
    FetcherError
        Raises if the md5 checksum of the file does not match the expected
        value. The downloaded file is not deleted when this error is raised.

    """
    if not os.path.exists(folder):
        _log("Creating new folder %s" % (folder))
        os.makedirs(folder)

    all_skip = True
    for f in files:
        url, md5 = files[f]
        fullpath = pjoin(folder, f)
        if os.path.exists(fullpath) and (_get_file_md5(fullpath) == md5):
            continue
        all_skip = False
        _log('Downloading "%s" to %s' % (f, folder))
        _get_file_data(fullpath, url)
        if _get_file_md5(fullpath) != md5:
            msg = """The downloaded file, %s, does not have the expected md5
checksum of "%s". This could mean that that something is wrong with the file or
that the upstream file has been updated.""" % (fullpath, md5)
            msg = textwrap.fill(msg)
            raise FetcherError(msg)

    if all_skip:
        _log("All files already in %s." % (folder))
    else:
        _log("Files successfully downloaded to %s" % (folder))