def _process_internal(self, config: dict) -> bool:
        """
         * Processes the config. Throw
        :param config:
        :return:
        """

        if "boundingboxes" not in config:
            raise RuntimeError("No 'boundingboxes' were specified in the config.")

        bboxes = config['boundingboxes']
        cities = list(bboxes.keys())
        random.shuffle(cities)

        options = config.get("options", {})
        gloabl_zoom_levels = options.get("zoom_levels", [])
        separate_instances = options.get("separate_instances", False)

        query = config.get("query", {})
        tags = query.get("tags", [])

        output_directory = options.get("target_dir", ".")
        if not os.path.isabs(output_directory):
            output_directory = os.path.join(os.getcwd(), output_directory)
        if not os.path.isdir(output_directory):
            os.makedirs(output_directory)
        assert os.path.isdir(output_directory)

        all_downloaded = True
        for bbox_name in cities:
            print("Processing '{}'...".format(bbox_name))
            bbox = bboxes[bbox_name]

            zoom_levels = gloabl_zoom_levels
            if isinstance(bbox, dict):
                if 'zoom_levels' in bbox:
                    zoom_levels = bbox['zoom_levels']

            if not zoom_levels:
                raise RuntimeError("Neither the config nor the bounding box '{}' have any zoom_levels specified.")

            for z in zoom_levels:
                complete = self._process_bbox(bbox_name=bbox_name,
                                              bbox=bbox,
                                              zoom_level=z,
                                              output_directory=os.path.join(output_directory, bbox_name),
                                              separate_instances=separate_instances,
                                              tags=tags)
                if not complete:
                    all_downloaded = False
        return all_downloaded