Index: setup.py
===================================================================
--- setup.py	(revision 2750)
+++ setup.py	(working copy)
@@ -5,7 +5,7 @@
 import sys
 import string
 from glob import glob
-from distutils.core import setup
+from setuptools import setup
 from distutils.command.install import install
 from distutils.command.install_data import install_data
 from distutils.command.install_scripts import install_scripts
@@ -234,6 +234,10 @@
                _p('scripts/tracdb2env'),
                _p('cgi-bin/trac.cgi'),
                _p('cgi-bin/trac.fcgi')],
+      entry_points="""
+      [paste.app_factory]
+      main = trac.web.main:paste_app_factory
+      """,
       cmdclass = {'install': my_install,
                   'install_scripts': my_install_scripts,
                   'install_data': my_install_data})
Index: trac/web/main.py
===================================================================
--- trac/web/main.py	(revision 2750)
+++ trac/web/main.py	(working copy)
@@ -299,8 +299,8 @@
             req.hdf[key] = val
 
     if parent_dir and not env_paths:
-        env_paths = [os.path.join(parent_dir, filename) for filename
-                     in os.listdir(parent_dir)]
+        env_paths = dict([(filename, os.path.join(parent_dir, filename)) for filename
+                          in os.listdir(parent_dir)])
 
     projects = []
     for env_name, env_path in env_paths.items():
@@ -314,7 +314,7 @@
                 'href': req.href(env_name)
             }
         except Exception, e:
-            proj = {'name': project, 'description': str(e)}
+            project = {'name': env_name, 'description': str(e)}
         projects.append(project)
     projects.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))
 
@@ -323,3 +323,36 @@
         req.display(template)
     except RequestDone:
         pass
+
+
+def check_env_path(name, path):
+    if path is None:
+        return
+    path = os.path.normpath(path)
+    if os.path.abspath(path) != path:
+        raise ValueError, (
+            "%s must be an absolute directory (use %%(here)s "
+            "to make it relative to the config file): %r" %
+            (name, path))
+    if not os.path.exists(path):
+        raise ValueError, (
+            "%s does not exist: %r" % (name, path))
+
+def paste_app_factory(global_conf, path=None,
+                      paths=None, parent_dir=None):
+    check_env_path('path', path)
+    # XXX: I'm not sure how to handle paths/aka env_paths
+    assert paths is None
+    check_env_path('parent_dir', parent_dir)
+    if not path and not paths and not parent_dir:
+        raise ValueError, (
+            "You must provide one of path, paths, or parent_dir")
+    def application(environ, start_response):
+        if path is not None:
+            environ['trac.env_path'] = path
+        if paths:
+            environ['trac.env_paths'] = paths
+        if parent_dir:
+            environ['trac.env_parent_dir'] = parent_dir
+        return dispatch_request(environ, start_response)
+    return application
Index: doc/sample_deploy.ini
===================================================================
--- doc/sample_deploy.ini	(revision 0)
+++ doc/sample_deploy.ini	(revision 0)
@@ -0,0 +1,19 @@
+[app:trac]
+use = egg:trac
+# Use path or parent_dir to configure Trac
+#path = %(here)s/testproj/
+parent_dir = %(here)s
+
+[filter-app:main]
+# Using this section (#main) will check all responses for WSGI 
+# correctness
+use = egg:Paste#lint
+next = trac
+
+[server:main]
+# I personally am getting weird behavior with this server,
+# but wsgiutils is working fine.
+#use = egg:Paste#http
+use = egg:PasteScript#wsgiutils
+host = 127.0.0.1
+port = 9900

