def validate_higlass_file_sources(files_info, expected_genome_assembly):
    """
    Args:
        files_info(list)            : A list of dicts. Each dict contains the
            file's uuid and data.
        expected_genome_assembly(str, optional, default=None): If provided,
            each file should have this genome assembly. If it's not provided,
            all of the files will be checked to ensure they have a matching
            genome assembly.

    Returns:
        A dictionary with the following keys:
            success(bool)               : True if there were no errors.
            current_genome_assembly(str): A string indicating the genome assembly of the files.
            errors(str)                 : A string (or None if there are no errors)
    """

    files_by_genome_assembly = {}
    for file in files_info:
        # Get the uuid.
        uuid = file["uuid"]

        # Get the file data.
        data = file["data"]

        if not data:
            return {
                "success" : False,
                "errors" : "File {uuid} does not exist".format(uuid=uuid),
            }

        # Get the higlass_uid.
        if "higlass_uid" not in data:
            return {
                "success" : False,
                "errors" : "File {uuid} does not have higlass_uid".format(uuid=uuid)
            }

        # Get the genome_assembly.
        if "genome_assembly" not in data:
            return {
                "success" : False,
                "errors" : "File {uuid} does not have genome assembly".format(uuid=uuid)
            }

        if data["genome_assembly"] not in files_by_genome_assembly:
            files_by_genome_assembly[data["genome_assembly"]] = []
        files_by_genome_assembly[data["genome_assembly"]].append(uuid)

    # Make sure all of the files have the same genome assembly.
    human_readable_ga_listings = []
    for ga in [g for g in files_by_genome_assembly if g != expected_genome_assembly]:
        human_readable_ga_listings.append(
            "{ga}: {uuids}".format(
                ga=ga,
                uuids=", ".join(files_by_genome_assembly[ga])
            )
        )

    if len(files_info) > 0:
        if expected_genome_assembly:
            if expected_genome_assembly not in files_by_genome_assembly or \
                len(files_by_genome_assembly.keys()) > 1:
                return {
                    "success" : False,
                    "errors" : "All files are not {expected} genome assembly: {files_by_ga}".format(
                        expected = expected_genome_assembly,
                        files_by_ga = "; ".join(human_readable_ga_listings),
                    )
                }
        else:
            if len(files_by_genome_assembly.keys()) > 1:
                return {
                    "success" : False,
                    "errors" : "Files have multiple genome assemblies: {files_by_ga}".format(
                        expected = expected_genome_assembly,
                        files_by_ga = "; ".join(human_readable_ga_listings),
                    )
                }

    # Make sure we found a genome assembly.
    if not (expected_genome_assembly or files_by_genome_assembly):
        return {
            "success" : False,
            "errors": "No Genome Assembly provided or found in files."
        }

    # Everything is verified.
    return {
        "success" : True,
        "errors": "",
        "genome_assembly": expected_genome_assembly or list(files_by_genome_assembly.keys())[0]
    }