diff --git a/Tools/idle/browser.py b/Tools/idle/browser.py
new file mode 100755
index 0000000..3829d49
--- /dev/null
+++ b/Tools/idle/browser.py
@@ -0,0 +1,157 @@
+"""Remote-control interfaces to some browsers."""
+
+import os
+import string
+import sys
+
+
+DEFAULT_CONFIG_FILE = "~/.browser.ini"
+PROCESS_CREATION_DELAY = 4
+
+DEFAULT_BROWSER = "netscape"
+
+_browsers = {}
+
+
+def get(name=None):
+    if name is None:
+        name = get_default_browser()
+    else:
+        name = string.lower(name)
+    L = _browsers[name]
+    if L[1] is None:
+        L[1] = L[0]()
+    return L[1]
+
+
+def get_default_browser(file=None):
+    if file is None:
+        files = [DEFAULT_CONFIG_FILE]
+    else:
+        files = [file, DEFAULT_CONFIG_FILE]
+    for file in files:
+        file = os.path.expandvars(os.path.expanduser(file))
+        if file and os.path.isfile(file):
+            import ConfigParser
+            cf = ConfigParser.ConfigParser()
+            cf.read([file])
+            try:
+                return string.lower(cf.get("Browser", "name"))
+            except ConfigParser.Error:
+                pass
+    return DEFAULT_BROWSER
+
+
+_default_browser = None
+
+def _get_browser():
+    global _default_browser
+    if _default_browser is None:
+        _default_browser = get()
+    return _default_browser
+
+
+def open(url, new=0):
+    _get_browser().open(url, new)
+
+
+def open_new(url):
+    _get_browser().open_new(url)
+
+
+def register(name, klass):
+    _browsers[string.lower(name)] = [klass, None]
+
+
+class Netscape:
+    autoRaise = 0
+
+    def _remote(self, action):
+        raise_opt = ("-noraise", "-raise")[self.autoRaise]
+        cmd = "netscape %s -remote '%s' >/dev/null 2>&1" % (raise_opt, action)
+        rc = os.system(cmd)
+        if rc:
+            import time
+            os.system("netscape -no-about-splash &")
+            time.sleep(PROCESS_CREATION_DELAY)
+            rc = os.system(cmd)
+        return not rc
+
+    def open(self, url, new=0):
+        if new:
+            self.open_new(url)
+        else:
+            self._remote("openURL(%s)" % url)
+
+    def open_new(self, url):
+        self._remote("openURL(%s, new-window)" % url)
+
+register("netscape", Netscape)
+
+
+class Grail:
+    # There should be a way to maintain a connection to Grail, but the
+    # Grail remote control protocol doesn't really allow that at this
+    # point.  It probably never will!
+
+    def _find_grail_rc(self):
+        import glob
+        import pwd
+        import socket
+        import tempfile
+        tempdir = os.path.join(tempfile.gettempdir(), ".grail-unix")
+        user = pwd.getpwuid(_os.getuid())[0]
+        filename = os.path.join(tempdir, user + "-*")
+        maybes = glob.glob(filename)
+        if not maybes:
+            return None
+        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        for fn in maybes:
+            # need to PING each one until we find one that's live
+            try:
+                s.connect(fn)
+            except socket.error:
+                # no good; attempt to clean it out, but don't fail:
+                try:
+                    os.unlink(fn)
+                except IOError:
+                    pass
+            else:
+                return s
+
+    def _remote(self, action):
+        s = self._find_grail_rc()
+        if not s:
+            return 0
+        s.send(action)
+        s.close()
+        return 1
+
+    def open(self, url, new=0):
+        if new:
+            self.open_new(url)
+        else:
+            self._remote("LOAD " + url)
+
+    def open_new(self, url):
+        self._remote("LOADNEW " + url)
+
+register("grail", Grail)
+
+
+class WindowsDefault:
+    def open(self, url, new=0):
+        import win32api, win32con
+        try:
+            win32api.ShellExecute(0, "open", url, None, ".",
+                                  win32con.SW_SHOWNORMAL)
+        except:
+            traceback.print_exc()
+            raise
+
+    def open_new(self, url):
+        self.open(url)
+
+if sys.platform[:3] == "win":
+    register("windows-default", WindowsDefault)
+    DEFAULT_BROWSER = "windows-default"
