diff --git a/TODO b/TODO
new file mode 100644
index 0000000000000000000000000000000000000000..9fde8c743bb8754c07ed799b680dda003fb798b3
--- /dev/null
+++ b/TODO
@@ -0,0 +1,2 @@
+- Split out affinely mapped groups
+- p refinement
diff --git a/doc/mesh.rst b/doc/mesh.rst
index f26417047ea7ca1bfcfc3637df566fbe432a14a0..28a332cf5186b7b95e91baff1d336d545ee47f88 100644
--- a/doc/mesh.rst
+++ b/doc/mesh.rst
@@ -1,3 +1,8 @@
+Common infrastructure
+=====================
+
+.. automodule:: meshmode
+
 Mesh management
 ===============
 
diff --git a/doc/upload-docs.sh b/doc/upload-docs.sh
new file mode 100755
index 0000000000000000000000000000000000000000..25c97f52894584dfd72f3955c20026f475136e39
--- /dev/null
+++ b/doc/upload-docs.sh
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+rsync --progress --verbose --archive --delete _build/html/* doc-upload:doc/meshmode
diff --git a/meshmode/__init__.py b/meshmode/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e1a4c5e6aedbffd76ceed3f426ee347380d13cce 100644
--- a/meshmode/__init__.py
+++ b/meshmode/__init__.py
@@ -0,0 +1,37 @@
+from __future__ import division
+
+__copyright__ = "Copyright (C) 2014 Andreas Kloeckner"
+
+__license__ = """
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+"""
+
+
+__doc__ = """
+.. exception:: Error
+.. exception:: ConnectivityUnavailable
+"""
+
+
+class Error(RuntimeError):
+    pass
+
+
+class ConnectivityUnavailable(Error):
+    pass
diff --git a/meshmode/discretization/poly_element.py b/meshmode/discretization/poly_element.py
index bc2ff4baa1554a0681aa06ac816dc2c05cb347e0..d59346691c93f7e967a1174b0a4622fdfff05426 100644
--- a/meshmode/discretization/poly_element.py
+++ b/meshmode/discretization/poly_element.py
@@ -35,21 +35,16 @@ __doc__ = """
 Group types
 ^^^^^^^^^^^
 
-.. autclass:: InterpolatoryQuadratureSimplexElementGroup
+.. autoclass:: InterpolatoryQuadratureSimplexElementGroup
 .. autoclass:: QuadratureSimplexElementGroup
 .. autoclass:: PolynomialWarpAndBlendElementGroup
 
 Group factories
 ^^^^^^^^^^^^^^^
 
-.. autclass:: InterpolatoryQuadratureSimplexGroupFactory
+.. autoclass:: InterpolatoryQuadratureSimplexGroupFactory
 .. autoclass:: QuadratureSimplexGroupFactory
 .. autoclass:: PolynomialWarpAndBlendGroupFactory
-
-Discretization class
-^^^^^^^^^^^^^^^^^^^^
-
-.. autoclass:: PolynomialElementDiscretization
 """
 
 # FIXME Most of the loopy kernels will break as soon as we start using multiple
diff --git a/meshmode/mesh/__init__.py b/meshmode/mesh/__init__.py
index ef8e31410fbaf3d8839f620ee3b5998610f00700..f17d1123d9d02cff7ee756cb24184d1f7f6ee9d0 100644
--- a/meshmode/mesh/__init__.py
+++ b/meshmode/mesh/__init__.py
@@ -27,6 +27,20 @@ import modepy as mp
 #import numpy.linalg as la
 from pytools import Record
 
+__doc__ = """
+
+.. autoclass:: MeshElementGroup
+    :members:
+    :undoc-members:
+
+.. autoclass:: Mesh
+    :members:
+    :undoc-members:
+
+.. autoclass:: ElementConnectivity
+
+"""
+
 
 # {{{ element group
 
diff --git a/meshmode/mesh/io.py b/meshmode/mesh/io.py
index 0f5473800bea44a649507b0ebc7d1d0b33ae3bf8..bdfbf2882cd4df8985d114001743ebe01d354e6b 100644
--- a/meshmode/mesh/io.py
+++ b/meshmode/mesh/io.py
@@ -188,7 +188,7 @@ def read_gmsh(filename, force_ambient_dim=None):
 
 def generate_gmsh(source, dimensions, order=None, other_options=[],
         extension="geo", gmsh_executable="gmsh", force_ambient_dim=None):
-    """Run :cmd:`gmsh` on the input given by *source*, and return a
+    """Run :command:`gmsh` on the input given by *source*, and return a
     :class:`meshmode.mesh.Mesh` based on the result.
 
     :arg source: an instance of either :class:`FileSource` or