diff --git a/core/config.class.php b/core/config.class.php
index 155d7dda..1295da6a 100644
--- a/core/config.class.php
+++ b/core/config.class.php
@@ -3,22 +3,49 @@
  * an abstract interface for altering a name:value pair list
  */
 interface Config {
+	/**
+	 * Save the list of name:value pairs to wherever they came from,
+	 * so that the next time a page is loaded it will use the new
+	 * configuration
+	 */
 	public function save($name=null);
 
+	/** @name set_*
+	 * Set a configuration option to a new value, regardless
+	 * of what the value is at the moment
+	 */
+	//@{
 	public function set_int($name, $value);
 	public function set_string($name, $value);
 	public function set_bool($name, $value);
 	public function set_array($name, $value);
+	//@}
 
+	/** @name set_default_*
+	 * Set a configuration option to a new value, if there is no
+	 * value currently. Extensions should generally call these
+	 * from their InitExtEvent handlers. This has the advantage
+	 * that the values will show up in the "advanced" setup page
+	 * where they can be modified, while calling get_* with a
+	 * "default" paramater won't show up.
+	 */
+	//@{
 	public function set_default_int($name, $value);
 	public function set_default_string($name, $value);
 	public function set_default_bool($name, $value);
 	public function set_default_array($name, $value);
+	//@}
 
+	/** @name get_*
+	 * pick a value out of the table by name, cast to the
+	 * appropritate data type
+	 */
+	//@{
 	public function get_int($name, $default=null);
 	public function get_string($name, $default=null);
 	public function get_bool($name, $default=null);
 	public function get_array($name, $default=array());
+	//@}
 }
 
 
diff --git a/core/extension.class.php b/core/extension.class.php
index 2ad96945..d67a7473 100644
--- a/core/extension.class.php
+++ b/core/extension.class.php
@@ -41,10 +41,10 @@
  * }
  *
  * // ext/hello/test.php
- * public class HelloTest extends ShimmieWebTestCase {
+ * public class HelloTest extends SCoreWebTestCase {
  *     public void testHello() {
  *         $this->get_page("post/list");
- *         $this->assertText("Hello there");
+ *         $this->assert_text("Hello there");
  *     }
  * }
  *
diff --git a/core/page.class.php b/core/page.class.php
index 287b1769..72275559 100644
--- a/core/page.class.php
+++ b/core/page.class.php
@@ -9,9 +9,9 @@
  * extends SetupTheme and overrides some of its methods.
  * 
  * Generally an extension should only deal with processing data; whenever it
- * wants to display something, it should pass the $page data structure along
- * with the data to be displayed to the theme object, and the theme will add
- * the data into the page.
+ * wants to display something, it should pass the data to be displayed to the
+ * theme object, and the theme will add the data into the global $page
+ * structure.
  *
  * A page should make sure that all the data it outputs is free from dangerous
  * data by using html_escape(), url_escape(), or int_escape() as appropriate.
@@ -34,11 +34,15 @@
  * then Layout turns it into HTML
  */
 class Page {
+	/** @name Overall */
+	//@{
+	/** @private */
 	var $mode = "page";
+	/** @private */
 	var $type = "text/html";
 
 	/**
-	 * Set what this page should do; page, data, or redirect.
+	 * Set what this page should do; "page", "data", or "redirect".
 	 */
 	public function set_mode($mode) {
 		$this->mode = $mode;
@@ -52,73 +56,85 @@ class Page {
 	}
 
 
+	//@}
 	// ==============================================
+	/** @name "data" mode */
+	//@{
 
-	// data
+	/** @private */
 	var $data = "";
+	/** @private */
 	var $filename = null;
 
 	/**
-	 * If the page is in "data" mode, this will set the data to be sent
+	 * Set the raw data to be sent
 	 */
 	public function set_data($data) {
 		$this->data = $data;
 	}
 
 	/**
-	 * If the page is in "data" mode, this will set the recommended download filename
+	 * Set the recommended download filename
 	 */
 	public function set_filename($filename) {
 		$this->filename = $filename;
 	}
 
 
+	//@}
 	// ==============================================
+	/** @name "redirect" mode */
+	//@{
 
-	// redirect
+	/** @private */
 	var $redirect = "";
 
 	/**
-	 * If the page is in "redirect" mode, this will set where to redirect to
+	 * Set the URL to redirect to (remember to use make_link() if linking
+	 * to a page in the same site)
 	 */
 	public function set_redirect($redirect) {
 		$this->redirect = $redirect;
 	}
 
 
+	//@}
 	// ==============================================
+	/** @name "page" mode */
+	//@{
 
-	// page
+	/** @privatesection */
 	var $title = "";
 	var $heading = "";
 	var $subheading = "";
 	var $quicknav = "";
 	var $headers = array();
 	var $blocks = array();
+	/** @publicsection */
 
 	/**
-	 * If the page is in "page" mode, set the window title
+	 * Set the window title
 	 */
 	public function set_title($title) {
 		$this->title = $title;
 	}
 
 	/**
-	 * If the page is in "page" mode, set the main heading
+	 * Set the main heading
 	 */
 	public function set_heading($heading) {
 		$this->heading = $heading;
 	}
 
 	/**
-	 * If the page is in "page" mode, set the sub heading
+	 * Set the sub heading
 	 */
 	public function set_subheading($subheading) {
 		$this->subheading = $subheading;
 	}
 
 	/**
-	 * If the page is in "page" mode, add a line to the HTML head section
+	 * Add a line to the HTML head section
 	 */
 	public function add_header($line, $position=50) {
 		while(isset($this->headers[$position])) $position++;
@@ -126,16 +142,18 @@ class Page {
 	}
 
 	/**
-	 * If the page is in "page" mode, add a block of data
+	 * Add a Block of data
 	 */
-	public function add_block($block) {
+	public function add_block(Block $block) {
 		$this->blocks[] = $block;
 	}
 
+
+	//@}
 	// ==============================================
 
 	/**
-	 * display the page according to the mode and data given
+	 * Display the page according to the mode and data given
 	 */
 	public function display() {
 		global $page;
diff --git a/core/user.class.php b/core/user.class.php
index 37fba8f6..5e412cf4 100644
--- a/core/user.class.php
+++ b/core/user.class.php
@@ -10,9 +10,6 @@ function _new_user($row) {
  * The currently logged in user will always be accessable via the global variable $user
  */
 class User {
-	var $config;
-	var $database;
-
 	var $id;
 	var $name;
 	var $email;
@@ -95,6 +92,16 @@ class User {
 		return ($this->id == $config->get_int('anon_id'));
 	}
 
+	/**
+	 * Test if this user is logged in
+	 *
+	 * @retval bool
+	 */
+	public function is_logged_in() {
+		global $config;
+		return ($this->id != $config->get_int('anon_id'));
+	}
+
 	/**
 	 * Test if this user is an administrator
 	 *
diff --git a/core/util.inc.php b/core/util.inc.php
index 8f714782..c36bc29f 100644
--- a/core/util.inc.php
+++ b/core/util.inc.php
@@ -156,7 +156,9 @@ function undb_bool($val) {
 
 /**
  * Figure out the correct way to link to a page, taking into account
- * things like the nice URLs setting
+ * things like the nice URLs setting.
+ *
+ * eg make_link("post/list") becomes "/v2/index.php?q=post/list"
  *
  * @retval string
  */