diff --git a/html/sites/all/modules/glossify/glossify.module b/html/sites/all/modules/glossify/glossify.module
index f369d07..2d42bfe 100644
--- a/html/sites/all/modules/glossify/glossify.module
+++ b/html/sites/all/modules/glossify/glossify.module
@@ -385,32 +385,114 @@ function glossify_filter($op, $delta = 0, $format = -1, $text = '', $cache_id =
         }
       }
 
-      $html_body = str_get_html($text);
-      foreach ($configurations as $config_name => $configuration) {
-        if (isset($configuration['from'][$node->type])) {
-          $enabled_styles = array_filter($configuration['style']);
-          foreach (_fetch_possible_keywords($configuration, $node->nid) as $term_title => $target_url) {
-            $replaced = 0;
-            foreach ($enabled_styles as $style => $enabled) {
-              if ($enabled && !empty($term_title) && false !== strpos($html_body->innertext, $term_title)) {
-                $replacement = _fetch_replacement($style, $term_title, $target_url);
-                _glossify_replace($configuration, $html_body, $term_title, $replacement, $replaced);
-                // update the state of the DOM to reflect new tags added.
-                if (0 < $replaced) {
-                  $html_body = str_get_html($html_body->innertext);
-                }
-              }
-            }
-          }
-        }
+      if (class_exists('DOMDocument', false)) {
+        $text = _glossify_replace_terms_phpdom($text, $configurations, $node);
+      }
+      else {
+        $text = _glossify_replace_terms_simplehtmldom($text, $configurations, $node);
       }
-      return $html_body->innertext;
+
+      return $text;
 
     default:
       return $text;
   }
 }
 
+function _glossify_replace_terms_simplehtmldom($text, $configurations, $node) {
+  $html_body = str_get_html($text);
+  foreach ($configurations as $config_name => $configuration) {
+    if (isset($configuration['from'][$node->type])) {
+      $enabled_styles = array_filter($configuration['style']);
+      foreach (_fetch_possible_keywords($configuration, $node->nid) as $term_title => $target_url) {
+        $replaced = 0;
+        foreach ($enabled_styles as $style => $enabled) {
+          if ($enabled && !empty($term_title) && false !== strpos($html_body->innertext, $term_title)) {
+            $replacement = _fetch_replacement($style, $term_title, $target_url);
+            _glossify_replace($configuration, $html_body, $term_title, $replacement, $replaced);
+            // update the state of the DOM to reflect new tags added.
+            if (0 < $replaced) {
+              $html_body = str_get_html($html_body->innertext);
+            }
+          }
+        }
+      }
+    }
+  }
+  return $html_body->innertext;
+}
+
+/**
+ * Uses PHP's built in DOM extension if available.
+ * Adapted from http://stackoverflow.com/questions/3151064/find-and-replace-keywords-by-hyperlinks-in-an-html-fragment-via-php-dom
+ *
+ * @param  $text
+ * @param  $configurations
+ * @param  $node
+ * @return text
+ */
+function _glossify_replace_terms_phpdom($text, $configurations, $node) {
+  
+  $text = '<meta http-equiv="content-type" content="text/html; charset=utf-8">'
+        . $text;
+  
+  $dom = new DOMDocument;
+  $dom->formatOutput = true;
+  @$dom->loadHTML($text);
+  $xpath = new DOMXpath($dom);
+
+  foreach ($configurations as $config_name => $configuration) {
+    if (isset($configuration['from'][$node->type])) {
+      $enabled_styles = array_filter($configuration['style']);
+      $exclude_tags = $configuration['exclude_tags']
+               + array('iframe' => 'iframe', 'a' => 'a', 'object' => 'object');
+      foreach (_fetch_possible_keywords($configuration, $node->nid) as $term_title => $target_url) {
+        foreach ($enabled_styles as $style => $enabled) {
+          $rx = '/\b' . $term_title . '\b/';
+          if ($enabled
+              && !empty($term_title)
+              && 0 < preg_match($rx, $text)) {
+            $replacement = _fetch_replacement($style, $term_title, $target_url);
+            $nodes = $xpath->query('//text()[contains(., "' . $term_title . '")]');
+            $count = 0;
+            foreach ($nodes as $node) {
+
+              // don't replace within excluded tags
+              if (isset($exclude_tags[$node->parentNode->nodeName])) {
+                continue;
+              }
+
+              // if configured for only first occurrence, bail early
+              if (1 == $configuration['only_first']
+                  && $count >= 1) {
+                break 1;
+              }
+
+              // if configured for only first occurrence,
+              // we need to use preg_replace to limit replacements
+              if (1 == $configuration['only_first']) {
+                $replaced = preg_replace($rx, $replacement, $node->wholeText, 1);
+                $count = $count + 1;
+              } else {
+                $replaced = str_replace($term_title, $replacement, $node->wholeText, $result);
+                $count += $result;
+              }
+              $newNode = $dom->createDocumentFragment();
+              $newNode->appendXML($replaced);
+              $node->parentNode->replaceChild($newNode, $node);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // return just what is in the body tags of our document   
+  $body = $dom->GetElementsByTagName('body')->item(0);
+  $out = $dom->saveHTML($body);
+  $out = str_replace(array('<body>', '</body>'), '', $out);
+  return $out;
+}
 /**
  * Helper function that emulates a contributing module's nodeapi load operation
  * @param stdObject
