diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py
new file mode 100644
index 0000000..5a4a80f
--- /dev/null
+++ b/Lib/webbrowser.py
@@ -0,0 +1,229 @@
+"""Remote-control interfaces to some browsers."""
+
+import os
+import sys
+
+
+PROCESS_CREATION_DELAY = 4
+
+
+class Error(Exception):
+    pass
+
+
+_browsers = {}
+
+def register(name, klass, instance=None):
+    """Register a browser connector and, optionally, connection."""
+    _browsers[name.lower()] = [klass, instance]
+
+
+def get(name=None):
+    """Retrieve a connection to a browser by type name, or the default
+    browser."""
+    name = name or DEFAULT_BROWSER
+    try:
+        L = _browsers[name.lower()]
+    except KeyError:
+        raise ValueError, "unknown browser type: " + `name`
+    if L[1] is None:
+        L[1] = L[0]()
+    return L[1]
+
+
+# Please note: the following definition hides a builtin function.
+
+def open(url, new=0):
+    get().open(url, new)
+
+
+def open_new(url):
+    get().open_new(url)
+
+
+def _iscommand(cmd):
+    """Return true if cmd can be found on the executable search path."""
+    path = os.environ.get("PATH")
+    if not path:
+        return 0
+    for d in path.split(os.pathsep):
+        exe = os.path.join(d, cmd)
+        if os.path.isfile(exe):
+            return 1
+    return 0
+
+
+class CommandLineBrowser:
+    _browsers = []
+    if os.environ.get("DISPLAY"):
+        _browsers.extend([
+            ("netscape", "netscape %s >/dev/null &"),
+            ("mosaic", "mosaic %s >/dev/null &"),
+            ])
+    _browsers.extend([
+        ("lynx", "lynx %s"),
+        ("w3m", "w3m %s"),
+        ])
+
+    def open(self, url, new=0):
+        for exe, cmd in self._browsers:
+            if _iscommand(exe):
+                os.system(cmd % url)
+                return
+        raise Error("could not locate runnable browser")
+
+    def open_new(self, url):
+        self.open(url)
+
+register("command-line", CommandLineBrowser)
+
+
+class Netscape:
+    autoRaise = 1
+
+    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 Konquerer:
+    """Controller for the KDE File Manager (kfm, or Konquerer).
+
+    See http://developer.kde.org/documentation/other/kfmclient.html
+    for more information on the Konquerer remote-control interface.
+
+    """
+    def _remote(self, action):
+        cmd = "kfmclient %s >/dev/null 2>&1" % action
+        rc = os.system(cmd)
+        if rc:
+            import time
+            os.system("kfm -d &")
+            time.sleep(PROCESS_CREATION_DELAY)
+            rc = os.system(cmd)
+        return not rc
+
+    def open(self, url, new=1):
+	# XXX currently I know no way to prevent KFM from opening a new win.
+        self.open_new(url)
+
+    def open_new(self, url):
+        self._remote("openURL %s" % url)
+
+register("kfm", Konquerer)
+
+
+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
+        win32api.ShellExecute(0, "open", url, None, ".",
+                              win32con.SW_SHOWNORMAL)
+
+    def open_new(self, url):
+        self.open(url)
+
+
+DEFAULT_BROWSER = "command-line"
+
+if sys.platform[:3] == "win":
+    del _browsers["kfm"]
+    register("windows-default", WindowsDefault)
+    DEFAULT_BROWSER = "windows-default"
+elif os.environ.get("DISPLAY"):
+    if os.environ.get("KDEDIR"):
+        DEFAULT_BROWSER = "kfm"
+    elif _iscommand("netscape"):
+        DEFAULT_BROWSER = "netscape"
+
+# If the $BROWSER environment variable is set and true, let that be
+# the name of the browser to use:
+#
+DEFAULT_BROWSER = os.environ.get("BROWSER") or DEFAULT_BROWSER
+
+
+# Now try to support the MacOS world.  This is the only supported
+# controller on that platform, so don't mess with the default!
+
+try:
+    import ic
+except ImportError:
+    pass
+else:
+    class InternetConfig:
+        def open(self, url, new=0):
+            ic.launcurl(url)
+
+        def open_new(self, url):
+            self.open(url)
+
+    _browsers.clear()
+    register("internet-config", InternetConfig)
+    DEFAULT_BROWSER = "internet-config"
