diff --git a/ajax.php b/ajax.php
new file mode 100644
--- /dev/null
+++ b/ajax.php
@@ -0,0 +1,102 @@
+
+ *
+ * This file is a part of slate_permutate.
+ *
+ * slate_permutate is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * slate_permutate is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with slate_permutate.  If not, see .
+ */
+
+/**
+ * \file
+ *   This file is an endpoint for generic AJAX requests (as opposed to
+ *   autocompletion of course names).
+ */
+
+require_once('inc/school.inc');
+require_once('inc/class.page.php');
+require_once('inc/class.course.inc');
+
+page::session_start();
+
+/* should the following block of code be moved into a proposed Page::json()? */
+if (isset($_REQUEST['txt'])) {
+  header('Content-Type: text/plain; encoding=utf-8');
+}
+else {
+  header('Content-Type: application/json; encoding=utf-8');
+}
+
+/**
+ * \brief
+ *   Wrap an error message up in JSON and send it.
+ *
+ * \param $message
+ *   A valid XHTML fragment which will be wrapped in 
+ */
+function slate_permutate_json_error($message)
+{
+  echo json_encode(array('success' => FALSE, 'message' => '' . $message . '
'));
+  exit;
+}
+
+/**
+ * \brief
+ *   Send a successful JSON response.
+ *
+ * \param $data
+ *   A PHP array to be encoded with json_encode() and sent as
+ *   obj.data.
+ */
+function slate_permutate_json_success(array $data = array())
+{
+  echo json_encode(array('success' => TRUE, 'data' => $data));
+  exit;
+}
+
+if (isset($_REQUEST['school_registration_html']))
+  {
+    if (!empty($_REQUEST['school']))
+      $school = school_load($_REQUEST['school']);
+    if (empty($school))
+      {
+	$school = school_load_guess();
+	if (empty($school))
+	  slate_permutate_json_error('Unable to load any school.');
+      }
+
+    $page = new Page('', array(), FALSE);
+
+    $courses = array();
+    if (!empty($_REQUEST['courses']) && is_array($_REQUEST['courses']))
+      {
+	/*
+	 * The below course deserialization blob should be moved into
+	 * the Course object.
+	 */
+	foreach ($_REQUEST['courses'] as $course_json)
+	  {
+	    $course = Course::from_json_array($course_json);
+	    if (!empty($course))
+	      $courses[] = $course;
+	  }
+      }
+
+    $html = school_registration_html($page, $school, $courses);
+    if (empty($html))
+      slate_permutate_json_error('School\'s registration information producer returned no data.');
+    slate_permutate_json_success(array('html' => $html));
+  }
+
+slate_permutate_json_error('Unrecognized command.');
diff --git a/inc/class.course.inc b/inc/class.course.inc
--- a/inc/class.course.inc
+++ b/inc/class.course.inc
@@ -26,7 +26,7 @@
 
 include_once 'class.section.php';
 
-class Course
+class Course implements IteratorAggregate
 {
   private $name;	// String
   private $sections;	// Array of sections
@@ -65,6 +65,15 @@ class Course
 
   /**
    * \brief
+   *   Required function to implement the IteratorAggregate interface.
+   */
+  public function getIterator()
+  {
+    return new ArrayIterator($this->sections);
+  }
+
+  /**
+   * \brief
    *    Returns the number of sections in the class.
    */
   function getnsections()
@@ -202,6 +211,30 @@ class Course
 
   /**
    * \brief
+   *   Produce a Course object based on a JSON array compatible with
+   *   the output of Course::to_json_array().
+   *
+   * \param $json
+   *   The JSON array to parse.
+   * \return
+   *   A Course.
+   */
+  public static function from_json_array($json)
+  {
+    $course = new Course($json['class']);
+
+    if (!empty($json['sections']))
+      $course->section_add(Section::from_json_arrays($json['sections']));
+    
+    if (!empty($json['dependencies']))
+      foreach ($json['dependencies'] as $dependency)
+	$course->dependency_add(Course::from_json_array($dependency));
+
+    return $course;
+  }
+
+  /**
+   * \brief
    *   Upgrade a course class to a newer version of that class.
    */
   public function __wakeup()
diff --git a/inc/class.schedule.php b/inc/class.schedule.php
--- a/inc/class.schedule.php
+++ b/inc/class.schedule.php
@@ -405,7 +405,7 @@ class Schedule
 	if ($sort_time)
 	  sort($time);
 
-        echo 'Enter these codes into your school\'s online course registration system to register for classes:
 ';
+        echo '';
 	echo '