# Buggy code
def update_tool_shed_repository(
    self,
    repository,
    tool_shed_url,
    latest_ctx_rev,
    latest_changeset_revision,
    install_new_dependencies=True,
    install_options=None,
):
    install_options = install_options or {}
    original_metadata_dict = repository.metadata
    original_repository_dependencies_dict = original_metadata_dict.get(
        "repository_dependencies", {}
    )
    original_repository_dependencies = original_repository_dependencies_dict.get(
        "repository_dependencies", []
    )
    original_tool_dependencies_dict = original_metadata_dict.get(
        "tool_dependencies", {}
    )
    shed_tool_conf, tool_path, relative_install_dir = (
        suc.get_tool_panel_config_tool_path_install_dir(self.app, repository)
    )
    if tool_path:
        repo_files_dir = os.path.abspath(
            os.path.join(tool_path, relative_install_dir, repository.name)
        )
    else:
        repo_files_dir = os.path.abspath(
            os.path.join(relative_install_dir, repository.name)
        )
    repository_clone_url = os.path.join(
        tool_shed_url, "repos", repository.owner, repository.name
    )
    log.info(
        "Updating repository '%s' to %s:%s",
        repository.name,
        latest_ctx_rev,
        latest_changeset_revision,
    )
    hg_util.pull_repository(repo_files_dir, repository_clone_url, latest_ctx_rev)
    hg_util.update_repository(repo_files_dir, latest_ctx_rev)
    # Remove old Data Manager entries
    if repository.includes_data_managers:
        dmh = data_manager.DataManagerHandler(self.app)
        dmh.remove_from_data_manager(repository)
    # Update the repository metadata.
    tpm = tool_panel_manager.ToolPanelManager(self.app)
    irmm = InstalledRepositoryMetadataManager(
        app=self.app,
        tpm=tpm,
        repository=repository,
        changeset_revision=latest_changeset_revision,
        repository_clone_url=repository_clone_url,
        shed_config_dict=repository.get_shed_config_dict(self.app),
        relative_install_dir=relative_install_dir,
        repository_files_dir=None,
        resetting_all_metadata_on_repository=False,
        updating_installed_repository=True,
        persist=True,
    )
    irmm.generate_metadata_for_changeset_revision()
    irmm_metadata_dict = irmm.get_metadata_dict()
    if "tools" in irmm_metadata_dict:
        tool_panel_dict = irmm_metadata_dict.get("tool_panel_section", None)
        if tool_panel_dict is None:
            tool_panel_dict = tpm.generate_tool_panel_dict_from_shed_tool_conf_entries(
                repository
            )
        repository_tools_tups = irmm.get_repository_tools_tups()
        tpm.add_to_tool_panel(
            repository_name=str(repository.name),
            repository_clone_url=repository_clone_url,
            changeset_revision=str(repository.installed_changeset_revision),
            repository_tools_tups=repository_tools_tups,
            owner=str(repository.owner),
            shed_tool_conf=shed_tool_conf,
            tool_panel_dict=tool_panel_dict,
            new_install=False,
        )
        # Add new Data Manager entries
        if "data_manager" in irmm_metadata_dict:
            dmh = data_manager.DataManagerHandler(self.app)
            dmh.install_data_managers(
                self.app.config.shed_data_manager_config_file,
                irmm_metadata_dict,
                repository.get_shed_config_dict(self.app),
                os.path.join(relative_install_dir, repository.name),
                repository,
                repository_tools_tups,
            )
    if (
        "repository_dependencies" in irmm_metadata_dict
        or "tool_dependencies" in irmm_metadata_dict
    ):
        new_repository_dependencies_dict = irmm_metadata_dict.get(
            "repository_dependencies", {}
        )
        new_repository_dependencies = new_repository_dependencies_dict.get(
            "repository_dependencies", []
        )
        new_tool_dependencies_dict = irmm_metadata_dict.get("tool_dependencies", {})
        if new_repository_dependencies:
            # [[http://localhost:9009', package_picard_1_56_0', devteam', 910b0b056666', False', False']]
            if new_repository_dependencies == original_repository_dependencies:
                for new_repository_tup in new_repository_dependencies:
                    # Make sure all dependencies are installed.
                    # TODO: Repository dependencies that are not installed should be displayed to the user,
                    # giving them the option to install them or not. This is the same behavior as when initially
                    # installing and when re-installing.
                    (
                        new_tool_shed,
                        new_name,
                        new_owner,
                        new_changeset_revision,
                        new_pir,
                        new_oicct,
                    ) = common_util.parse_repository_dependency_tuple(
                        new_repository_tup
                    )
                    # Mock up a repo_info_tupe that has the information needed to see if the repository dependency
                    # was previously installed.
                    repo_info_tuple = (
                        "",
                        new_tool_shed,
                        new_changeset_revision,
                        "",
                        new_owner,
                        [],
                        [],
                    )
                    # Since the value of new_changeset_revision came from a repository dependency
                    # definition, it may occur earlier in the Tool Shed's repository changelog than
                    # the Galaxy tool_shed_repository.installed_changeset_revision record value, so
                    # we set from_tip to True to make sure we get the entire set of changeset revisions
                    # from the Tool Shed.
                    new_repository_db_record, installed_changeset_revision = (
                        repository_util.repository_was_previously_installed(
                            self.app,
                            tool_shed_url,
                            new_name,
                            repo_info_tuple,
                            from_tip=True,
                        )
                    )
                    if (
                        new_repository_db_record
                        and new_repository_db_record.status
                        in [
                            self.install_model.ToolShedRepository.installation_status.ERROR,
                            self.install_model.ToolShedRepository.installation_status.NEW,
                            self.install_model.ToolShedRepository.installation_status.UNINSTALLED,
                        ]
                    ) or not new_repository_db_record:
                        log.debug(
                            "Update to %s contains new repository dependency %s/%s",
                            repository.name,
                            new_owner,
                            new_name,
                        )
                        if not install_new_dependencies:
                            return ("repository", irmm_metadata_dict)
                        else:
                            self.install(
                                tool_shed_url,
                                new_name,
                                new_owner,
                                new_changeset_revision,
                                install_options,
                            )
        # Updates received did not include any newly defined repository dependencies but did include
        # newly defined tool dependencies.  If the newly defined tool dependencies are not the same
        # as the originally defined tool dependencies, we need to install them.
        if not install_new_dependencies:
            for new_key, new_val in new_tool_dependencies_dict.items():
                if new_key not in original_tool_dependencies_dict:
                    return ("tool", irmm_metadata_dict)
                original_val = original_tool_dependencies_dict[new_key]
                if new_val != original_val:
                    return ("tool", irmm_metadata_dict)
    # Updates received did not include any newly defined repository dependencies or newly defined
    # tool dependencies that need to be installed.
    repository = self.app.update_repository_manager.update_repository_record(
        repository=repository,
        updated_metadata_dict=irmm_metadata_dict,
        updated_changeset_revision=latest_changeset_revision,
        updated_ctx_rev=latest_ctx_rev,
    )
    return (None, None)


# Traceback (ParseError)
Nov 09 13:22:10 sn04.bi.uni-freiburg.de uwsgi[4107748]: [pid: 4124485|app: 0|req: 9911/42155] 88.66.136.83 () {84 vars in 1575 bytes} [Sat Nov  9 13:22:10 2019] POST /admin_toolshed/repository_installation_status_updates => generated 2 bytes in 23 msecs (HTTP/1.1 200) 3 headers in 96 bytes (1 switches on core 0)
Nov 09 13:22:11 sn04.bi.uni-freiburg.de uwsgi[3191341]: galaxy.datatypes.registry DEBUG 2019-11-09 13:22:11,317 [p:119216,w:4,m:0] [Thread-1] Loaded external metadata tool: __SET_METADATA__
Nov 09 13:22:11 sn04.bi.uni-freiburg.de uwsgi[3191341]: galaxy.tools.special_tools DEBUG 2019-11-09 13:22:11,323 [p:119216,w:4,m:0] [Thread-1] Loaded history import tool: __IMPORT_HISTORY__
Nov 09 13:22:11 sn04.bi.uni-freiburg.de uwsgi[3191341]: galaxy.tools.special_tools DEBUG 2019-11-09 13:22:11,327 [p:119216,w:4,m:0] [Thread-1] Loaded data fetch tool: __DATA_FETCH__
Nov 09 13:22:11 sn04.bi.uni-freiburg.de uwsgi[3191341]: galaxy.tools.special_tools DEBUG 2019-11-09 13:22:11,330 [p:119216,w:4,m:0] [Thread-1] Loaded history export tool: __EXPORT_HISTORY__
Nov 09 13:22:11 sn04.bi.uni-freiburg.de uwsgi[3191341]: galaxy.queue_worker INFO 2019-11-09 13:22:11,332 [p:119216,w:4,m:0] [Thread-1] Queuing async task rebuild_toolbox_search_index for main.web.4.
Nov 09 13:22:11 sn04.bi.uni-freiburg.de uwsgi[3191341]: galaxy.queue_worker DEBUG 2019-11-09 13:22:11,336 [p:119216,w:4,m:0] [Thread-1] Toolbox reload (29743.348 ms)
Nov 09 13:22:11 sn04.bi.uni-freiburg.de uwsgi[3191341]: galaxy.queue_worker INFO 2019-11-09 13:22:11,338 [p:119216,w:4,m:0] [Thread-1] Instance 'main.web.4' received 'reload_toolbox' task, executing now.
Nov 09 13:22:11 sn04.bi.uni-freiburg.de uwsgi[3191341]: galaxy.queue_worker DEBUG 2019-11-09 13:22:11,338 [p:119216,w:4,m:0] [Thread-1] Executing toolbox reload on 'main.web.4'
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3843198]: 115.146.92.55 - - [09/Nov/2019:13:22:11 +0200] "GET /api/jobs/4d16a9b9d521c9b3?key=59001665ead9d0bfd82dad0c0253dda0 HTTP/1.1" 200 - "-" "python-requests/2.22.0"
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3843198]: [pid: 3882852|app: 0|req: 11155/55634] 115.146.92.55 () {70 vars in 992 bytes} [Sat Nov  9 13:22:11 2019] GET /api/jobs/4d16a9b9d521c9b3?key=59001665ead9d0bfd82dad0c0253dda0 => generated 1118 bytes in 88 msecs (HTTP/1.1 200) 2 headers in 110 bytes (1 switches on core 0)
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3843198]: galaxy.tools.search DEBUG 2019-11-09 13:22:12,036 [p:228435,w:4,m:0] [Thread-1] Toolbox index finished (29660.792 ms)
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: galaxy.util ERROR 2019-11-09 13:22:12,537 [p:119216,w:4,m:0] [Thread-1] Error parsing file /opt/galaxy/mutable-config/integrated_tool_panel.xml
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: Traceback (most recent call last):
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "lib/galaxy/util/__init__.py", line 236, in parse_xml
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: root = tree.parse(fname, parser=ElementTree.XMLParser(target=DoctypeSafeCallbackTarget()))
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "/usr/lib64/python2.7/xml/etree/ElementTree.py", line 657, in parse
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: self._root = parser.close()
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "/usr/lib64/python2.7/xml/etree/ElementTree.py", line 1654, in close
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: self._raiseerror(v)
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "/usr/lib64/python2.7/xml/etree/ElementTree.py", line 1506, in _raiseerror
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: raise err
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: ParseError: unclosed token: line 10952, column 8
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: galaxy.queue_worker ERROR 2019-11-09 13:22:12,538 [p:119216,w:4,m:0] [Thread-1] Error running control task type: reload_toolbox
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: Traceback (most recent call last):
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "lib/galaxy/queue_worker.py", line 372, in process_task
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: result = f(self.app, **body['kwargs'])
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "lib/galaxy/queue_worker.py", line 171, in reload_toolbox
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: _get_new_toolbox(app)
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "lib/galaxy/queue_worker.py", line 188, in _get_new_toolbox
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: new_toolbox = tools.ToolBox(tool_configs, app.config.tool_path, app)
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "lib/galaxy/tools/__init__.py", line 253, in __init__
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: app=app,
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "lib/galaxy/tools/toolbox/base.py", line 1163, in __init__
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: super(BaseGalaxyToolBox, self).__init__(config_filenames, tool_root_dir, app)
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "lib/galaxy/tools/toolbox/base.py", line 100, in __init__
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: self._init_integrated_tool_panel(app.config)
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "lib/galaxy/tools/toolbox/integrated_panel.py", line 39, in _init_integrated_tool_panel
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: self._load_integrated_tool_panel_keys()
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "lib/galaxy/tools/toolbox/base.py", line 445, in _load_integrated_tool_panel_keys
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: tree = parse_xml(self._integrated_tool_panel_config)
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "lib/galaxy/util/__init__.py", line 236, in parse_xml
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: root = tree.parse(fname, parser=ElementTree.XMLParser(target=DoctypeSafeCallbackTarget()))
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "/usr/lib64/python2.7/xml/etree/ElementTree.py", line 657, in parse
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: self._root = parser.close()
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "/usr/lib64/python2.7/xml/etree/ElementTree.py", line 1654, in close
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: self._raiseerror(v)
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: File "/usr/lib64/python2.7/xml/etree/ElementTree.py", line 1506, in _raiseerror
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: raise err
Nov 09 13:22:12 sn04.bi.uni-freiburg.de uwsgi[3191341]: ParseError: unclosed token: line 10952, column 8

# Fixed code
def update_tool_shed_repository(
    self,
    repository,
    tool_shed_url,
    latest_ctx_rev,
    latest_changeset_revision,
    install_new_dependencies=True,
    install_options=None,
):
    install_options = install_options or {}
    original_metadata_dict = repository.metadata
    original_repository_dependencies_dict = original_metadata_dict.get(
        "repository_dependencies", {}
    )
    original_repository_dependencies = original_repository_dependencies_dict.get(
        "repository_dependencies", []
    )
    original_tool_dependencies_dict = original_metadata_dict.get(
        "tool_dependencies", {}
    )
    shed_tool_conf, tool_path, relative_install_dir = (
        suc.get_tool_panel_config_tool_path_install_dir(self.app, repository)
    )
    if tool_path:
        repo_files_dir = os.path.abspath(
            os.path.join(tool_path, relative_install_dir, repository.name)
        )
    else:
        repo_files_dir = os.path.abspath(
            os.path.join(relative_install_dir, repository.name)
        )
    repository_clone_url = os.path.join(
        tool_shed_url, "repos", repository.owner, repository.name
    )
    # Set a status, even though we're probably not cloning.
    self.update_tool_shed_repository_status(
        repository, status=repository.installation_status.CLONING
    )
    log.info(
        "Updating repository '%s' to %s:%s",
        repository.name,
        latest_ctx_rev,
        latest_changeset_revision,
    )
    if not os.path.exists(repo_files_dir):
        log.debug(
            "Repository directory '%s' does not exist, cloning repository instead of updating repository",
            repo_files_dir,
        )
        hg_util.clone_repository(
            repository_clone_url=repository_clone_url,
            repository_file_dir=repo_files_dir,
            ctx_rev=latest_ctx_rev,
        )
    hg_util.pull_repository(repo_files_dir, repository_clone_url, latest_ctx_rev)
    hg_util.update_repository(repo_files_dir, latest_ctx_rev)
    # Remove old Data Manager entries
    if repository.includes_data_managers:
        dmh = data_manager.DataManagerHandler(self.app)
        dmh.remove_from_data_manager(repository)
    # Update the repository metadata.
    tpm = tool_panel_manager.ToolPanelManager(self.app)
    irmm = InstalledRepositoryMetadataManager(
        app=self.app,
        tpm=tpm,
        repository=repository,
        changeset_revision=latest_changeset_revision,
        repository_clone_url=repository_clone_url,
        shed_config_dict=repository.get_shed_config_dict(self.app),
        relative_install_dir=relative_install_dir,
        repository_files_dir=None,
        resetting_all_metadata_on_repository=False,
        updating_installed_repository=True,
        persist=True,
    )
    irmm.generate_metadata_for_changeset_revision()
    irmm_metadata_dict = irmm.get_metadata_dict()
    self.update_tool_shed_repository_status(
        repository, status=repository.installation_status.INSTALLED
    )
    if "tools" in irmm_metadata_dict:
        tool_panel_dict = irmm_metadata_dict.get("tool_panel_section", None)
        if tool_panel_dict is None:
            tool_panel_dict = tpm.generate_tool_panel_dict_from_shed_tool_conf_entries(
                repository
            )
        repository_tools_tups = irmm.get_repository_tools_tups()
        tpm.add_to_tool_panel(
            repository_name=str(repository.name),
            repository_clone_url=repository_clone_url,
            changeset_revision=str(repository.installed_changeset_revision),
            repository_tools_tups=repository_tools_tups,
            owner=str(repository.owner),
            shed_tool_conf=shed_tool_conf,
            tool_panel_dict=tool_panel_dict,
            new_install=False,
        )
        # Add new Data Manager entries
        if "data_manager" in irmm_metadata_dict:
            dmh = data_manager.DataManagerHandler(self.app)
            dmh.install_data_managers(
                self.app.config.shed_data_manager_config_file,
                irmm_metadata_dict,
                repository.get_shed_config_dict(self.app),
                os.path.join(relative_install_dir, repository.name),
                repository,
                repository_tools_tups,
            )
    if (
        "repository_dependencies" in irmm_metadata_dict
        or "tool_dependencies" in irmm_metadata_dict
    ):
        new_repository_dependencies_dict = irmm_metadata_dict.get(
            "repository_dependencies", {}
        )
        new_repository_dependencies = new_repository_dependencies_dict.get(
            "repository_dependencies", []
        )
        new_tool_dependencies_dict = irmm_metadata_dict.get("tool_dependencies", {})
        if new_repository_dependencies:
            # [[http://localhost:9009', package_picard_1_56_0', devteam', 910b0b056666', False', False']]
            if new_repository_dependencies == original_repository_dependencies:
                for new_repository_tup in new_repository_dependencies:
                    # Make sure all dependencies are installed.
                    # TODO: Repository dependencies that are not installed should be displayed to the user,
                    # giving them the option to install them or not. This is the same behavior as when initially
                    # installing and when re-installing.
                    (
                        new_tool_shed,
                        new_name,
                        new_owner,
                        new_changeset_revision,
                        new_pir,
                        new_oicct,
                    ) = common_util.parse_repository_dependency_tuple(
                        new_repository_tup
                    )
                    # Mock up a repo_info_tupe that has the information needed to see if the repository dependency
                    # was previously installed.
                    repo_info_tuple = (
                        "",
                        new_tool_shed,
                        new_changeset_revision,
                        "",
                        new_owner,
                        [],
                        [],
                    )
                    # Since the value of new_changeset_revision came from a repository dependency
                    # definition, it may occur earlier in the Tool Shed's repository changelog than
                    # the Galaxy tool_shed_repository.installed_changeset_revision record value, so
                    # we set from_tip to True to make sure we get the entire set of changeset revisions
                    # from the Tool Shed.
                    new_repository_db_record, installed_changeset_revision = (
                        repository_util.repository_was_previously_installed(
                            self.app,
                            tool_shed_url,
                            new_name,
                            repo_info_tuple,
                            from_tip=True,
                        )
                    )
                    if (
                        new_repository_db_record
                        and new_repository_db_record.status
                        in [
                            self.install_model.ToolShedRepository.installation_status.ERROR,
                            self.install_model.ToolShedRepository.installation_status.NEW,
                            self.install_model.ToolShedRepository.installation_status.UNINSTALLED,
                        ]
                    ) or not new_repository_db_record:
                        log.debug(
                            "Update to %s contains new repository dependency %s/%s",
                            repository.name,
                            new_owner,
                            new_name,
                        )
                        if not install_new_dependencies:
                            return ("repository", irmm_metadata_dict)
                        else:
                            self.install(
                                tool_shed_url,
                                new_name,
                                new_owner,
                                new_changeset_revision,
                                install_options,
                            )
        # Updates received did not include any newly defined repository dependencies but did include
        # newly defined tool dependencies.  If the newly defined tool dependencies are not the same
        # as the originally defined tool dependencies, we need to install them.
        if not install_new_dependencies:
            for new_key, new_val in new_tool_dependencies_dict.items():
                if new_key not in original_tool_dependencies_dict:
                    return ("tool", irmm_metadata_dict)
                original_val = original_tool_dependencies_dict[new_key]
                if new_val != original_val:
                    return ("tool", irmm_metadata_dict)
    # Updates received did not include any newly defined repository dependencies or newly defined
    # tool dependencies that need to be installed.
    repository = self.app.update_repository_manager.update_repository_record(
        repository=repository,
        updated_metadata_dict=irmm_metadata_dict,
        updated_changeset_revision=latest_changeset_revision,
        updated_ctx_rev=latest_ctx_rev,
    )
    return (None, None)