def _get_xul_runtime(self):
        """ Get path to executable of a xul runtime. The returned path
        is in a writable directory. On Unix/OSX it may be a symlink,
        on Windows it is a real file. Returns None if no XUL runtime
        could be found.
        """

        # Define name of xul executable
        exe_name = 'xulrunner'
        exe_name += '.exe' if sys.platform.startswith('win') else ''

        # Get location and version of firefox
        ff_exe = get_firefox_exe()
        ff_version = ''
        if ff_exe:
            if 'Contents/MacOS/' in ff_exe:
                inifile = op.join(op.dirname(ff_exe),
                                  '../Resources/application.ini')
            else:
                inifile = op.join(op.dirname(ff_exe), 'application.ini')
            for line in open(inifile, 'rb').read().decode().splitlines():
                if line.lower().startswith('version'):
                    ff_version = 'xul_' + line.split('=')[1].strip()
                    break

        # Get dir with runtimes and list of subdirs (that represent versions)
        xuldir = op.join(appdata_dir('flexx'), 'webruntimes')
        if not op.isdir(xuldir):
            os.mkdir(xuldir)
        dnames = [d for d in sorted(os.listdir(xuldir)) if d.startswith('xul')]

        # Get obsolete versions, and remove them
        obsolete = [d for d in dnames if not
                    op.isfile(op.realpath(op.join(xuldir, d, exe_name)))]
        dnames = [d for d in dnames if d not in obsolete]

        # Clean up old runtimes (do before installing new ff, because
        # we may be "updating" it)
        for dname in (obsolete + dnames[:-1]):
            logging.info('Clearing XUL runtime at %s' % dname)
            try:
                shutil.rmtree(op.join(xuldir, dname))
            except (OSError, IOError):
                pass

        # Must we install ff?
        if ff_version:
            if (not dnames) or (dnames[-1] < ff_version):
                self._install_ff_locally(op.join(xuldir, ff_version), ff_exe)
                dnames.append(ff_version)

        # Return highest version or None
        if dnames:
            return op.join(xuldir, dnames[-1], exe_name)
dataset/ETHPy150Open zoofIO/flexx/flexx/webruntime/xul.py/XulRuntime._get_xul_runtime/original