diff --git a/profiles/unl_profile/unl_profile.install b/profiles/unl_profile/unl_profile.install
index f65a5cd3fd929b5c4462acdef532da5115fa4e34..f971bdb3a068ac4114fef2a03b21f38145d11334 100644
--- a/profiles/unl_profile/unl_profile.install
+++ b/profiles/unl_profile/unl_profile.install
@@ -211,7 +211,10 @@ EOF;
     // End adding custom blocks
     
     
-    
+    // Set the "Home" menu link to be expanded by default
+    $links = menu_load_links('main-menu');
+    $links[0]['expanded'] = 1;
+    menu_link_save($links[0]);
     
     
 
diff --git a/sites/all/modules/unl/cron.php b/sites/all/modules/unl/cron.php
index 956b5436ae71c26dfa14e69486970a35b7337fcd..a4e417593a42cc36bd52f246570eb4657bf31f5b 100644
--- a/sites/all/modules/unl/cron.php
+++ b/sites/all/modules/unl/cron.php
@@ -12,44 +12,125 @@ require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
 drupal_override_server_variables();
 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
 
-$query = db_query('SELECT * FROM {unl_sites} WHERE installed=0');
-while ($row = $query->fetchAssoc()) {
-  db_update('unl_sites')
-   ->fields(array('installed' => 1))
-   ->condition('site_id', $row['site_id'])
-   ->execute();
-  if (unl_add_site($row['site_path'], $row['uri'], $row['clean_url'], $row['db_prefix'], $row['site_id'])) {
+unl_remove_aliases();
+unl_remove_sites();
+unl_add_sites();
+unl_add_aliases();
+
+function unl_add_sites() {
+  $query = db_query('SELECT * FROM {unl_sites} WHERE installed=0');
+  
+  while ($row = $query->fetchAssoc()) {
     db_update('unl_sites')
-      ->fields(array('installed' => 2))
+      ->fields(array('installed' => 1))
       ->condition('site_id', $row['site_id'])
       ->execute();
+    if (unl_add_site($row['site_path'], $row['uri'], $row['clean_url'], $row['db_prefix'], $row['site_id'])) {
+      db_update('unl_sites')
+        ->fields(array('installed' => 2))
+        ->condition('site_id', $row['site_id'])
+        ->execute();
+    }
+    else {
+      db_update('unl_sites')
+        ->fields(array('installed' => 5))
+        ->condition('site_id', $row['site_id'])
+        ->execute();
+    }
   }
-  else {
+}
+
+function unl_remove_sites() {
+  $query = db_query('SELECT * FROM {unl_sites} WHERE installed=3');
+  while ($row = $query->fetchAssoc()) {
     db_update('unl_sites')
-      ->fields(array('installed' => 5))
+      ->fields(array('installed' => 4))
       ->condition('site_id', $row['site_id'])
       ->execute();
+    if (unl_remove_site($row['site_path'], $row['uri'], $row['db_prefix'], $row['site_id'])) {
+      db_delete('unl_sites')
+        ->condition('site_id', $row['site_id'])
+        ->execute();
+    }
+    else {
+      db_update('unl_sites')
+        ->fields(array('installed' => 5))
+        ->condition('site_id', $row['site_id'])
+        ->execute();
+    }
   }
 }
 
-$query = db_query('SELECT * FROM {unl_sites} WHERE installed=3');
-while ($row = $query->fetchAssoc()) {
-  db_update('unl_sites')
-    ->fields(array('installed' => 4))
-    ->condition('site_id', $row['site_id'])
-    ->execute();
-  if (unl_remove_site($row['site_path'], $row['uri'], $row['db_prefix'], $row['site_id'])) {
-    db_delete('unl_sites')
-      ->condition('site_id', $row['site_id'])
+function unl_add_aliases() {
+  $query = db_select('unl_sites_aliases', 'a');
+  $query->join('unl_sites', 's', 's.site_id = a.site_id');
+  $query->fields('s', array('uri'));
+  $query->fields('a', array('site_alias_id', 'uri'));
+  $query->condition('a.installed', 0);
+  $results = $query->execute()->fetchAll();
+  
+  foreach ($results as $row) {
+    db_update('unl_sites_aliases')
+      ->fields(array('installed' => 1))
+      ->condition('site_alias_id', $row->site_alias_id)
       ->execute();
+    if (unl_add_alias($row->uri, $row->a_uri)) {
+      db_update('unl_sites_aliases')
+        ->fields(array('installed' => 2))
+        ->condition('site_alias_id', $row->site_alias_id)
+        ->execute();
+    }
+    else {
+      db_update('unl_sites_aliases')
+        ->fields(array('installed' => 5))
+        ->condition('site_alias_id', $row->site_alias_id)
+        ->execute();
+    }
   }
-  else {
-    db_update('unl_sites')
-      ->fields(array('installed' => 5))
-      ->condition('site_id', $row['site_id'])
+}
+
+function unl_remove_aliases() {
+  $query = db_select('unl_sites_aliases', 'a');
+  $query->fields('a', array('site_alias_id', 'uri'));
+  $query->condition('a.installed', 3);
+  $results = $query->execute()->fetchAll();
+  
+  foreach ($results as $row) {
+    db_update('unl_sites_aliases')
+      ->fields(array('installed' => 4))
+      ->condition('site_alias_id', $row->site_alias_id)
       ->execute();
+    if (unl_remove_alias($row->uri)) {
+      db_delete('unl_sites_aliases')
+        ->condition('site_alias_id', $row->site_alias_id)
+        ->execute();
+    }
+    else {
+      db_update('unl_sites_aliases')
+        ->fields(array('installed' => 5))
+        ->condition('site_alias_id', $row->site_alias_id)
+        ->execute();
+    }
+  }
+}
+
+
+function _unl_get_sites_subdir($uri, $trim_subdomain = TRUE) {
+  $path_parts = parse_url($uri);
+  if ($trim_subdomain && substr($path_parts['host'], -7) == 'unl.edu') {
+    $path_parts['host'] = 'unl.edu';
+  }
+  $sites_subdir = $path_parts['host'] . $path_parts['path'];
+  $sites_subdir = strtr($sites_subdir, array('/' => '.'));
+
+  while (substr($sites_subdir, 0, 1) == '.') {
+    $sites_subdir = substr($sites_subdir, 1);
+  }
+  while (substr($sites_subdir, -1) == '.') {
+    $sites_subdir = substr($sites_subdir, 0, -1);
   }
   
+  return $sites_subdir;
 }
 
 
@@ -155,18 +236,16 @@ function unl_remove_site($site_path, $uri, $db_prefix, $site_id) {
   return TRUE;
 }
 
-function _unl_get_sites_subdir($uri) {
-  $path_parts = parse_url($uri);
-  if (substr($path_parts['host'], -7) == 'unl.edu') {
-    $path_parts['host'] = 'unl.edu';
-  }
-  $sites_subdir = $path_parts['host'] . $path_parts['path'];
-  $sites_subdir = strtr($sites_subdir, array('/' => '.')); 
-  
-  return $sites_subdir;
+function unl_add_alias($site_uri, $alias_uri) {
+  $real_config_dir = _unl_get_sites_subdir($site_uri);
+  $alias_config_dir = _unl_get_sites_subdir($alias_uri, FALSE);
+  return symlink($real_config_dir, DRUPAL_ROOT . '/sites/' . $alias_config_dir);
 }
 
-
+function unl_remove_alias($alias_uri) {
+  $alias_config_dir = _unl_get_sites_subdir($alias_uri, FALSE);
+  return unlink(DRUPAL_ROOT . '/sites/' . $alias_config_dir);
+}
 
 
 
diff --git a/sites/all/modules/unl/unl.install b/sites/all/modules/unl/unl.install
index 5ca132fe6ae1202721dab5531969436c803a835a..ca5a547999ba26bdfe8d56031756f441018d6cf0 100644
--- a/sites/all/modules/unl/unl.install
+++ b/sites/all/modules/unl/unl.install
@@ -42,7 +42,43 @@ function unl_schema() {
     'primary key' => array('site_id'),
     'unique keys' => array(
       'sub_site' => array('site_path'),
-    )
+    ),
+  );
+  
+  $schema['unl_sites_aliases'] = array(
+    'description' => 'Table of URL aliases for UNL sites.',
+    'fields' => array(
+      'site_alias_id' => array(
+        'type'     => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'site_id' => array(
+        'type'     => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'uri' => array(
+        'type'     => 'varchar',
+        'length'   => 255,
+        'not null' => TRUE,
+      ),
+      'installed' => array(
+        'type'     => 'int',
+        'not null' => TRUE,
+        'default'  => 0,
+      ),
+    ),
+    'primary key' => array('site_alias_id'),
+    'unique keys' => array(
+      'alias_uri' => array('uri'),
+    ),
+    'foreign keys' => array(
+      'aliased_site' => array(
+        'table'   => 'unl_sites',
+        'columns' => array('site_id' => 'site_id'),
+      ),
+    ),
   );
   
   return $schema;
@@ -112,3 +148,43 @@ function unl_update_7102() {
   db_query("UPDATE {unl_sites} SET site_path = CONCAT(site_path_prefix, '/', site_path) WHERE site_path_prefix != ''");
   db_drop_field('unl_sites', 'site_path_prefix');
 }
+
+function unl_update_7103() {
+  $table = array(
+    'description' => 'Table of URL aliases for UNL sites.',
+    'fields' => array(
+      'site_alias_id' => array(
+        'type'     => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'site_id' => array(
+        'type'     => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'uri' => array(
+        'type'     => 'varchar',
+        'length'   => 255,
+        'not null' => TRUE,
+      ),
+      'installed' => array(
+        'type'     => 'int',
+        'not null' => TRUE,
+        'default'  => 0,
+      ),
+    ),
+    'primary key' => array('site_alias_id'),
+    'unique keys' => array(
+      'alias_uri' => array('uri'),
+    ),
+    'foreign keys' => array(
+      'aliased_site' => array(
+        'table'   => 'unl_sites',
+        'columns' => array('site_id' => 'site_id'),
+      ),
+    ),
+  );
+  
+  db_create_table('unl_sites_aliases', $table);
+}
diff --git a/sites/all/modules/unl/unl.module b/sites/all/modules/unl/unl.module
index 6eea4d43f23ec5c6854a094e5f708fadb020abc5..6d4684f99e3be0d5f7986c065d828ae2a86a5cfc 100644
--- a/sites/all/modules/unl/unl.module
+++ b/sites/all/modules/unl/unl.module
@@ -47,6 +47,7 @@ function unl_wysiwyg_plugin($editor) {
             'skin' => 'unl',
             'table_styles' => 'ZenTable Bright (yellow)=zentable bright;ZenTable Cool (blue)=zentable cool;ZenTable Energetic (orange)=zentable energetic;ZenTable Soothing (green)=zentable soothing;ZenTable Primary (red)=zentable primary;ZenTable Neutral (gray)=zentable neutral;', 'doctype' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
           ),
+          'extended_valid_elements' => array('*[*]'),
         )
         // Wysiwyg wrapper plugin AJAX callback.
         // 'callback' => url('myplugin/browse'),
@@ -105,27 +106,25 @@ function unl_menu() {
   if (conf_path() == 'sites/default') {
     $items['admin/sites/unl'] = array(
       'title'            => 'UNL Site Creation Tool',
-      'description'      => 'Create a new UNL Drupal site',
+      'description'      => 'Create and manage UNL Drupal sites and aliases.',
       'access arguments' => array('unl site creation'),
-      'page callback'    => 'drupal_get_form',
-      'page arguments'   => array('unl_site_creation'),
+      'page callback'    => 'unl_sites_page',
       'type'             => MENU_LOCAL_TASK,
       'file'             => 'unl_site_creation.php',
     );
     
-    $items['admin/sites/unl/add'] = array(
-      'title'       => 'Add',
-      'description' => 'Determine access to features by selecting permissions for roles.',
+    $items['admin/sites/unl/sites'] = array(
+      'title'       => 'Sites',
+      'description' => 'Create and manage UNL Drupal sites.',
       'type'        => MENU_DEFAULT_LOCAL_TASK,
       'weight'      => -8,
     );
     
-    $items['admin/sites/unl/list'] = array(
-      'title'            => 'List',
-      'description'      => 'List UNL Drupal sites',
+    $items['admin/sites/unl/aliases'] = array(
+      'title'            => 'Aliases',
+      'description'      => 'Manage aliases of UNL Drupal sites.',
       'access arguments' => array('unl site creation'),
-      'page callback'    => 'drupal_get_form',
-      'page arguments'   => array('unl_site_list'),
+      'page callback'    => 'unl_aliases_page',
       'type'             => MENU_LOCAL_TASK,
       'file'             => 'unl_site_creation.php',
     );
@@ -214,6 +213,78 @@ function unl_form_alter(&$form, $form_state, $form_id) {
       }
     }
   }
+  
+  /**
+   * On the node edit form, hide the "Provide a menu link" checkbox since we'll
+   * be using the menu to build a site hierarchy.  Instead, add a button that will
+   * determine whether or not the menu link is visible or not.
+   */ 
+  if (substr($form_id, -10) == '_node_form') {
+    $form['menu']['#title'] = 'Site hierachy';
+    
+    $form['menu']['enabled']['#default_value'] = TRUE;
+    $form['menu']['enabled']['#prefix'] = '<div style="display: none;">';
+    $form['menu']['enabled']['#suffix'] = '</div>';
+    
+    $form['menu']['link']['link_title']['#required'] = TRUE;
+    
+  
+    $mlid = $form['menu']['link']['mlid']['#value'];
+    if ($mlid) {
+      $menu_link = menu_link_load($mlid);
+      $default_visible = ($menu_link['hidden'] ? 0 : 1);
+    }
+    else {
+      $default_visible = 0;
+    }
+    $form['menu']['visible'] = array(
+      '#type' => 'checkbox',
+      '#title' => 'Display in menu',
+      '#default_value' => $default_visible,
+      '#weight' => 0,
+    );
+    
+    $form['actions']['submit']['#submit'][] = 'unl_node_form_submit';
+    
+    // Also turn on revisioning by default
+    $form['revision_information']['revision']['#default_value'] = TRUE;
+    unset($form['revision_information']['revision']['#states']);
+    
+    // Also hide the "Promoted to front page" option
+    $form['options']['promote']['#prefix'] = '<div style="display:none;">';
+    $form['options']['promote']['#suffix'] = '</div>';
+    
+    // Also hide the "Sticky at top of lists" option
+    $form['options']['sticky']['#prefix'] = '<div style="display:none;">';
+    $form['options']['sticky']['#suffix'] = '</div>';
+  }
+}
+
+/**
+ * When a node is modified, update its menu link to be hidden or not based on the user input.
+ */
+function unl_node_form_submit($form, &$form_state) {
+  $menu_data = $form_state['values']['menu'];
+
+  if ($menu_data['mlid']) {
+    $menu_link = menu_link_load($menu_data['mlid']);
+  }
+  else {
+    list($parent_menu_name, $parent_mlid) = explode(':', $menu_data['parent']);
+    $menu_links = menu_load_links($parent_menu_name);
+    foreach ($menu_links as $menu_link) {
+      if ($menu_link['plid'] != $parent_mlid) {
+        continue;
+      }
+      if ($menu_link['link_path'] != 'node/' . $form_state['values']['nid']) {
+        continue;
+      }
+      break;
+    }
+  }
+  
+  $menu_link['hidden'] = $menu_data['visible'] ? 0 : 1;
+  menu_link_save($menu_link);
 }
 
 function unl_system_settings_form_submit($form, &$form_state) {
@@ -223,8 +294,11 @@ function unl_system_settings_form_submit($form, &$form_state) {
 function unl_theme() {
   return array(
     'unl_site_list_table' => array(
-      'render element' => 'form'
-    )
+      'render element' => 'form',
+    ),
+    'unl_alias_list_table' => array(
+      'render element' => 'form',
+    ),
   );
 }
 
diff --git a/sites/all/modules/unl/unl_migration.php b/sites/all/modules/unl/unl_migration.php
index b2bbc16eaa31f130d3c972b6d4a17dcfd4148f16..5b2e9c07687c0aa2e9ad7226aa7b5f1324915133 100644
--- a/sites/all/modules/unl/unl_migration.php
+++ b/sites/all/modules/unl/unl_migration.php
@@ -30,6 +30,11 @@ function unl_migration($form, &$form_state)
         '#title' => t('Frontier FTP Password'),
         '#required' => FALSE
     );
+    $form['root']['ignore_duplicates'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Ignore Duplicate Pages/Files'),
+        '#description' => t("This may be needed if your site has an unlimited number of dynamicly generated paths."),
+    );
     
     $form['submit'] = array(
         '#type' => 'submit',
@@ -45,7 +50,8 @@ function unl_migration_submit($form, &$form_state)
       $form_state['values']['site_url'],
       $form_state['values']['frontier_path'],
       $form_state['values']['frontier_user'],
-      $form_state['values']['frontier_pass']
+      $form_state['values']['frontier_pass'],
+      $form_state['values']['ignore_duplicates']
     );
     while (!$migration->migrate());
 }
@@ -78,6 +84,7 @@ class Unl_Migration_Tool
     private $_content             = array();
     private $_createdContent      = array();
     private $_lastModifications   = array();
+    private $_redirects           = array();
     private $_hrefTransform       = array();
     private $_hrefTransformFiles  = array();
     private $_menu                = array();
@@ -85,6 +92,9 @@ class Unl_Migration_Tool
     private $_pageTitles          = array();
     private $_log                 = array();
     private $_blocks              = array();
+    private $_isFrontier          = FALSE;
+    private $_frontierIndexFiles  = array('low_bandwidth.shtml', 'index.shtml', 'index.html', 'index.htm', 'default.shtml');
+    private $_ignoreDuplicates    = FALSE;
     
     /**
      * Keep track of the state of the migration progress so that we can resume later
@@ -96,20 +106,28 @@ class Unl_Migration_Tool
     const STATE_CREATING_NODES   = 3;
     const STATE_DONE             = 4;
     
-    public function __construct($baseUrl, $frontierPath, $frontierUser, $frontierPass)
+    public function __construct($baseUrl, $frontierPath, $frontierUser, $frontierPass, $ignoreDuplicates)
     {
         header('Content-type: text/plain');
 
+        // Check to see if we're migrating from frontier so we can make some extra assumptions.
+        $baseUrlParts = parse_url($baseUrl);
+        $remoteHostname = gethostbyaddr(gethostbyname($baseUrlParts['host']));
+        if ($remoteHostname == 'frontier.unl.edu') {
+            $this->_isFrontier = TRUE;
+        }
+        
         // Add trailing slash if necessary
         $baseUrl = trim($baseUrl);
         if (substr($baseUrl, -1) != '/') {
-            $baseUrl .= '/';
+            //$baseUrl .= '/';
         }
 
         $this->_frontierPath = $frontierPath;
         $this->_frontierUser = $frontierUser;
         $this->_frontierPass = $frontierPass;
-
+        
+        $this->_ignoreDuplicates = (bool) $ignoreDuplicates;
         
         $this->_baseUrl = $baseUrl;
         $this->_addSitePath('');
@@ -150,6 +168,9 @@ class Unl_Migration_Tool
                     unset($transforms['']);
                 }
                 foreach ($transforms as $oldPath => &$newPath) {
+                    if (array_key_exists($newPath, $this->_redirects)) {
+                        $newPath = $this->_redirects[$newPath];
+                    }
                     if (array_key_exists($newPath, $this->_hrefTransformFiles)) {
                         $newPath = $this->_hrefTransformFiles[$newPath];
                     }
@@ -162,7 +183,7 @@ class Unl_Migration_Tool
         if ($this->_state == self::STATE_CREATING_NODES) {
             // Update links and then create new page nodes. (Takes a while)
             foreach ($this->_content as $path => $content) {
-                if (in_array($path, $this->_createdContent)) {
+                if (in_array($path, $this->_createdContent, TRUE)) {
                     continue;
                 }
                 if (time() - $start_time > $time_limit) {
@@ -170,11 +191,9 @@ class Unl_Migration_Tool
                 }
                 set_time_limit(30);
                 
-                $hrefTransform = $this->_hrefTransform[$path];
+                $hrefTransform = isset($this->_hrefTransform[$path]) ? $this->_hrefTransform[$path] : array();
+                $content = strtr($content, $hrefTransform);
                 
-                if (is_array($hrefTransform)) {
-                    $content = strtr($content, $hrefTransform);
-                }
                 $pageTitle = $this->_pageTitles[$path];
                 $this->_createPage($pageTitle, $content, $path, '' == $path);
                 $this->_createdContent[] = $path;
@@ -223,9 +242,16 @@ class Unl_Migration_Tool
         $dom->loadHTML($html);
         $navlinksNode = $dom->getElementById('navigation');
     
+        // Check to see if there's a base tag on this page.
+        $base_tags = $dom->getElementsByTagName('base');
+        $page_base = NULL;
+        if ($base_tags->length > 0) {
+          $page_base = $base_tags->item(0)->getAttribute('href');
+        }
+        
         $linkNodes = $navlinksNode->getElementsByTagName('a');
         foreach ($linkNodes as $linkNode) {
-            $this->_processLinks($linkNode->getAttribute('href'), '');
+            $this->_processLinks($linkNode->getAttribute('href'), '', $page_base, '<menu>');
         }
         
         $navlinksUlNode = $navlinksNode->getElementsByTagName('ul')->item(0);
@@ -262,6 +288,17 @@ class Unl_Migration_Tool
 
     private function _createMenu()
     {
+        // Start off by removing the "Home" menu link if it exists.
+        $menu_links = menu_load_links('main-menu');
+        foreach ($menu_links as $menu_link) {
+          if ($menu_link['plid'] == 0 &&
+              $menu_link['link_title'] == 'Home' &&
+              $menu_link['link_path'] == '<front>') {
+            menu_link_delete($menu_link['mlid']);
+          }
+        }
+        
+        // Now recursively create each menu.
         $primaryWeights = 1;
         foreach ($this->_menu as $primaryMenu) {
             $item = array(
@@ -401,12 +438,17 @@ class Unl_Migration_Tool
         
         $pageHash = hash('md5', $data['content']);
         if (($matchingPath = array_search($pageHash, $this->_processedPageHashes)) !== FALSE) {
-            $this->_log("The file found at $fullPath was a duplicate of the file at {$this->_baseUrl}$matchingPath ! Ignoring.");
-            return;
+            $logMessage = "The file found at $fullPath was a duplicate of the file at {$this->_baseUrl}$matchingPath !";
+            if ($this->_ignoreDuplicates) {
+                $this->_log($logMessage . ' Ignoring.');
+                return;
+            } else {
+                $this->_log($logMessage);
+            }
         }
         $this->_processedPageHashes[$path] = $pageHash; 
         
-        if ($data['lastModified']) {
+        if (isset($data['lastModified'])) {
             $this->_lastModifications[$path] = $data['lastModified'];
         }
         if (strpos($data['contentType'], 'html') === FALSE) {
@@ -433,7 +475,14 @@ class Unl_Migration_Tool
         }
         
         $dom = new DOMDocument();
-        $dom->loadHTML($html);
+        @$dom->loadHTML($html);
+        
+        // Check to see if there's a base tag on this page.
+        $base_tags = $dom->getElementsByTagName('base');
+        $page_base = NULL;
+        if ($base_tags->length > 0) {
+          $page_base = $base_tags->item(0)->getAttribute('href');
+        }
         
         $pageTitle = '';
         $pageTitleNode = $dom->getElementById('pagetitle');
@@ -469,36 +518,55 @@ class Unl_Migration_Tool
         
         $linkNodes = $maincontentNode->getElementsByTagName('a');
         foreach ($linkNodes as $linkNode) {
-            $this->_processLinks($linkNode->getAttribute('href'), $path);
+            $this->_processLinks($linkNode->getAttribute('href'), $path, $page_base);
         }
     
         $linkNodes = $maincontentNode->getElementsByTagName('img');
         foreach ($linkNodes as $linkNode) {
-            $this->_processLinks($linkNode->getAttribute('src'), $path);
+            $this->_processLinks($linkNode->getAttribute('src'), $path, $page_base);
         }
         
         $this->_content[$path] = $maincontentarea;
         $this->_pageTitles[$path] = $pageTitle;
     }
     
-    private function _processLinks($originalHref, $path)
+    private function _processLinks($originalHref, $path, $page_base = NULL, $tag = NULL)
     {
         if (substr($originalHref, 0, 1) == '#') {
             return;
         }
-        $href = $this->_makeLinkAbsolute($originalHref, $path);
+        
+        if (!$page_base) {
+          $page_base = $path;
+        }
+        
+        $href = $this->_makeLinkAbsolute($originalHref, $page_base);
+        
         if (substr($href, 0, strlen($this->_baseUrl)) == $this->_baseUrl) {
             $newPath = substr($href, strlen($this->_baseUrl));
             if ($newPath === FALSE) {
                 $newPath = '';
             }
-            $this->_hrefTransform[$path][$originalHref] = $newPath;
+            if ($tag) {
+                $this->_hrefTransform[$tag][$originalHref] = $newPath;
+            } else {
+                $this->_hrefTransform[$path][$originalHref] = $newPath;
+            }
             $this->_addSitePath($newPath);
         }
     }
     
     private function _makeLinkAbsolute($href, $path)
     {
+        $path_parts = parse_url($path);
+        
+        if (isset($path_parts['scheme'])) {
+            $base_url = $path;
+            $path = '';
+        } else {
+            $base_url = $this->_baseUrl;
+        }
+        
         if (substr($path, -1) == '/') {
             $intermediatePath = $path;
         } else {
@@ -512,7 +580,7 @@ class Unl_Migration_Tool
         }
         
         $parts = parse_url($href);
-        if (isset($parts['scheme']) && $parts['scheme'] == 'mailto') {
+        if (isset($parts['scheme']) && !in_array($parts['scheme'], array('http', 'https'))) {
             return $href;
         }
         if (isset($parts['scheme'])) {
@@ -520,7 +588,7 @@ class Unl_Migration_Tool
         } else if (isset($parts['path']) && substr($parts['path'], 0, 1) == '/') {
             $baseParts = parse_url($this->_baseUrl);
             $absoluteUrl = $baseParts['scheme'] . '://' . $baseParts['host'] . $parts['path'];
-            if ($parts['fragment']) {
+            if (isset($parts['fragment'])) {
                 $absoluteUrl .= '#' . $parts['fragment'];
             }
         } else if (substr($href, 0, 1) == '#') {
@@ -555,8 +623,20 @@ class Unl_Migration_Tool
         
         $absoluteUrl = $parts['scheme'] . '://' . $parts['host'];
         $absoluteUrl .= isset($parts['path']) ? $parts['path'] : '';
+        $absoluteUrl .= isset($parts['query']) ? '?' . $parts['query'] : '';
         $absoluteUrl .= isset($parts['fragment']) ? '#'.$parts['fragment'] : '';
         
+        if (
+          $this->_isFrontier &&
+          substr($absoluteUrl, 0, strlen($this->_baseUrl)) == $this->_baseUrl &&
+          in_array(basename($parts['path']), $this->_frontierIndexFiles)
+        ) {
+            $absoluteUrl = $parts['scheme'] . '://' . $parts['host'];
+            $absoluteUrl .= isset($parts['path']) ? dirname($parts['path']) . '/' : '';
+            $absoluteUrl .= isset($parts['query']) ? '?' . $parts['query'] : '';
+            $absoluteUrl .= isset($parts['fragment']) ? '#'.$parts['fragment'] : '';
+        }
+        
         return $absoluteUrl;
     }
     
@@ -590,7 +670,7 @@ class Unl_Migration_Tool
             return;
         }
         
-        if ($this->_lastModifications[$alias]) {
+        if (isset($this->_lastModifications[$alias])) {
             $mtime = $this->_lastModifications[$alias];
             $mtimes = array(
                 'created' => $mtime,
@@ -606,6 +686,7 @@ class Unl_Migration_Tool
         
         if ($makeFrontPage) {
             variable_set('site_frontpage', 'node/' . $node->nid);
+            variable_set('site_name', $title);
         }
         
         $this->_log('Created page "' . $title . '" with node id ' . $node->nid . ' at ' . $alias . '.');
@@ -639,6 +720,13 @@ class Unl_Migration_Tool
             $location = $headers['Location'];
             $path = substr($location, strlen($this->_baseUrl));
             $this->_addSitePath($path);
+            
+            if (substr($location, 0, strlen($this->_baseUrl)) == $this->_baseUrl) {
+                $this->_redirects[substr($url, strlen($this->_baseUrl))] = substr($location, strlen($this->_baseUrl));
+            } else {
+                $this->_redirects[substr($url, strlen($this->_baseUrl))] = $location;
+            }
+            
             $this->_log('Found a redirect from ' . $url . ' to ' . $location . '. Some links may need to be updated.');
             return FALSE;
         } else if ($meta['http_code'] != 200) {
@@ -655,7 +743,7 @@ class Unl_Migration_Tool
             $mtime = $this->_getModifiedDate($url);
             if ($mtime) {
                 $data['lastModified'] = $mtime;
-            } else if ($headers['Last-Modified']) {
+            } else if (isset($headers['Last-Modified'])) {
                 $data['lastModified'] = strtotime($headers['Last-Modified']);
             }
         }
@@ -678,11 +766,24 @@ class Unl_Migration_Tool
         }
         
         $ftpPath = $this->_frontierPath . $path;
+        $ftpPaths = array();
         if (substr($ftpPath, -1) == '/') {
-            $ftpPath .= 'index.shtml';
+            foreach ($this->_frontierIndexFiles as $frontierIndexFile) {
+                $ftpPaths[] = $ftpPath . $frontierIndexFile;
+            }
+        } else {
+            $ftpPaths[] = $ftpPath;
         }
         
-        $files = ftp_rawlist($this->_frontier, $ftpPath);
+        foreach ($ftpPaths as $ftpPath) {
+            $files = ftp_rawlist($this->_frontier, $ftpPath);
+            if (isset($files[0])) {
+                break;
+            }
+        }
+        if (!isset($files[0])) {
+            return NULL;
+        }
         $mtime = substr($files[0], 43, 12);
         $mtime = strtotime($mtime);
         return $mtime;
@@ -690,7 +791,7 @@ class Unl_Migration_Tool
     
     private function _frontierConnect()
     {
-        if (!$this->_frontierPath) {
+        if (!$this->_isFrontier || !$this->_frontierPath) {
             return NULL;
         }
         
@@ -702,6 +803,7 @@ class Unl_Migration_Tool
                 $this->_frontier = NULL;
                 $this->_log('Error: could not connect to frontier with user ' . $this->_frontierUser . '.');
             }
+            ftp_pasv($this->_frontier, TRUE);
         }
         return $this->_frontier;
     }
@@ -722,8 +824,11 @@ class Unl_Migration_Tool
                 //file is a directory
                 $this->_frontierScan($path . $file . '/');
             } else {
+                if (substr($path, 0, 1) == '/') {
+                    $path = substr($path, 1);
+                }
                 $files[] = $file;
-                if ($file == 'index.shtml') {
+                if (in_array($file, $this->_frontierIndexFiles)) {
                     $this->_addSitePath($path);
                 } else {
                     $this->_addSitePath($path . $file);
diff --git a/sites/all/modules/unl/unl_site_creation.php b/sites/all/modules/unl/unl_site_creation.php
index 91986d22e142b3b389e87a5024460d8cb37eab88..3bb3319dc95be85d8178ac1e0f2c51fd63d9481d 100644
--- a/sites/all/modules/unl/unl_site_creation.php
+++ b/sites/all/modules/unl/unl_site_creation.php
@@ -2,10 +2,21 @@
 
 require_once DRUPAL_ROOT . '/includes/install.core.inc';
 
-function unl_site_creation($form, &$form_state) {
+
+
+function unl_sites_page() {
+  $page = array();
+  $page[] = drupal_get_form('unl_site_create');
+  $page[] = drupal_get_form('unl_site_list');
+  
+  return $page;
+}
+
+
+function unl_site_create($form, &$form_state) {
   $form['root'] = array(
     '#type'  => 'fieldset',
-    '#title' => 'Site Creation Tool',
+    '#title' => 'Create New Site',
   );
   
   $form['root']['site_path'] = array(
@@ -23,7 +34,7 @@ function unl_site_creation($form, &$form_state) {
     '#default_value' => 1,
   );
   
-  $form['submit'] = array(
+  $form['root']['submit'] = array(
     '#type'  => 'submit',
     '#value' => 'Create Site',
   );
@@ -31,7 +42,7 @@ function unl_site_creation($form, &$form_state) {
   return $form;
 }
 
-function unl_site_creation_validate($form, &$form_state) {
+function unl_site_create_validate($form, &$form_state) {
   $site_path = trim($form_state['values']['site_path']);
   
   if (substr($site_path, 0, 1) == '/') {
@@ -50,7 +61,7 @@ function unl_site_creation_validate($form, &$form_state) {
   $form_state['values']['site_path'] = $site_path;
 }
 
-function unl_site_creation_submit($form, &$form_state) {
+function unl_site_create_submit($form, &$form_state) {
   $site_path = $form_state['values']['site_path'];
   $clean_url = $form_state['values']['clean_url'];
   
@@ -77,8 +88,11 @@ function unl_site_creation_submit($form, &$form_state) {
 function unl_site_list($form, &$form_state) {
   $form['root'] = array(
     '#type'  => 'fieldset',
-    '#title' => 'UNL Site List',
-    '#theme' => 'unl_site_list_table'
+    '#title' => 'Existing Sites',
+  );
+  
+  $form['root']['site_list'] = array(
+    '#theme' => 'unl_site_list_table',
   );
   
   $sites = db_select('unl_sites', 's')
@@ -87,7 +101,7 @@ function unl_site_list($form, &$form_state) {
     ->fetchAll();
   
   foreach ($sites as $site) {
-    $form['root'][$site->site_id] = array(
+    $form['root']['site_list'][$site->site_id] = array(
       'site_path' => array('#value' => $site->site_path),
       'db_prefix' => array('#value' => $site->db_prefix . '_' . $GLOBALS['databases']['default']['default']['prefix']),
       'installed' => array('#value' => $site->installed),
@@ -100,12 +114,11 @@ function unl_site_list($form, &$form_state) {
     );
   }
   
-  $form['submit'] = array(
+  $form['root']['submit'] = array(
     '#type'  => 'submit',
     '#value' => 'Delete Selected Sites',
   );
   
-  //print_r($form); exit;
   return $form;
 }
 
@@ -115,32 +128,7 @@ function theme_unl_site_list_table($variables) {
   $headers = array('Site Path', 'Datbase Prefix', 'Status', 'Link', 'Remove (can not undo!)');
   $rows = array();
   foreach (element_children($form) as $key) {
-    $installed = $form[$key]['installed']['#value'];
-    switch ($installed) {
-      case 0:
-    	$installed = 'Scheduled for creation.';
-    	break;
-    	
-      case 1:
-    	$installed = 'Curently being created.';
-    	break;
-
-      case 2:
-    	$installed = 'In production.';
-    	break;
-
-      case 3:
-    	$installed = 'Scheduled for removal.';
-    	break;
-    	
-      case 4:
-    	$installed = 'Currently being removed.';
-    	break;
-    	
-      default:
-    	$installed = 'Unknown';
-    	break;
-    }
+    $installed = _unl_get_install_status_text($form[$key]['installed']['#value']);
     $rows[] = array(
       'data' => array(
         $form[$key]['site_path']['#value'],
@@ -152,7 +140,7 @@ function theme_unl_site_list_table($variables) {
     );
   }
   
-  return theme('table', array('header' => $headers, 'rows' => $rows, 'caption' => $form['#title']));
+  return theme('table', array('header' => $headers, 'rows' => $rows));
 }
 
 function unl_site_list_submit($form, &$form_state) {
@@ -167,6 +155,7 @@ function unl_site_list_submit($form, &$form_state) {
   }
 }
 
+
 function unl_site_remove($site_id) {
   $uri = db_select('unl_sites', 's')
     ->fields('s', array('uri'))
@@ -202,6 +191,10 @@ function unl_site_remove($site_id) {
     ->fields(array('installed' => 3))
     ->condition('site_id', $site_id)
     ->execute();
+  db_update('unl_sites_aliases')
+    ->fields(array('installed' => 3))
+    ->condition('site_id', $site_id)
+    ->execute();
   drupal_set_message('The site has been scheduled for removal.');
 }
 
@@ -218,12 +211,163 @@ function _unl_get_sites_subdir($uri) {
 
 
 
+function unl_aliases_page() {
+  $page = array();
+  $page[] = drupal_get_form('unl_alias_create');
+  $page[] = drupal_get_form('unl_alias_list');
+  
+  return $page;
+}
 
 
+function unl_alias_create($form, &$form_state) {
+  
+  $sites = db_select('unl_sites', 's')
+    ->fields('s', array('site_id', 'uri'))
+    ->execute()
+    ->fetchAll();
+  foreach ($sites as $site) {
+    $site_list[$site->site_id] = $site->uri . '/';
+  }
+  
+  $form['root'] = array(
+    '#type'  => 'fieldset',
+    '#title' => 'Create New Alias',
+  );
+  
+  $form['root']['site'] = array(
+    '#type' => 'select',
+    '#title' => 'Aliased Site',
+    '#description' => 'The site the alias will point to.',
+    '#options' => $site_list,
+    '#required' => TRUE,
+  );
+    
+  $form['root']['alias_uri'] = array(
+    '#type'          => 'textfield',
+    '#title'         => t('Alias URL'),
+    '#description'   => t('Full URL for the new alias.'),
+    '#default_value' => t('http://newsite.example.com/'),
+    '#required'      => TRUE,
+  );
+  
+  $form['root']['submit'] = array(
+    '#type'  => 'submit',
+    '#value' => 'Create Alias',
+  );
+  
+  return $form;
+}
 
+function unl_alias_create_submit($form, &$form_state) {
+  db_insert('unl_sites_aliases')->fields(array(
+    'site_id' => $form_state['values']['site'],
+    'uri'     => $form_state['values']['alias_uri'],
+  ))->execute();
+}
 
 
+function unl_alias_list($form, &$form_state) {
+  $query = db_select('unl_sites_aliases', 'a');
+  $query->join('unl_sites', 's', 's.site_id = a.site_id');
+  $query->fields('s', array('uri'));
+  $query->fields('a', array('site_alias_id', 'uri', 'installed'));
+  $sites = $query->execute()->fetchAll();
 
+  $form['root'] = array(
+    '#type'  => 'fieldset',
+    '#title' => 'Existing Aliases',
+  );
+  
+  $form['root']['alias_list'] = array(
+    '#theme' => 'unl_alias_list_table',
+  );
+  
+  foreach ($sites as $site) {
+    $form['root']['alias_list'][$site->site_alias_id] = array(
+      'site_uri' => array('#value' => $site->uri),
+      'alias_uri' => array('#value' => $site->a_uri),
+      'installed' => array('#value' => $site->installed),
+      'remove'    => array(
+        '#type'          => 'checkbox',
+        '#parents'       => array('aliases', $site->site_alias_id, 'remove'),
+      	'#default_value' => 0
+      ),
+    );
+  }
+  
+  $form['root']['submit'] = array(
+    '#type'  => 'submit',
+    '#value' => 'Delete Selected Aliases',
+  );
+  
+  return $form;
+}
+
+function theme_unl_alias_list_table($variables) {
+  $form = $variables['form'];
+  
+  $headers = array('Site URI', 'Alias URI', 'Status', 'Remove (can not undo!)');
+  $rows = array();
+  foreach (element_children($form) as $key) {
+    $installed = _unl_get_install_status_text($form[$key]['installed']['#value']);
+    $rows[] = array(
+      'data' => array(
+        $form[$key]['site_uri']['#value'],
+        $form[$key]['alias_uri']['#value'],
+        $installed,
+        drupal_render($form[$key]['remove']),
+      )
+    );
+  }
+  
+  return theme('table', array('header' => $headers, 'rows' => $rows));
+}
+
+function unl_alias_list_submit($form, &$form_state) {
+  $site_alias_ids = array();
+  foreach ($form_state['values']['aliases'] as $site_alias_id => $alias) {
+    if ($alias['remove']) {
+      $site_alias_ids[] = $site_alias_id;
+    }
+  }
+  
+  db_update('unl_sites_aliases')
+    ->fields(array('installed' => 3))
+    ->condition('site_alias_id', $site_alias_ids, 'IN')
+    ->execute();
+}
+
+
+function _unl_get_install_status_text($id) {
+  switch ($id) {
+    case 0:
+  	$installed = 'Scheduled for creation.';
+  	break;
+  	
+    case 1:
+  	$installed = 'Curently being created.';
+  	break;
+
+  	case 2:
+  	  $installed = 'In production.';
+  	  break;
+
+    case 3:
+      $installed = 'Scheduled for removal.';
+      break;
+    	
+    case 4:
+      $installed = 'Currently being removed.';
+      break;
+
+    default:
+      $installed = 'Unknown';
+      break;
+  }
+
+  return $installed;
+}
 
 
 
diff --git a/sites/all/themes/unl_wdn/html.tpl.php b/sites/all/themes/unl_wdn/html.tpl.php
index caccfa53dddefd6139a2e002dae2b2bc9edee38a..6a19b76377574f242aed8d171f811bd5ed554db5 100644
--- a/sites/all/themes/unl_wdn/html.tpl.php
+++ b/sites/all/themes/unl_wdn/html.tpl.php
@@ -39,7 +39,8 @@ $t->head .= PHP_EOL
           . $styles . PHP_EOL
           . $scripts . PHP_EOL
           . '<link href="' . url('<front>', array('absolute' => TRUE)) . '" rel="home" />' . PHP_EOL
-          . '<link rel="logout" href="user/logout" title="Log out of myapp" />' . PHP_EOL
+          . '<link rel="logout" href="user/logout" />' . PHP_EOL
+          . '<link rel="login" href="user" />' . PHP_EOL
           . theme_get_setting('head_html') . PHP_EOL
           ;
 
diff --git a/sites/all/themes/unl_wdn/theme.js b/sites/all/themes/unl_wdn/theme.js
new file mode 100644
index 0000000000000000000000000000000000000000..3e5cae46e96267ad859e0d265728c093857404d2
--- /dev/null
+++ b/sites/all/themes/unl_wdn/theme.js
@@ -0,0 +1,24 @@
+WDN.jQuery(document).ready(function () {
+	// if there's no base tag on the page, we don't have to worry about this
+	if (WDN.jQuery('base').length == 0) {
+		return;
+	}
+	WDN.jQuery('a').click(function(e){
+		// if this link has a hash tag
+	    if (this.href.split('#')[1] == '') {
+	        return;
+	    }
+	    // and it is specifically for this page
+	    if (this.getAttribute('href').split('#')[0] != '') {
+	    	return;
+	    }
+	    // and something else hasn't already customized the link
+	    if (e.isDefaultPrevented()) {
+	    	return;
+	    }
+	    
+	    // fix clicking the link so that it ignores the base tag
+	    e.preventDefault();
+	    document.location.hash = this.href.split('#')[1];
+	});
+});
\ No newline at end of file
diff --git a/sites/all/themes/unl_wdn/unl_wdn.info b/sites/all/themes/unl_wdn/unl_wdn.info
index 591390930e491a963bfa84896665a39b30dc4175..4354e7f27c8f521ef10016f97ab76976e5ed6cf2 100644
--- a/sites/all/themes/unl_wdn/unl_wdn.info
+++ b/sites/all/themes/unl_wdn/unl_wdn.info
@@ -6,6 +6,8 @@ engine = phptemplate
 
 stylesheets[all][] = style.css
 
+scripts[] = theme.js
+
 features[] = main_menu
 features[] = name
 features[] = node_user_picture