# Buggy code
def to_xml_file(self, shed_tool_data_table_config, new_elems=None, remove_elems=None):
    """
    Write the current in-memory version of the shed_tool_data_table_conf.xml file to disk.
    remove_elems are removed before new_elems are added.
    """
    if not (new_elems or remove_elems):
        log.debug(
            "ToolDataTableManager.to_xml_file called without any elements to add or remove."
        )
        return  # no changes provided, no need to persist any changes
    if not new_elems:
        new_elems = []
    if not remove_elems:
        remove_elems = []
    full_path = os.path.abspath(shed_tool_data_table_config)
    # FIXME: we should lock changing this file by other threads / head nodes
    try:
        tree = util.parse_xml(full_path)
        root = tree.getroot()
        out_elems = [elem for elem in root]
    except Exception as e:
        out_elems = []
        log.debug(
            "Could not parse existing tool data table config, assume no existing elements: %s",
            e,
        )
    for elem in remove_elems:
        # handle multiple occurrences of remove elem in existing elems
        while elem in out_elems:
            remove_elems.remove(elem)
    # add new elems
    out_elems.extend(new_elems)
    out_path_is_new = not os.path.exists(full_path)
    with open(full_path, "wb") as out:
        out.write('<?xml version="1.0"?>\n<tables>\n')
        for elem in out_elems:
            out.write(util.xml_to_string(elem, pretty=True))
        out.write("</tables>\n")
    os.chmod(full_path, 0o644)
    if out_path_is_new:
        self.tool_data_path_files.update_files()


# Traceback (OSError)
Exception in thread ToolConfWatcher.thread:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "lib/galaxy/tools/toolbox/watcher.py", line 138, in check
self.reload_callback()
File "lib/galaxy/webapps/galaxy/config_watchers.py", line 24, in <lambda>
self.tool_config_watcher = get_tool_conf_watcher(reload_callback=lambda: reload_toolbox(self.app), tool_cache=self.app.tool_cache)
File "lib/galaxy/queue_worker.py", line 92, in reload_toolbox
_get_new_toolbox(app)
File "lib/galaxy/queue_worker.py", line 111, in _get_new_toolbox
new_toolbox = tools.ToolBox(tool_configs, app.config.tool_path, app)
File "lib/galaxy/tools/__init__.py", line 226, in __init__
app=app,
File "lib/galaxy/tools/toolbox/base.py", line 1061, in __init__
super(BaseGalaxyToolBox, self).__init__(config_filenames, tool_root_dir, app)
File "lib/galaxy/tools/toolbox/base.py", line 87, in __init__
self._save_integrated_tool_panel()
File "lib/galaxy/tools/toolbox/integrated_panel.py", line 46, in _save_integrated_tool_panel
self._write_integrated_tool_panel_config_file()
File "lib/galaxy/tools/toolbox/integrated_panel.py", line 106, in _write_integrated_tool_panel_config_file
os.chmod(self._integrated_tool_panel_config, 0o644)
OSError: [Errno 2] No such file or directory: '/data/users/mvandenb/gx/config/integrated_tool_panel.xml'

# Fixed code
def to_xml_file(self, shed_tool_data_table_config, new_elems=None, remove_elems=None):
    """
    Write the current in-memory version of the shed_tool_data_table_conf.xml file to disk.
    remove_elems are removed before new_elems are added.
    """
    if not (new_elems or remove_elems):
        log.debug(
            "ToolDataTableManager.to_xml_file called without any elements to add or remove."
        )
        return  # no changes provided, no need to persist any changes
    if not new_elems:
        new_elems = []
    if not remove_elems:
        remove_elems = []
    full_path = os.path.abspath(shed_tool_data_table_config)
    # FIXME: we should lock changing this file by other threads / head nodes
    try:
        tree = util.parse_xml(full_path)
        root = tree.getroot()
        out_elems = [elem for elem in root]
    except Exception as e:
        out_elems = []
        log.debug(
            "Could not parse existing tool data table config, assume no existing elements: %s",
            e,
        )
    for elem in remove_elems:
        # handle multiple occurrences of remove elem in existing elems
        while elem in out_elems:
            remove_elems.remove(elem)
    # add new elems
    out_elems.extend(new_elems)
    out_path_is_new = not os.path.exists(full_path)
    with RenamedTemporaryFile(full_path) as out:
        out.write('<?xml version="1.0"?>\n<tables>\n')
        for elem in out_elems:
            out.write(util.xml_to_string(elem, pretty=True))
        out.write("</tables>\n")
    os.chmod(full_path, 0o644)
    if out_path_is_new:
        self.tool_data_path_files.update_files()