diff --git a/ad.install b/ad.install
index d32d963..0727438 100644
--- a/ad.install
+++ b/ad.install
@@ -47,13 +47,6 @@ function ad_schema() {
         'default' => '',
         'description' => 'Ad type',
       ),
-      'redirect' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Ad redirect URL',
-      ),
       'autoactivate' => array(
         'type' => 'int',
         'not null' => TRUE,
@@ -483,3 +476,12 @@ function ad_update_6008() {
   $ret[] = update_sql("UPDATE {blocks} SET cache = ". BLOCK_CACHE_PER_PAGE ." WHERE module = 'ad'");
   return $ret;
 }
+
+/** 
+ * Drop unnecessary 'redirect' column 
+ */
+function ad_update_6009() {
+	$ret = array();
+	db_drop_field($ret, 'ads', 'redirect');
+	return $ret;
+}
diff --git a/ad.module b/ad.module
index 0850a24..0f96806 100644
--- a/ad.module
+++ b/ad.module
@@ -75,6 +75,7 @@ function ad_theme() {
  */
 function ad($group = FALSE, $quantity = 1, $options = array()) {
   global $base_url;
+  global $base_path;
 
   $adserve = variable_get('adserve', '');
   $adserveinc = variable_get('adserveinc', '');
@@ -84,6 +85,14 @@ function ad($group = FALSE, $quantity = 1, $options = array()) {
     $adserve = variable_get('adserve', '');
     $adserveinc = variable_get('adserveinc', '');
   }
+
+  // Update the base path.  This could be cleared when caches are cleared.
+  // It's used by serve.php to get the proper site base path, instead of serve.php's base path.
+  $ad_base_path = variable_get('ad_base_path','');
+  if (empty($ad_base_path)) {
+     variable_set('ad_base_path', $base_path);
+     dpm("Updated ad_base_path to $base_path");
+  }
   if (!file_exists($adserve) || !file_exists($adserveinc)) {
     drupal_set_message(t('Ads cannot be displayed.  The ad module is <a href="@misconfigured">misconfigured</a>, failed to locate the required <em>serve.php</em> ond/or <em>adserve.inc</em> file.', array('@misconfigured' => url('admin/content/ad/configure'))), 'error');
     _ad_check_installation();
@@ -261,6 +270,46 @@ function ad_redirect($aid, $group = NULL) {
 }
 
 /**
+ * AD API Helper
+ * ad_l() : like l(), but for ads.  This function uses the site's
+ * base path even when the request goes to sites/all/modules/ad/serve.php
+ * which would otherwise add 'sites/all/modules/ad' to the $base_path;
+ * 
+ */
+function ad_l($text, $ad, $options){
+	return l($text, ad_link_url($ad), $options);
+}
+
+/**
+ * AD API Helper
+ * ad_link_url(): Create the full URL for a redirect based on the ad node.
+ */
+function ad_link_url($node) {
+	global $base_root;
+	$ad_base_path = variable_get('ad_base_path', '/');
+
+/*	_debug_echo("ad path components: >>$base_root<< >>$ad_base_path<<");
+	_debug_echo("ad_l Path: $path");	
+*/
+	return $base_root.$ad_base_path.ad_link_path($node);
+}
+
+/**
+ * Ad API Helper Function:
+ * Create the redirect path for this ad suitable for passing to url() or l().
+ */
+function ad_link_path($node) {
+	if (!is_object($node)) {
+		dpr("ad_link_path");
+		dvr($node);
+		dpr(debug_backtrace());
+		return "ad/redirect/0";
+		exit(0);
+	}
+	return 'ad/redirect/' . $node->aid .'/@HOSTID___';
+}
+
+/**
  * Ad API Helper Function:
  * Append all necessary attributes to <a> tags.
  */
@@ -306,6 +355,14 @@ function ad_rebuild_cache($verbose = FALSE) {
 }
 
 /**
+ * Implementation of hook_flush_caches()
+ */
+function ad_flush_caches() {
+	dpm("Delete ad_base_path variable");
+	variable_del('ad_base_path');
+}
+
+/**
  * Ad API Helper Function:
  * Append rel="nofollow" if globally enabled.
  */
@@ -942,7 +999,7 @@ function ad_nodeapi(&$node, $op, $teaser, $page) {
         if (!isset($node->maxclicks)) {
           $node->maxclicks = 0;
         }
-        db_query("INSERT INTO {ads} (aid, uid, adstatus, adtype, redirect, autoactivate, autoexpire, activated, maxviews, maxclicks) VALUES(%d, %d, '%s', '%s', '%s', %d, %d, %d, %d, %d)", $node->nid, $node->uid, $node->adstatus, $node->adtype, url('ad/redirect/'. $node->nid, array('absolute' => TRUE)), $node->autoactivate, $node->autoexpire, $activated, $node->maxviews, $node->maxclicks);
+        db_query("INSERT INTO {ads} (aid, uid, adstatus, adtype, autoactivate, autoexpire, activated, maxviews, maxclicks) VALUES(%d, %d, '%s', '%s', '%s', %d, %d, %d, %d, %d)", $node->nid, $node->uid, $node->adstatus, $node->adtype, $node->autoactivate, $node->autoexpire, $activated, $node->maxviews, $node->maxclicks);
         ad_statistics_increment($node->nid, 'create');
       }
       break;
@@ -989,7 +1046,7 @@ function ad_nodeapi(&$node, $op, $teaser, $page) {
           ad_statistics_increment($node->nid, $node->adstatus);
         }
         // Update ads table with new information.
-        db_query("UPDATE {ads} SET uid = %d, adstatus = '%s', adtype = '%s', redirect = '%s', autoactivate = %d, autoexpire = %d, activated = %d, maxviews = %d, maxclicks = %d, expired = %d WHERE aid = %d", $node->uid, $node->adstatus, $node->adtype, url('ad/redirect/'. $node->nid, array('absolute' => TRUE)), $node->autoactivate, $node->autoexpire, isset($activated) ? $activated : 0, isset($node->maxviews) ? (int)$node->maxviews : 0, isset($node->maxclicks) ? (int)$node->maxclicks : 0, isset($expired) ? $expired : 0, $node->nid);
+        db_query("UPDATE {ads} SET uid = %d, adstatus = '%s', adtype = '%s', autoactivate = %d, autoexpire = %d, activated = %d, maxviews = %d, maxclicks = %d, expired = %d WHERE aid = %d", $node->uid, $node->adstatus, $node->adtype, $node->autoactivate, $node->autoexpire, isset($activated) ? $activated : 0, isset($node->maxviews) ? (int)$node->maxviews : 0, isset($node->maxclicks) ? (int)$node->maxclicks : 0, isset($expired) ? $expired : 0, $node->nid);
         ad_statistics_increment($node->nid, 'update');
       }
       break;
diff --git a/ad_token.inc b/ad_token.inc
index 6fe845a..446a2ed 100644
--- a/ad_token.inc
+++ b/ad_token.inc
@@ -26,7 +26,7 @@ function ad_token_values($type, $object = NULL, $options = array()) {
         $values['type'] = $node->adtype;
         $values['status'] = $node->adstatus;
         $values['url'] = url('node/'. $node->nid, array('absolute' => TRUE));
-        $values['redirect'] = url($node->redirect, array('absolute' => TRUE));
+        $values['redirect'] = url(ad_link_path($node), array('absolute' => TRUE));
         $values['comments'] = $node->comment_count;
 
         $values['created_small'] = format_date($node->created, 'small');
diff --git a/adcache.inc b/adcache.inc
index 7a707de..2cae435 100644
--- a/adcache.inc
+++ b/adcache.inc
@@ -464,7 +464,7 @@ function adserve_cache_display($ids) {
   $ads = 0;
   foreach ($ids as $id) {
     $ad = adserve_cache('display_ad', $id);
-    _debug_echo('ad: '. htmlentities($ad));
+    _debug_echo("($id) ad: ". htmlentities($ad));
     // if displaying multiple ads, separate each with a div
     if ($output) {
       $group = adserve_variable('group');
diff --git a/adserve.inc b/adserve.inc
index 45e927f..d136c14 100644
--- a/adserve.inc
+++ b/adserve.inc
@@ -291,6 +291,7 @@ function adserve_bootstrap($bootstrap = NULL) {
   echo _debug_echo("Drupal bootstrap '$bootstrap'.");
 
   drupal_bootstrap($bootstrap);
+
   echo _debug_echo("Drupal bootstrap complete.");
 }
 
@@ -299,6 +300,10 @@ function adserve_bootstrap($bootstrap = NULL) {
  */
 function adserve_debug() {
   if (adserve_variable('debug')) {
+	global $base_url;
+	global $base_root;
+	echo "Base Root: $base_root<br/>";
+    echo "Base URL: $base_url<br/>";
     echo "Root drupal directory detected as '". adserve_variable('root_dir') ."'.<br />\n<br />\n";
 
     $ad_dir = adserve_variable('ad_dir');
diff --git a/image/ad_image.module b/image/ad_image.module
index a695b9d..9bf6d79 100644
--- a/image/ad_image.module
+++ b/image/ad_image.module
@@ -26,12 +26,12 @@ function ad_image_display_ad($ad) {
 function theme_ad_image_ad($ad) {
   if (isset($ad->aid) && (isset($ad->filepath) || isset($ad->remote_image))) {
     $output = '<div class="image-advertisement" id="ad-'. $ad->aid .'">';
+    $image = theme('ad_image_image', !empty($ad->remote_image) ? $ad->remote_image : $ad->filepath, check_plain($ad->tooltip), check_plain($ad->tooltip));
     if (isset($ad->url) && !empty($ad->url)) {
-      $image = theme('ad_image_image', !empty($ad->remote_image) ? $ad->remote_image : $ad->filepath, check_plain($ad->tooltip), check_plain($ad->tooltip));
-      $output .= l($image, $ad->redirect .'/@HOSTID___', array('attributes' => ad_link_attributes(), 'absolute' => TRUE, 'html' => TRUE));
+      $output .= ad_l($image, $ad, array('attributes' => ad_link_attributes(), 'absolute' => TRUE, 'html' => TRUE));
     }
     else {
-      $output .= theme('ad_image_image', !empty($ad->remote_image) ? $ad->remote_image : $ad->filepath, check_plain($ad->tooltip), check_plain($ad->tooltip));
+      $output .= $image;
     }
     $output .= '</div>';
     return $output;
diff --git a/text/ad_text.module b/text/ad_text.module
index 9381da1..7cd1831 100644
--- a/text/ad_text.module
+++ b/text/ad_text.module
@@ -28,9 +28,14 @@ function theme_ad_text_ad($ad) {
     if (!isset($ad->adheader)) {
       $ad = node_load($ad->aid);
     }
+
+    $safe_adheader = ad_text_display_prepare($ad->body, $ad->format);
+    $safe_adbody = ad_text_display_prepare($ad->body, $ad->format);
+    $ad_link = $ad->url ? ad_link_url($ad) : NULL;
+
     $output = '<div class="text-advertisement" id="ad-'. $ad->aid .'">';
     if (isset($ad->url) && !empty($ad->url)) {
-      $output .= theme('ad_text_text', ad_text_display_prepare($ad->adheader, $ad->format), ad_text_display_prepare($ad->adbody, $ad->format), $ad->redirect .'/@HOSTID___');
+      $output .= theme('ad_text_text', ad_text_display_prepare($ad->adheader, $ad->format), ad_text_display_prepare($ad->adbody, $ad->format), $ad_link);
     }
     else {
       $output .= theme('ad_text_text', ad_text_display_prepare($ad->adheader, $ad->format), ad_text_display_prepare($ad->adbody, $ad->format));
