diff --git a/account.php b/account.php
index ae124a598a9df81b3373a0a8a366d785582dd6ae..b8f84533e6c5ccfe33dc9ec6e8a1443d2cb5925c 100644
--- a/account.php
+++ b/account.php
@@ -2,7 +2,7 @@
 
 include_once "includes/common.inc";
 
-if (variable_get(dev_timing, 0)) timer_start();
+page_header();
 
 function account_get_user($uname) {
   $result = db_query("SELECT * FROM users WHERE userid = '$uname'");
@@ -74,7 +74,7 @@ function account_session_close() {
 }
 
 function account_user_edit() {
-  global $allowed_html, $theme, $user;
+  global $theme, $user;
 
   if ($user->id) {
     // construct form:
@@ -83,8 +83,8 @@ function account_user_edit() {
     $form .= form_item(t("Real e-mail address"), $user->real_email, t("Required, unique, can not be changed.") ." ". t("Your real e-mail address is never displayed publicly: only needed in case you lose your password."));
     $form .= form_textfield(t("Fake e-mail address"), "fake_email", $user->fake_email, 30, 55, t("Optional") .". ". t("Displayed publicly so you may spam proof your real e-mail address if you want."));
     $form .= form_textfield(t("Homepage"), "url", $user->url, 30, 55, t("Optional") .". ". t("Make sure you enter fully qualified URLs only.  That is, remember to include \"http://\"."));
-    $form .= form_textarea(t("Bio"), "bio", $user->bio, 35, 5, t("Optional") .". ". t("Maximal 255 characters.") ." ". t("This biographical information is publicly displayed on your user page.") ."<BR>". t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html));
-    $form .= form_textarea(t("Signature"), "signature", $user->signature, 35, 5, t("Optional") .". ". t("Maximal 255 characters.") ." ". t("This information will be publicly displayed at the end of your comments.") ."<BR>". t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html));
+    $form .= form_textarea(t("Bio"), "bio", $user->bio, 35, 5, t("Optional") .". ". t("Maximal 255 characters.") ." ". t("This biographical information is publicly displayed on your user page.") ."<BR>". t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")));
+    $form .= form_textarea(t("Signature"), "signature", $user->signature, 35, 5, t("Optional") .". ". t("Maximal 255 characters.") ." ". t("This information will be publicly displayed at the end of your comments.") ."<BR>". t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")));
     $form .= form_item(t("Password"), "<INPUT TYPE=\"password\" NAME=\"edit[pass1]\" SIZE=\"10\" MAXLENGTH=\"20\"> <INPUT TYPE=\"password\" NAME=\"edit[pass2]\" SIZE=\"10\" MAXLENGTH=\"20\">", t("Enter your new password twice if you want to change your current password or leave it blank if you are happy with your current password."));
     $form .= form_submit(t("Save user information"));
 
@@ -491,6 +491,6 @@ function account_track_site() {
     account_user($user->userid);
 }
 
-if (variable_get(dev_timing, 0)) timer_print();
+page_footer();
 
 ?>
\ No newline at end of file
diff --git a/admin.php b/admin.php
index 33f89dd7662f60a86f83ca552dbe7bd029bb88fa..4a359ad914986fab46e0e88fe538eef2e3ec2707 100644
--- a/admin.php
+++ b/admin.php
@@ -24,9 +24,9 @@ function module($name) {
    <HEAD><TITLE><?php echo variable_get(site_name, "drupal"); ?> administration</TITLE></HEAD>
    <STYLE>
     body { font-family: helvetica, arial; }
-    h1   { font-size: 18pt; font-weight: bold; color: #990000; }
-    h2   { font-family: helvetica, arial; font-size: 18pt; font-weight: bold; }
-    h3   { font-family: helvetica, arial; font-size: 14pt; font-weight: bold; }
+    h1   { font-famile: helvetica, arial; font-size: 18pt; font-weight: bold; color: #660000; }
+    h2   { font-family: helvetica, arial; font-size: 18pt; font-weight: bold; color: #000066; }
+    h3   { font-family: helvetica, arial; font-size: 14pt; font-weight: bold; color: #006600; }
     th   { font-family: helvetica, arial; text-align: center; vertical-align: top; background-color: #CCCCCC; color: #995555; }
     td   { font-family: helvetica, arial; }
    </STYLE>
diff --git a/database/database.mysql b/database/database.mysql
index 7fc160d31c375ab12282659be388cc331d682b05..bdb675fbf95bf94f8b8ec63499234b2075e2f404 100644
--- a/database/database.mysql
+++ b/database/database.mysql
@@ -118,17 +118,6 @@ CREATE TABLE comments (
   KEY lid (lid)
 );
 
-#
-# Table structure for table 'crons'
-#
-DROP TABLE IF EXISTS crons;
-CREATE TABLE crons (
-  module varchar(64) DEFAULT '' NOT NULL,
-  scheduled int(11),
-  timestamp int(11),
-  PRIMARY KEY (module)
-);
-
 #
 # Table structure for table 'cvs'
 #
diff --git a/includes/comment.inc b/includes/comment.inc
index 9ecc1c690ed5cb5ff14cdab36c80714de6e2a2a3..f7bea9ac6e4b830ce57f4ae6a329d2327edaddfd 100644
--- a/includes/comment.inc
+++ b/includes/comment.inc
@@ -48,7 +48,7 @@ function comment_settings($mode, $order, $threshold) {
 }
 
 function comment_reply($pid, $id) {
-  global $allowed_html, $REQUEST_URI, $theme, $user;
+  global $REQUEST_URI, $theme, $user;
 
   if ($pid) {
     $item = db_fetch_object(db_query("SELECT comments.*, users.userid FROM comments LEFT JOIN users ON comments.author = users.id WHERE comments.cid = '$pid'"));
@@ -69,8 +69,8 @@ function comment_reply($pid, $id) {
 
   // Comment field:
   $output .= "<B>".t("Comment") .":</B><BR>\n";
-  $output .= "<TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"10\" NAME=\"comment\">". check_textarea($user->signature) ."</TEXTAREA><BR>\n";
-  $output .= "<SMALL><I>". t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html) .".</I></SMALL><P>\n";
+  $output .= "<TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"10\" NAME=\"comment\">". check_form($user->signature) ."</TEXTAREA><BR>\n";
+  $output .= "<SMALL><I>". t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")) .".</I></SMALL><P>\n";
 
   // Preview button:
   $output .= "<SMALL><I>". t("You must preview at least once before you can submit") .":</I></SMALL><BR>\n";
@@ -84,10 +84,10 @@ function comment_reply($pid, $id) {
 }
 
 function comment_preview($pid, $id, $subject, $comment) {
-  global $allowed_html, $REQUEST_URI, $theme, $user;
+  global $REQUEST_URI, $theme, $user;
 
   // Preview comment:
-  comment_view(new Comment($user->userid, $subject, $comment, time(), $user->url, $user->fake_email, 0, 0, 0, 0), t("reply to this comment"));
+  comment_view(new Comment($user->userid, check_preview($subject), check_preview($comment), time(), check_preview($user->url), check_preview($user->fake_email), 0, 0, 0, 0), t("reply to this comment"));
 
   // Build reply form:
   $output .= "<FORM ACTION=\"$REQUEST_URI\" METHOD=\"post\">\n";
@@ -98,12 +98,12 @@ function comment_preview($pid, $id, $subject, $comment) {
 
   // Subject field:
   $output .= "<B>". t("Subject") .":</B><BR>\n";
-  $output .= "<INPUT TYPE=\"text\" NAME=\"subject\" SIZE=\"50\" MAXLENGTH=\"60\" VALUE=\"". check_textfield($subject) ."\"><P>\n";
+  $output .= "<INPUT TYPE=\"text\" NAME=\"subject\" SIZE=\"50\" MAXLENGTH=\"60\" VALUE=\"". check_form($subject) ."\"><P>\n";
 
   // Comment field:
   $output .= "<B>". t("Comment") .":</B><BR>\n";
-  $output .= "<TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"10\" NAME=\"comment\">". check_textarea($comment) ."</TEXTAREA><BR>\n";
-  $output .= "<SMALL><I>". t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html) .".</I></SMALL><P>\n";
+  $output .= "<TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"10\" NAME=\"comment\">". check_form($comment) ."</TEXTAREA><BR>\n";
+  $output .= "<SMALL><I>". t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")) .".</I></SMALL><P>\n";
 
   // Hidden fields:
   $output .= "<INPUT TYPE=\"hidden\" NAME=\"pid\" VALUE=\"$pid\">\n";
diff --git a/includes/common.inc b/includes/common.inc
index bb8c2677e6b9457b017d709bc6576824ab66537e..2ceb45505601bac08a3b1476022d567913c787c2 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -6,7 +6,7 @@ function conf_init() {
   global $HTTP_HOST, $REQUEST_URI;
   $file = strtolower(strtr($HTTP_HOST ."". substr($REQUEST_URI, 0, strrpos($REQUEST_URI, "/")), "/:", ".."));
   while ($file && !file_exists("includes/$file.php")) $file = substr($file, 0, strrpos($file, "."));
-  return $file ? $file : "setting";
+  return $file ? $file : "conf";
 }
 
 function error_handler($errno, $message, $filename, $line, $variables) {
@@ -52,30 +52,16 @@ function notice_account() {
   return t("This page requires a valid user account.  Please <A HREF=\"account.php\">create a user account</A> and <A HREF=\"account.php\">login</A> prior to accessing it.");
 }
 
-function check_textfield($message) {
-  return strip_tags(str_replace("\"", "&quot;", stripslashes($message)));
+function check_form($text) {
+  return htmlspecialchars(stripslashes($text));
 }
 
-function check_select($message) {
-  return check_textfield($message);
+function check_export($text) {
+  return htmlspecialchars(stripslashes($text));
 }
 
-function check_export($message) {
-  return check_textfield($message);
-}
-
-function check_textarea($message) {
-  global $allowed_html;
-  return htmlspecialchars(strip_tags(stripslashes($message), $allowed_html));
-}
-
-function check_input($message) {
-  global $allowed_html;
-  return strip_tags(addslashes(stripslashes(substr($message, 0, variable_get(max_input_size, 10000)))), $allowed_html);
-}
-
-function check_code($message) {
-  return $message;
+function check_code($text) {
+  return $text;
 }
 
 function check_mail($mail) {
@@ -86,10 +72,18 @@ function check_name($name) {
   return ereg("[^a-zA-Z0-9_-]", $name) ? 0 : 1;
 }
 
-function check_output($message, $nl2br = 0) {
-  global $allowed_html, $na;
-  $var = strip_tags(stripslashes(node_macro($message)), $allowed_html);
-  return ($var) ? (($nl2br) ? nl2br($var) : $var) : $na;
+function check_preview($text) {
+  return check_output(check_input($text), 1);
+}
+
+function check_input($text) {
+  foreach (module_list() as $module) $text = module_invoke($module, "filter", $text);
+  return addslashes(stripslashes(substr($text, 0, variable_get("max_input_size", 10000))));
+}
+
+function check_output($text, $nl2br = 0) {
+  global $na;
+  return ($text) ? (($nl2br) ? nl2br(stripslashes($text)) : stripslashes($text)) : $na;
 }
 
 function format_plural($count, $singular, $plural) {
@@ -172,15 +166,15 @@ function form_item($title, $value, $description = 0) {
 }
 
 function form_textfield($title, $name, $value, $size, $maxlength, $description = 0) {
-  return form_item($title, "<INPUT MAXLENGTH=\"$maxlength\" NAME=\"edit[$name]\" SIZE=\"$size\" VALUE=\"". check_textfield($value) ."\">", $description);
+  return form_item($title, "<INPUT MAXLENGTH=\"$maxlength\" NAME=\"edit[$name]\" SIZE=\"$size\" VALUE=\"". check_form($value) ."\">", $description);
 }
 
 function form_textarea($title, $name, $value, $cols, $rows, $description = 0) {
-  return form_item($title, "<TEXTAREA WRAP=\"virtual\" COLS=\"$cols\" ROWS=\"$rows\" NAME=\"edit[$name]\">". check_textarea($value) ."</TEXTAREA>", $description);
+  return form_item($title, "<TEXTAREA WRAP=\"virtual\" COLS=\"$cols\" ROWS=\"$rows\" NAME=\"edit[$name]\">". check_form($value) ."</TEXTAREA>", $description);
 }
 
 function form_select($title, $name, $value, $options, $description = 0) {
-  foreach ($options as $key=>$choice) $select .= "<OPTION VALUE=\"$key\"". ($key == $value ? " SELECTED" : "") .">". check_select($choice) ."</OPTION>";
+  foreach ($options as $key=>$choice) $select .= "<OPTION VALUE=\"$key\"". ($key == $value ? " SELECTED" : "") .">". check_form($choice) ."</OPTION>";
   return form_item($title, "<SELECT NAME=\"edit[$name]\">$select</SELECT>", $description);
 }
 
@@ -189,11 +183,11 @@ function form_file($title, $name, $size, $description = 0) {
 }
 
 function form_hidden($name, $value) {
-  return "<INPUT TYPE=\"hidden\" NAME=\"edit[$name]\" VALUE=\"". check_textfield($value) ."\">\n";
+  return "<INPUT TYPE=\"hidden\" NAME=\"edit[$name]\" VALUE=\"". check_form($value) ."\">\n";
 }
 
 function form_submit($value) {
-  return "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"". check_textfield($value) ."\">\n";
+  return "<INPUT TYPE=\"submit\" NAME=\"op\" VALUE=\"". check_form($value) ."\">\n";
 }
 
 function field_get($string, $name) {
@@ -227,6 +221,26 @@ function field_set($string, $name, $value) {
   return $rval;
 }
 
+function timer_start() {
+  global $timer;
+  $timer = explode(" ", microtime());
+}
+
+function timer_print() {
+  global $timer;
+  $stop = explode(" ", microtime());
+  $diff = $stop[0] - $timer[0];
+  print "<PRE>execution time: $diff ms</PRE>";
+}
+
+function page_header() {
+  if (variable_get("dev_timer", 0)) timer_start();
+}
+
+function page_footer() {
+  if (variable_get("dev_timer", 0)) timer_print();
+}
+
 $conf = conf_init();
 
 include_once "includes/$conf.php";
@@ -237,7 +251,6 @@ function field_set($string, $name, $value) {
 include_once "includes/module.inc";
 include_once "includes/locale.inc";
 include_once "includes/search.inc";
-include_once "includes/timer.inc";
 include_once "includes/theme.inc";
 include_once "includes/user.inc";
 include_once "includes/node.inc";
diff --git a/includes/setting.php b/includes/conf.php
similarity index 69%
rename from includes/setting.php
rename to includes/conf.php
index 525de3bb4226230010807347d249ce523d71ed9f..77fb302981aa534042bfd5cfea4b92ed93ab9271 100644
--- a/includes/setting.php
+++ b/includes/conf.php
@@ -24,11 +24,6 @@
                        "+4"   => "+ 4",
                        "+5"   => "+ 5");
 
-#
-# Allowed HTML tags:
-#
-$allowed_html = "<A><B><BLOCKQUOTE><CODE><DD><DL><DT><EM><HR><I><LI><SMALL><OL><U><UL>";
-
 #
 # Themes:
 #   The first theme listed in this associative array will automatically
@@ -47,16 +42,6 @@
 #   automatically become the default language.  You can add a language
 #   but make sure your SQL table, called locales is updated
 #   appropriately.
-#
-#   Translation support - as provided by the default locale module add
-#   significant overhead to your site in exchange for excessive
-#   maintenance capabilities.  If your site does not require
-#   translation support, disable it by commenting out the $language
-#   variable below.
-#$languages = array();  // = language support disabled
 $languages = array("en" => "English");
 
-# This line prevents users from accessing your settings file:
-if (basename($SCRIPT_FILENAME) == basename(__FILE__) && basename($SCRIPT_FILENAME) != "") die("access denied");
-
 ?>
\ No newline at end of file
diff --git a/includes/database.inc b/includes/database.inc
index 634ec55efc4c634b99a183f7640aa6e0ee11acef..68562f334ce65a2e07fd26f8384ffa3c9911e75a 100644
--- a/includes/database.inc
+++ b/includes/database.inc
@@ -6,6 +6,7 @@ function db_connect($host, $user, $pass, $name) {
   // NOTE: we are using a persistent connection!
 }
 
+
 function db_query($query, $debug = 0) {
   $result = mysql_query($query);
   if ($debug) print "<P>query: $query<BR>error:". mysql_error() ."</P>";
diff --git a/includes/module.inc b/includes/module.inc
index aa631faecf18bf1301a2065b77dcc7f5f5c533a8..9033078c37f9bd6f5c4b7ae0f852f9cf0fba4e57 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -13,7 +13,7 @@ function module_iterate($function, $argument = "") {
 // invoke hook $hook of module $name with optional arguments:
 function module_invoke($name, $hook, $argument = "") {
   $function = $name ."_". $hook;
-  if (function_exists($function)) return $function($argument);
+  return function_exists($function) ? $function($argument) : $argument;
 }
 
 // return true if module $name supports hook $hook, and false otherwise:
diff --git a/includes/node.inc b/includes/node.inc
index fcfd26dd7b8683b9183078c6e46562946d087074..6d999e25c35f0dc1b898a239fa2d02e013b0edab 100644
--- a/includes/node.inc
+++ b/includes/node.inc
@@ -183,13 +183,20 @@ function visit(site) {
   }
 
   $output .= "<FORM METHOD=\"get\" ACTION=\"\">\n";
-  foreach ($choices as $key => $value) $options .= "<OPTION VALUE=\"$key\"". (strstr($REQUEST_URI,"/$key") ? " SELECTED" : "") .">". check_select($value) ."</OPTION>\n";
+  foreach ($choices as $key => $value) $options .= "<OPTION VALUE=\"$key\"". (strstr($REQUEST_URI,"/$key") ? " SELECTED" : "") .">". check_form($value) ."</OPTION>\n";
   $output .= " <SELECT NAME=\"op\" ONCHANGE=\"visit(this.options[this.selectedIndex].value)\">$options</SELECT>\n";
   $output .= "</FORM>\n";
 
   return $output;
 }
 
+function node_preview($node) {
+  foreach ($node as $key=>$value) {
+    if ($node[$key]) $node[$key] = check_preview($value);
+  }
+  return $node;
+}
+
 function node_visible($node) {
   global $user, $status;
   return ($node->status == $status[posted]) || ($node->status == $status[queued] && $user->id) || user_access($user, $node->type) || user_access($user, "node");
diff --git a/includes/search.inc b/includes/search.inc
index af2139e842b4d4df742b6c9400308729ae43013a..11247c525a9e8b29c21bea026069aa50e801f9f2 100644
--- a/includes/search.inc
+++ b/includes/search.inc
@@ -3,7 +3,7 @@
 function search_form($keys) {
   global $REQUEST_URI;
   $output .= "<FORM ACTION=\"$REQUEST_URI\" METHOD=\"POST\">\n";
-  $output .= " <INPUT SIZE=\"50\" VALUE=\"". check_textfield($keys) ."\" NAME=\"keys\">";
+  $output .= " <INPUT SIZE=\"50\" VALUE=\"". check_form($keys) ."\" NAME=\"keys\">";
   $output .= " <INPUT TYPE=\"submit\" VALUE=\"". t("Search") ."\">\n";
   $output .= "</FORM>\n";
   return $output;
diff --git a/includes/structure.inc b/includes/structure.inc
index 6d38bfbcec996c5b4238b1d984c58f923ac709aa..989ee7f2fd5dd5528c96607a5bba444d734a5a25 100644
--- a/includes/structure.inc
+++ b/includes/structure.inc
@@ -74,7 +74,7 @@ function category_name($cid) {
 function category_form_select($type, $edit = array(), $size = 1) {
   $result = db_query("SELECT * FROM category WHERE type = '$type'");
   while ($category = db_fetch_object($result)) {
-    $options .= "<OPTION VALUE=\"$category->cid\"". ($edit[cid] == $category->cid ? "SELECTED" : "") .">". check_select($category->name) ."</OPTION>";
+    $options .= "<OPTION VALUE=\"$category->cid\"". ($edit[cid] == $category->cid ? "SELECTED" : "") .">". check_form($category->name) ."</OPTION>";
   }
   return "<SELECT NAME=\"edit[cid]\" SIZE=\"$size\"". ($size > 1 ? "MULTIPLE" : "") .">$options</SELECT>\n";
 }
@@ -133,7 +133,7 @@ function topic_moderate($tid) {
 // renders a HTML form to select one or more topics:
 function topic_form_select($edit = array(), $size = 1) {
   foreach (topic_tree() as $tid=>$name) {
-    $options .= "<OPTION VALUE=\"$tid\"". ($edit[tid] == $tid ? "SELECTED" : "") .">". check_select($name) ."</OPTION>";
+    $options .= "<OPTION VALUE=\"$tid\"". ($edit[tid] == $tid ? "SELECTED" : "") .">". check_form($name) ."</OPTION>";
   }
   return "<SELECT NAME=\"edit[tid]\" SIZE=\"$size\"". ($size > 1 ? "MULTIPLE" : "") .">$options</SELECT>\n";
 }
diff --git a/includes/variable.inc b/includes/variable.inc
index 5f47c03e658cfd8d078e6dfad9739ac05e2a7a8f..618c7f4cefe441e7dddb3f8dccd89158dcb7d804 100644
--- a/includes/variable.inc
+++ b/includes/variable.inc
@@ -32,7 +32,7 @@ function variable_get($name, $default, $object = 0) {
     case "expire_threshold":
       return handler_expire_threshold($object, $default);
     default:
-      return ($conf[$name] ? $conf[$name] : $default);
+      return $conf[$name] ? $conf[$name] : $default;
   }
 }
 
@@ -45,4 +45,12 @@ function variable_set($name, $value) {
   $conf[$name] = $value;
 }
 
+function variable_del($name) {
+  global $conf;
+
+  db_query("DELETE FROM variable WHERE name = '". check_input($name) ."'");
+
+  $conf[$name] = "";
+}
+
 ?>
\ No newline at end of file
diff --git a/index.php b/index.php
index eef129d57b27c294b6f4f86db4b7714dfc954b99..781dca5767adc77f07397d6a9fe6e50199ceef38 100644
--- a/index.php
+++ b/index.php
@@ -2,9 +2,7 @@
 
 include_once "includes/common.inc";
 
-if (variable_get("dev_timing", 0)) {
-  timer_start();
-}
+page_header();
 
 if ($category) {
   $c = "AND cid = '". check_input($category) ."'";
@@ -23,8 +21,6 @@
 }
 $theme->footer();
 
-if (variable_get("dev_timing", 0)) {
-  timer_print();
-}
+page_footer();
 
 ?>
diff --git a/module.php b/module.php
index 4dff9fe3fd80616e9a0b7877496113240ffde5b2..13aca87e2b28e36eb483fbb2d0723bcb943a1321 100644
--- a/module.php
+++ b/module.php
@@ -1,8 +1,9 @@
 <?php
 
 include_once "includes/common.inc";
-if (variable_get(dev_timing, 0)) timer_start();
+
+page_header();
 module_invoke($mod, "page");
-if (variable_get(dev_timing, 0)) timer_print();
+page_footer();
 
 ?>
diff --git a/modules/book.module b/modules/book.module
index 887f9f8f14b16d79f498f07511063f255b5a3cdc..c46e7cd0d135dc703fed09e602683665e8a070e5 100644
--- a/modules/book.module
+++ b/modules/book.module
@@ -101,7 +101,7 @@ function book_toc($parent = "", $indent = "", $toc = array()) {
 }
 
 function book_form($edit = array()) {
-  global $allowed_html, $REQUEST_URI, $user;
+  global $REQUEST_URI, $user;
 
   $form .= form_item(t("Author"), format_username(($edit[userid] ? $edit[userid] : $user->userid)));
   $form .= form_hidden(userid, $edit[userid]);
@@ -117,7 +117,7 @@ function book_form($edit = array()) {
     $form .= form_select(t("Parent"), "parent", $edit[parent], book_toc(), t("The parent subject or category the page belongs in."));
   }
 
-  $form .= form_textarea(t("Content"), "body", $edit[body], 50, 10, t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html));
+  $form .= form_textarea(t("Content"), "body", $edit[body], 50, 10, t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")));
   $form .= form_textarea(t("Log message"), "log", $edit[log], 50, 5, t("An explanation of the additions or updates being made to help the group understand your motivations."));
 
   if (user_access($user, "book")) {
@@ -218,7 +218,7 @@ function book_admin() {
       print book_tree();
       break;
     case t("Preview"):
-      book_view(new Book($edit));
+      book_view(new Book(node_preview($edit)));
       print book_form($edit);
       break;
     case t("Submit"):
@@ -269,7 +269,7 @@ function book_user() {
       $theme->box($title, book_update($id));
       break;
     case t("Preview"):
-      book_view(new Book($edit));
+      book_view(new Book(node_preview($edit)));
       $theme->box($title, book_form($edit));
       break;
     case t("Submit"):
diff --git a/modules/book/book.module b/modules/book/book.module
index 887f9f8f14b16d79f498f07511063f255b5a3cdc..c46e7cd0d135dc703fed09e602683665e8a070e5 100644
--- a/modules/book/book.module
+++ b/modules/book/book.module
@@ -101,7 +101,7 @@ function book_toc($parent = "", $indent = "", $toc = array()) {
 }
 
 function book_form($edit = array()) {
-  global $allowed_html, $REQUEST_URI, $user;
+  global $REQUEST_URI, $user;
 
   $form .= form_item(t("Author"), format_username(($edit[userid] ? $edit[userid] : $user->userid)));
   $form .= form_hidden(userid, $edit[userid]);
@@ -117,7 +117,7 @@ function book_form($edit = array()) {
     $form .= form_select(t("Parent"), "parent", $edit[parent], book_toc(), t("The parent subject or category the page belongs in."));
   }
 
-  $form .= form_textarea(t("Content"), "body", $edit[body], 50, 10, t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html));
+  $form .= form_textarea(t("Content"), "body", $edit[body], 50, 10, t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")));
   $form .= form_textarea(t("Log message"), "log", $edit[log], 50, 5, t("An explanation of the additions or updates being made to help the group understand your motivations."));
 
   if (user_access($user, "book")) {
@@ -218,7 +218,7 @@ function book_admin() {
       print book_tree();
       break;
     case t("Preview"):
-      book_view(new Book($edit));
+      book_view(new Book(node_preview($edit)));
       print book_form($edit);
       break;
     case t("Submit"):
@@ -269,7 +269,7 @@ function book_user() {
       $theme->box($title, book_update($id));
       break;
     case t("Preview"):
-      book_view(new Book($edit));
+      book_view(new Book(node_preview($edit)));
       $theme->box($title, book_form($edit));
       break;
     case t("Submit"):
diff --git a/modules/box.module b/modules/box.module
index 5edc748ac17020e0bece00ab7024eb86aac344f3..5ae9aa538bf6e71b8cd0ef55fbdc2f50909fa46f 100644
--- a/modules/box.module
+++ b/modules/box.module
@@ -104,7 +104,7 @@ function box_admin_edit($id) {
 
     $output .= "<P>\n";
     $output .= " <B>Subject:</B><BR>\n";
-    $output .= " <INPUT TYPE=\"text\" NAME=\"subject\" VALUE=\"". check_textfield($block->subject) ."\">\n";
+    $output .= " <INPUT TYPE=\"text\" NAME=\"subject\" VALUE=\"". check_form($block->subject) ."\">\n";
     $output .= "</P>\n";
     $output .= "<P>\n";
     $output .= " <B>Content:</B><BR>\n";
@@ -120,11 +120,11 @@ function box_admin_edit($id) {
     $output .= "</P>\n";
     $output .= "<P>\n";
     $output .= " <B>Description:</B><BR>\n";
-    $output .= " <INPUT TYPE=\"text\" NAME=\"info\" VALUE=\"". check_textfield($block->info) ."\">\n";
+    $output .= " <INPUT TYPE=\"text\" NAME=\"info\" VALUE=\"". check_form($block->info) ."\">\n";
     $output .= "</P>\n";
     $output .= "<P>\n";
     $output .= " <B>Link:</B><BR>\n";
-    $output .= " <INPUT TYPE=\"text\" NAME=\"link\" VALUE=\"". check_textfield($block->link) ."\">\n";
+    $output .= " <INPUT TYPE=\"text\" NAME=\"link\" VALUE=\"". check_form($block->link) ."\">\n";
     $output .= "</P>\n";
     $output .= "<P>\n";
     $output .= " <INPUT TYPE=\"hidden\" NAME=\"id\" VALUE=\"$id\">\n";
diff --git a/modules/settings.module b/modules/conf.module
similarity index 56%
rename from modules/settings.module
rename to modules/conf.module
index 736ddbee220c7ff98445241f6bbe6896f4c95e3a..a1d4eaaa21a65f9f5b678aa01cb44fc7a72e7b06 100644
--- a/modules/settings.module
+++ b/modules/conf.module
@@ -1,10 +1,10 @@
 <?php
 
-function settings_help() {
+function conf_help() {
  ?>
-  <P>Drupal comes with system-wide defaults but the setting-module provides control over many Drupal preferences, behaviors including visual and operational settings.</P>
+  <P>Drupal comes with system-wide defaults but the setting-module provides control over many Drupal preferences, behaviors including visual and operational conf.</P>
   <H3>Cron</H3>
-  <P>Some settings require a <I>cron</I> or <I>crontab</I>.  Cron (which stands for chronograph) is a periodic command scheduler: it executes commands at intervals specified in seconds.  It can be used to control the execution of daily, weekly and monthly jobs (or anything with a period of <i>n</i> seconds).   Automating tasks is one of the best ways to keep a system running smoothly, and if most of your administration does not require your direct involvement, cron is an ideal solution.</P>
+  <P>Some conf require a <I>cron</I> or <I>crontab</I>.  Cron (which stands for chronograph) is a periodic command scheduler: it executes commands at intervals specified in seconds.  It can be used to control the execution of daily, weekly and monthly jobs (or anything with a period of <i>n</i> seconds).   Automating tasks is one of the best ways to keep a system running smoothly, and if most of your administration does not require your direct involvement, cron is an ideal solution.</P>
   <P>Whenever <A HREF="<?php echo path_uri(); ?>cron.php"><?php echo path_uri(); ?>cron.php</A> is accessed, cron will run: it checks for the jobs cron controls, and their periods in seconds.  If a certain task wasn't executed in the last n seconds, where n is the period of that job, it will be executed.  When all the executed commands terminate, cron is done.</P>
   <P>The recommended way to setup your cron system is to setup a Unix/Linux crontab that frequently visits <A HREF="<?php echo path_uri(); ?>cron.php"><?php echo path_uri(); ?>cron.php</A>. Note that cron does not guarantee the commands will be executed at the specified interval.  However, Drupal will try his best and run the crons as close to the specified intervals as possible.  The more you visit cron.php, the more accurate cron will be.</P>
   <P>If your hosting company does not allow you to setup crontabs, you can always ask someone else to setup a crontab for you. After all, virtually any Unix/Linux machine with access to the internet can setup a crontab to frequently visit <A HREF="<?php echo path_uri(); ?>cron.php"><?php echo path_uri(); ?>cron.php</A>.</P>
@@ -12,20 +12,21 @@ function settings_help() {
  <?php
 }
 
-function settings_conf() {
+function conf_view_system() {
   global $conf, $cmodes, $corder, $themes;
 
   // general settings:
-  $output .= form_textfield(t("Name"), "site_name", variable_get(site_name, "drupal"), 30, 55, t("The name of this website."));
-  $output .= form_textfield(t("Slogan"), "site_slogan", variable_get(site_slogan, ""), 30, 55, t("The slogan of this website"));
-  $output .= form_textfield(t("E-mail address"), "site_mail", variable_get(site_mail, "root@localhost"), 30, 55, t("A valid e-mail address for this website, used by the auto-mailer to create new user accounts."));
-  $output .= form_textarea(t("Footer message"), "site_footer", variable_get(site_footer, ""), 55, 3, t("This text will be displayed at the bottom of each page.  Useful for adding a copyright notice to your pages."));
-  $output .= form_textfield(t("Anonymous user"), "anonymous", variable_get(anonymous, "Anonymous"), 30, 55, t("The name used to indicate anonymous users."));
+  $output .= "<H3>General settings</H3>\n";
+  $output .= form_textfield(t("Name"), "site_name", variable_get("site_name", "drupal"), 30, 55, t("The name of this website."));
+  $output .= form_textfield(t("Slogan"), "site_slogan", variable_get("site_slogan", ""), 30, 55, t("The slogan of this website"));
+  $output .= form_textfield(t("E-mail address"), "site_mail", variable_get("site_mail", "root@localhost"), 30, 55, t("A valid e-mail address for this website, used by the auto-mailer to create new user accounts."));
+  $output .= form_textarea(t("Footer message"), "site_footer", variable_get("site_footer", ""), 55, 3, t("This text will be displayed at the bottom of each page.  Useful for adding a copyright notice to your pages."));
+  $output .= form_textfield(t("Anonymous user"), "anonymous", variable_get("anonymous", "Anonymous"), 30, 55, t("The name used to indicate anonymous users."));
   $output .= "<HR>\n";
 
   // node settings:
   $output .= "<H3>Node settings</H3>\n";
-  $output .= form_select(t("Default number of nodes to display"), "default_nodes_main", variable_get(default_nodes_main, 10), array(10 => 10, 15 => 15, 20 => 20, 25 => 25, 30 => 30), t("The default maximum number of nodes to display on the main page."));
+  $output .= form_select(t("Default number of nodes to display"), "default_nodes_main", variable_get("default_nodes_main", 10), array(10 => 10, 15 => 15, 20 => 20, 25 => 25, 30 => 30), t("The default maximum number of nodes to display on the main page."));
   $output .= "<HR>\n";
 
   // comment settings:
@@ -39,77 +40,93 @@ function settings_conf() {
   // submission settings:
   $output .= "<H3>Submission settings</H3>\n";
   $size = array(1000 => "1.000 characters", 5000 => "5.000 characters", 10000 => "10.000 characters", 15000 => "15.000 characters", 30.000 => "30.000 characters", 50000 => "50.000 characters", 100000 => "100.000 characters");
-  $output .= form_select(t("Maximum submission size"), "max_input_size", variable_get(max_input_size, 10000), $size, t("The maximum number of characters someone can enter in a form."));
+  $output .= form_select(t("Maximum submission size"), "max_input_size", variable_get("max_input_size", 10000), $size, t("The maximum number of characters someone can enter in a form."));
   $rate = array(1 => "Maximum 1 every second", 5 => "Maximum 1 every 5 seconds", 15 => "Maximum 1 every 15 seconds", 30 => "Maximum 1 every 30 seconds", 60 => "Maximum 1 every minute", 300 => "Maximum 1 every 5 minutes", 900 => "Maximum 1 every 15 minutes", 1800 => "Maximum 1 every 30 minutes", 3600 => "Maximum 1 every hour", 21600 => "Maximum 1 every 6 hour", 43200 => "Maximum 1 every 12 hour");
-  $output .= form_select(t("Maximum node rate"), "max_node_rate", variable_get(max_node_rate, 900), $rate, t("The maximum submission rate for nodes.  Its purpose is to stop potential abuse or denial of service attacks."));
-  $output .= form_select(t("Maximum comment rate"), "max_comment_rate", variable_get(max_comment_rate, 120), $rate, t("The maximum submission rate for comments.  Its purpose is to stop potential abuse or denial of service attacks."));
+  $output .= form_select(t("Maximum node rate"), "max_node_rate", variable_get("max_node_rate", 900), $rate, t("The maximum submission rate for nodes.  Its purpose is to stop potential abuse or denial of service attacks."));
+  $output .= form_select(t("Maximum comment rate"), "max_comment_rate", variable_get("max_comment_rate", 120), $rate, t("The maximum submission rate for comments.  Its purpose is to stop potential abuse or denial of service attacks."));
   $output .= "<HR>\n";
 
   // theme settings:
   $output .= "<H3>Theme settings</H3>\n";
-  foreach ($themes as $key=>$value) $options .= "<OPTION VALUE=\"$key\"". (variable_get(theme_default, key($themes)) == $key ? " SELECTED" : "") .">$key</OPTION>\n";
+  foreach ($themes as $key=>$value) $options .= "<OPTION VALUE=\"$key\"". (variable_get("theme_default", key($themes)) == $key ? " SELECTED" : "") .">$key</OPTION>\n";
   $output .= form_item(t("Default theme"), "<SELECT NAME=\"edit[theme_default]\">$options</SELECT>", t("The default theme as seen by new visitors and anonymous users."));
   $output .= "<HR>\n";
 
   // development settings:
   $output .= "<H3>Development settings</H3>\n";
-  $output .= form_select(t("Display timings"), "dev_timing", variable_get(dev_timing, 0), array("Disabled", "Enabled"), t("Display the time it took to generate a page: for Drupal development only."));
+  $output .= form_select(t("Display timer information"), "dev_timer", variable_get("dev_timer", 0), array("Disabled", "Enabled"), t("Display the time it took to generate a page.  For Drupal development only."));
+  $output .= "<HR>\n";
 
   return $output;
 }
 
-function setting_modules() {
+function conf_view_module() {
   foreach (module_list() as $name) {
-    if (module_hook($name, "conf")) {
-      $output .= "<H3>". ucfirst($name) ." module</H3>\n";
-      $output .= module_invoke($name, "conf");
-      $output .= "<HR>\n";
+    if (module_hook($name, "conf_options")) {
+      $output .= "<H3>". ucfirst($name) ." settings</H3>". module_invoke($name, "conf_options") ."<HR>\n";
     }
   }
   return $output;
 }
 
-function settings_save($edit = array()) {
-  // save variables:
-  foreach ($edit as $name=>$value) variable_set($name, $value);
+function conf_view_filter() {
+  foreach (module_list() as $name) {
+    if (module_hook($name, "conf_filters")) {
+      $output .= module_invoke($name, "conf_filters");
+    }
+  }
+  return $output;
+}
 
-  return "all settings have been saved.";
+function conf_save($edit = array()) {
+  foreach ($edit as $name=>$value) variable_set($name, $value);
+  return "the configuration options have been saved.";
 }
 
-function settings_default() {
-  db_query("DELETE FROM variable");
-  return "all settings have been reset to their default value.";
+function conf_default($edit = array()) {
+  foreach ($edit as $name=>$value) variable_del($name);
+  return "the configuration options have been reset to their default values.";
 }
 
-function settings_overview() {
-  global $settings;
+function conf_view($type) {
+  global $REQUEST_URI;
+
+  switch ($type) {
+    case "filter":
+      $form = conf_view_filter();
+      break;
+    case "module":
+      $form = conf_view_module();
+      break;
+    default:
+      $form = conf_view_system();
+  }
 
-  $form .= setting_modules();
-  $form .= form_submit("Save settings");
+  $form .= form_submit("Save configuration");
   $form .= form_submit("Reset to defaults");
 
-  return form("admin.php?mod=settings", $form);
+  return form($REQUEST_URI, $form);
 }
 
-function settings_admin() {
-  global $edit, $op;
+function conf_admin() {
+  global $edit, $op, $type;
 
-  print "<SMALL><A HREF=\"admin.php?mod=settings\">overview</A> | <A HREF=\"admin.php?mod=settings&op=help\">help</A></SMALL><HR>\n";
+  print "<SMALL><A HREF=\"admin.php?mod=conf&type=system\">system settings</A> | <A HREF=\"admin.php?mod=conf&type=module\">module settings</A> | <A HREF=\"admin.php?mod=conf&type=filter\">filters</A> | <A HREF=\"admin.php?mod=conf&op=help\">help</A></SMALL><HR>\n";
 
   switch ($op) {
     case "help":
-      settings_help();
+      conf_help();
       break;
     case "Reset to defaults":
-      print status(settings_default($edit));
-      print settings_overview();
+      print status(conf_default($edit));
+      print conf_view($type);
       break;
-    case "Save settings":
-      print status(settings_save($edit));
-      print settings_overview();
+    case "Save configuration":
+      print status(conf_save($edit));
+      print conf_view($type);
       break;
     default:
-      print settings_overview();
+      print conf_view($type);
   }
 }
 
diff --git a/modules/cvs.module b/modules/cvs.module
index f31dd2d26784233a7b344ec39172c25e401d3d60..1202047a6c52f9b788362241992818a23bb7b67b 100644
--- a/modules/cvs.module
+++ b/modules/cvs.module
@@ -17,7 +17,7 @@ function cvs_cron() {
   }
 }
 
-function cvs_conf() {
+function cvs_conf_options() {
   $period = array(43200 => format_interval(43200), 86400 => format_interval(86400), 172800 => format_interval(172800), 259200 => format_interval(259200), 604800 => format_interval(604800), 1209600 => format_interval(1209600));
   $output .= form_textfield(t("Digest recepients"), "cvs_mail", variable_get("cvs_mail", "root@localhost"), 30, 55, t("The e-mail address to mail the CVS log messages to.  Multiple recipients can be specified by putting a comma between each address."));
   $output .= form_select(t("Digest interval"), "cvs_cron_time" , variable_get("cvs_cron_time", 86400), $period, t("The time interval at which batched CVS digests are dispatched.  Requires crontab."));
diff --git a/modules/diary.module b/modules/diary.module
index d003c7cc11aac89662f8dbd531f0617b12abe72b..9cfb21c47f1d20f994a8937f8c23fcc0359149b2 100644
--- a/modules/diary.module
+++ b/modules/diary.module
@@ -72,13 +72,13 @@ function diary_page_display($username) {
 }
 
 function diary_page_add() {
-  global $theme, $user, $allowed_html;
+  global $theme, $user;
 
   $output .= "<FORM ACTION=\"module.php?mod=diary\" METHOD=\"post\">\n";
 
   $output .= "<P>\n";
   $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"15\" NAME=\"text\"></TEXTAREA><BR>\n";
-  $output .= " <SMALL><I>". t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html) .".</I></SMALL>\n";
+  $output .= " <SMALL><I>". t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")) .".</I></SMALL>\n";
   $output .= "</P>\n";
 
   $output .= "<P>\n";
@@ -98,7 +98,7 @@ function diary_page_delete($id) {
 }
 
 function diary_page_edit($id) {
-  global $theme, $user, $allowed_html;
+  global $theme, $user;
 
   $result = db_query("SELECT * FROM diaries WHERE id = '$id'");
   $diary = db_fetch_object($result);
@@ -107,8 +107,8 @@ function diary_page_edit($id) {
 
   $output .= "<FORM ACTION=\"module.php?mod=diary\" METHOD=\"post\">\n";
   $output .= "<P>\n";
-  $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"15\" NAME=\"text\">". check_textarea($diary->text) ."</TEXTAREA><BR>\n";
-  $output .= " <SMALL><I>". t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html) .".</I></SMALL>\n";
+  $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"15\" NAME=\"text\">". check_form($diary->text) ."</TEXTAREA><BR>\n";
+  $output .= " <SMALL><I>". t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")) .".</I></SMALL>\n";
   $output .= "</P>\n";
   $output .= "<P>\n";
   $output .= " <INPUT TYPE=\"hidden\" NAME=\"id\" VALUE=\"$diary->id\">\n";
@@ -123,14 +123,14 @@ function diary_page_edit($id) {
 }
 
 function diary_page_preview($text, $timestamp, $id = 0) {
-  global $theme, $user, $allowed_html;
+  global $theme, $user;
 
   $output .= diary_page_entry($timestamp, $text);
 
   $output .= "<FORM ACTION=\"module.php?mod=diary\" METHOD=\"post\">\n";
   $output .= "<P>\n";
-  $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"15\" NAME=\"text\">". check_textarea($text) ."</TEXTAREA><BR>\n";
-  $output .= " <SMALL><I>". t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html) .".</I></SMALL>\n";
+  $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"15\" NAME=\"text\">". check_form($text) ."</TEXTAREA><BR>\n";
+  $output .= " <SMALL><I>". t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")) .".</I></SMALL>\n";
   $output .= "</P>\n";
   $output .= "<P>\n";
   $output .= " <INPUT TYPE=\"hidden\" NAME=\"id\" VALUE=\"$id\">\n";
@@ -239,7 +239,7 @@ function diary_admin_edit($id) {
 
   $output .= "<P>\n";
   $output .= "<B>Diary entry:</B><BR>\n";
-  $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"10\" NAME=\"text\">". check_textarea($diary->text) ."</TEXTAREA><BR>\n";
+  $output .= " <TEXTAREA WRAP=\"virtual\" COLS=\"50\" ROWS=\"10\" NAME=\"text\">". check_form($diary->text) ."</TEXTAREA><BR>\n";
   $output .= "</P>\n";
 
   $output .= "<P>\n";
diff --git a/modules/headline.module b/modules/headline.module
index cfb347086ce59518070c228dd7678067b15e3269..1c6b417433c57e353dcf72b9334b015dbbf13aa3 100644
--- a/modules/headline.module
+++ b/modules/headline.module
@@ -11,7 +11,7 @@ function headline_help() {
  <?php
 }
 
-function headline_conf() {
+function headline_conf_options() {
   $period = array(900 => format_interval(900), 1800 => format_interval(1800), 3600 => format_interval(3600), 7200 => format_interval(7200), 10800 => format_interval(10800), 21600 => format_interval(21600), 32400 => format_interval(32400), 43200 => format_interval(43200), 64800 => format_interval(64800), 86400 => format_interval(86400));
   $output .= form_select(t("Update interval"), "headline_cron_time" , variable_get("headline_cron_time", 86400), $period, t("The update interval indicating how often you want to update your headline channels.  Requires crontab."));
   return $output;
diff --git a/modules/locale.module b/modules/locale.module
index deb802b2977f0524545c3fa53d92745e044f894c..1e2a074c865a9da490c07d3c793ffdfeec2792b4 100644
--- a/modules/locale.module
+++ b/modules/locale.module
@@ -3,7 +3,7 @@
 function locale_help() {
  ?>
   <P>Normally programs are written and documented in English, and use English to interact with users.  This is true for a great deal of websites.  However, most people are less comfortable with English than with their own native language, and would prefer to use their mother tongue as much as possible.  Many people love see their website showing a lot less of English, and far more of their own language.</P>
-  <P>Therefore drupal provides a framework to setup a multi-lingual website, or to overwrite the default texts in English.  We explored the various alternatives to support internationalization and decided to design the framework in such a way that the impact of internationalization on drupal's sources is minimized, modular and that it doesn't require a HTML or PHP wizard to maintain translations.  Maintaining translations had to be simple so it became as easy as filling out forms on the administration page.  A side effect is that translation support adds significant overhead to the dynamic generation of your website.  If you don't need translation support, consider to turn it off.</P>
+  <P>Therefore drupal provides a framework to setup a multi-lingual website, or to overwrite the default texts in English.  We explored the various alternatives to support internationalization and decided to design the framework in such a way that the impact of internationalization on drupal's sources is minimized, modular and that it doesn't require a HTML or PHP wizard to maintain translations.  Maintaining translations had to be simple so it became as easy as filling out forms on the administration page.  A side effect is that translation support adds significant overhead to the dynamic generation of your website.  If you don't need translation support, consider to turning it off from the "conf" section.</P>
 
   <H3>Adding a new language</H3>
 
@@ -24,6 +24,10 @@ function locale_help() {
  <?php
 }
 
+function locale_conf_options() {
+  return form_select(t("Locale support"), "locale", variable_get("locale", 1), array("Disabled", "Enabled"), t("Disable locale support if your site does not require translation or internationalization support."));
+}
+
 function locale_delete($id) {
   db_query("DELETE FROM locales WHERE id = '$id'");
 }
diff --git a/modules/locale/locale.module b/modules/locale/locale.module
index deb802b2977f0524545c3fa53d92745e044f894c..1e2a074c865a9da490c07d3c793ffdfeec2792b4 100644
--- a/modules/locale/locale.module
+++ b/modules/locale/locale.module
@@ -3,7 +3,7 @@
 function locale_help() {
  ?>
   <P>Normally programs are written and documented in English, and use English to interact with users.  This is true for a great deal of websites.  However, most people are less comfortable with English than with their own native language, and would prefer to use their mother tongue as much as possible.  Many people love see their website showing a lot less of English, and far more of their own language.</P>
-  <P>Therefore drupal provides a framework to setup a multi-lingual website, or to overwrite the default texts in English.  We explored the various alternatives to support internationalization and decided to design the framework in such a way that the impact of internationalization on drupal's sources is minimized, modular and that it doesn't require a HTML or PHP wizard to maintain translations.  Maintaining translations had to be simple so it became as easy as filling out forms on the administration page.  A side effect is that translation support adds significant overhead to the dynamic generation of your website.  If you don't need translation support, consider to turn it off.</P>
+  <P>Therefore drupal provides a framework to setup a multi-lingual website, or to overwrite the default texts in English.  We explored the various alternatives to support internationalization and decided to design the framework in such a way that the impact of internationalization on drupal's sources is minimized, modular and that it doesn't require a HTML or PHP wizard to maintain translations.  Maintaining translations had to be simple so it became as easy as filling out forms on the administration page.  A side effect is that translation support adds significant overhead to the dynamic generation of your website.  If you don't need translation support, consider to turning it off from the "conf" section.</P>
 
   <H3>Adding a new language</H3>
 
@@ -24,6 +24,10 @@ function locale_help() {
  <?php
 }
 
+function locale_conf_options() {
+  return form_select(t("Locale support"), "locale", variable_get("locale", 1), array("Disabled", "Enabled"), t("Disable locale support if your site does not require translation or internationalization support."));
+}
+
 function locale_delete($id) {
   db_query("DELETE FROM locales WHERE id = '$id'");
 }
diff --git a/modules/node.module b/modules/node.module
index 53c32219f62075ad2d1b67a12d1eaee27e3f599c..98b6482ef70fd24fec74de01912e324c54223a3a 100644
--- a/modules/node.module
+++ b/modules/node.module
@@ -11,13 +11,34 @@ function Node($node) {
   }
 }
 
-function node_macro($text) {
+function node_conf_filters() {
+  $output .= form_select(t("Strip HTML tags"), "filter_html", variable_get("filter_html", 0), array("Disabled", "Enabled"), t("Strip HTML and PHP tags."));
+  $output .= form_textfield(t("Allowed HTML tags"), "allowed_html", variable_get("allowed_html", "<A><B><BLOCKQUOTE><DD><DL><DT><I><LI><OL><U><UL>"), 64, 128, t("If enabled, optionally specify tags which should not be stripped.  'STYLE' attributes, 'ON' attributes and unclosed tags are always stripped."));
+  $output .= "<HR>";
+  $output .= form_select(t("Strip link tags"), "filter_link", variable_get("filter_link", 0), array("Disabled", "Enabled"), t("Substitute special [[link]] tags."));
+  $output .= "<HR>";
+  return $output;
+}
+
+function node_filter_html($text) {
+  $text = eregi_replace("([ \f\r\t\n\'\"])style=[^>]+", "\\1", $text);
+  $text = eregi_replace("([ \f\r\t\n\'\"])on[a-z]+=[^>]+", "\\1", $text);
+  $text = strip_tags($text, variable_get("allowed_html", ""));
+  return $text;
+}
+
+function node_filter_link($text) {
   $src = array("/\[\[(([^\|]*?)(\|([^\|]*?))?)\]\]/e");  // [link|description]
   $dst = array(format_tag('\\2', '\\4'));                // [link|description]
-
   return preg_replace($src, $dst, $text);
 }
 
+function node_filter($text) {
+  if (variable_get("filter_html", 0)) $text = node_filter_html($text);
+  if (variable_get("filter_link", 0)) $text = node_filter_link($text);
+  return $text;
+}
+
 function node_overview($query = array()) {
   global $user;
 
diff --git a/modules/node/node.module b/modules/node/node.module
index 53c32219f62075ad2d1b67a12d1eaee27e3f599c..98b6482ef70fd24fec74de01912e324c54223a3a 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -11,13 +11,34 @@ function Node($node) {
   }
 }
 
-function node_macro($text) {
+function node_conf_filters() {
+  $output .= form_select(t("Strip HTML tags"), "filter_html", variable_get("filter_html", 0), array("Disabled", "Enabled"), t("Strip HTML and PHP tags."));
+  $output .= form_textfield(t("Allowed HTML tags"), "allowed_html", variable_get("allowed_html", "<A><B><BLOCKQUOTE><DD><DL><DT><I><LI><OL><U><UL>"), 64, 128, t("If enabled, optionally specify tags which should not be stripped.  'STYLE' attributes, 'ON' attributes and unclosed tags are always stripped."));
+  $output .= "<HR>";
+  $output .= form_select(t("Strip link tags"), "filter_link", variable_get("filter_link", 0), array("Disabled", "Enabled"), t("Substitute special [[link]] tags."));
+  $output .= "<HR>";
+  return $output;
+}
+
+function node_filter_html($text) {
+  $text = eregi_replace("([ \f\r\t\n\'\"])style=[^>]+", "\\1", $text);
+  $text = eregi_replace("([ \f\r\t\n\'\"])on[a-z]+=[^>]+", "\\1", $text);
+  $text = strip_tags($text, variable_get("allowed_html", ""));
+  return $text;
+}
+
+function node_filter_link($text) {
   $src = array("/\[\[(([^\|]*?)(\|([^\|]*?))?)\]\]/e");  // [link|description]
   $dst = array(format_tag('\\2', '\\4'));                // [link|description]
-
   return preg_replace($src, $dst, $text);
 }
 
+function node_filter($text) {
+  if (variable_get("filter_html", 0)) $text = node_filter_html($text);
+  if (variable_get("filter_link", 0)) $text = node_filter_link($text);
+  return $text;
+}
+
 function node_overview($query = array()) {
   global $user;
 
diff --git a/modules/poll.module b/modules/poll.module
index c79723b09cf429949e218de181736fc610490578..06661ba511b398e7522a505a02f2db408072e468 100644
--- a/modules/poll.module
+++ b/modules/poll.module
@@ -152,7 +152,7 @@ function poll_view($node, $main = 0, $block = 0) {
 }
 
 function poll_form($edit = array(), $nocheck = 0) {
-  global $allowed_html, $REQUEST_URI, $user;
+  global $REQUEST_URI, $user;
 
   $duration = array(0 => t("Unlimited"), 86400 => t("1 day"), 172800 => t("2 days"), 345600 => t("4 days"),
                     604800 => t("1 week"), 1209600 => t("2 weeks"), 2678400 => t("1 month"), 5356800 => t("2 months"),
@@ -281,7 +281,7 @@ function poll_admin() {
     case t("Refresh"):
       $refresh = 1;
     case t("Preview"):
-      poll_view(new Poll($edit));
+      poll_view(new Poll(node_preview($edit)));
     case "add":
       print poll_form($edit, $refresh);
       break;
@@ -301,7 +301,7 @@ function poll_user() {
     case t("Refresh"):
       $refresh = 1;
     case t("Preview"):
-      poll_view(new Poll($edit));
+      poll_view(new Poll(node_preview($edit)));
       $theme->box(t("Submit"), poll_form($edit, $refresh));
       break;
     case t("Submit"):
diff --git a/modules/poll/poll.module b/modules/poll/poll.module
index c79723b09cf429949e218de181736fc610490578..06661ba511b398e7522a505a02f2db408072e468 100644
--- a/modules/poll/poll.module
+++ b/modules/poll/poll.module
@@ -152,7 +152,7 @@ function poll_view($node, $main = 0, $block = 0) {
 }
 
 function poll_form($edit = array(), $nocheck = 0) {
-  global $allowed_html, $REQUEST_URI, $user;
+  global $REQUEST_URI, $user;
 
   $duration = array(0 => t("Unlimited"), 86400 => t("1 day"), 172800 => t("2 days"), 345600 => t("4 days"),
                     604800 => t("1 week"), 1209600 => t("2 weeks"), 2678400 => t("1 month"), 5356800 => t("2 months"),
@@ -281,7 +281,7 @@ function poll_admin() {
     case t("Refresh"):
       $refresh = 1;
     case t("Preview"):
-      poll_view(new Poll($edit));
+      poll_view(new Poll(node_preview($edit)));
     case "add":
       print poll_form($edit, $refresh);
       break;
@@ -301,7 +301,7 @@ function poll_user() {
     case t("Refresh"):
       $refresh = 1;
     case t("Preview"):
-      poll_view(new Poll($edit));
+      poll_view(new Poll(node_preview($edit)));
       $theme->box(t("Submit"), poll_form($edit, $refresh));
       break;
     case t("Submit"):
diff --git a/modules/rating.module b/modules/rating.module
index 3c3e301b72a8fcc3066ecf38f3465dcf45670d57..18a23841fff8c8ab68c518b84b5cd405a14f4f89 100644
--- a/modules/rating.module
+++ b/modules/rating.module
@@ -1,6 +1,6 @@
 <?php
 
-function rating_conf() {
+function rating_conf_options() {
   $period = array(3600 => format_interval(3600), 10800 => format_interval(10800), 21600 => format_interval(21600), 32400 => format_interval(32400), 43200 => format_interval(43200), 86400 => format_interval(86400), 172800 => format_interval(172800), 259200 => format_interval(259200), 604800 => format_interval(604800), 1209600 => format_interval(1209600));
   $output .= form_select(t("Update interval"), "rating_cron_time" , variable_get("rating_cron_time", 86400), $period, t("The update interval for the user ratings.  Requires crontab."));
   return $output;
diff --git a/modules/story.module b/modules/story.module
index 7f0c1ba6467cdd602adee441c73c15b69d5d55cd..935f0ca931f8a5a902b1360249b1b5e8ed718751 100644
--- a/modules/story.module
+++ b/modules/story.module
@@ -35,14 +35,14 @@ function story_view($node, $main = 0) {
 }
 
 function story_form($edit = array()) {
-  global $allowed_html, $REQUEST_URI, $user;
+  global $REQUEST_URI, $user;
 
   $form .= form_item(t("Your name"), format_username(($edit[userid] ? $edit[userid] : $user->userid)));
   $form .= form_hidden("userid", $edit[userid]);
   $form .= form_textfield(t("Subject"), "title", $edit[title], 50, 64);
   $form .= structure_form("story", $edit);
-  $form .= form_textarea(t("Abstract"), "abstract", $edit[abstract], 50, 10, t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html));
-  $form .= form_textarea(t("Body"), "body", $edit[body], 50, 15, t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html));
+  $form .= form_textarea(t("Abstract"), "abstract", $edit[abstract], 50, 10, t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")));
+  $form .= form_textarea(t("Body"), "body", $edit[body], 50, 15, t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")));
 
   // hidden fields:
   if ($edit[nid] > 0) {
@@ -148,7 +148,7 @@ function story_admin() {
       print search_data($keys, $mod);
       break;
     case t("Preview"):
-      story_view(new Story($edit));
+      story_view(new Story(node_preview($edit)));
       print story_form($edit);
       break;
     case t("Submit"):
@@ -165,7 +165,7 @@ function story_user() {
 
   switch($op) {
     case t("Preview"):
-      story_view(new Story($edit));
+      story_view(new Story(node_preview($edit)));
       $theme->box(t("Submit"), story_form($edit));
       break;
     case t("Submit"):
diff --git a/modules/story/story.module b/modules/story/story.module
index 7f0c1ba6467cdd602adee441c73c15b69d5d55cd..935f0ca931f8a5a902b1360249b1b5e8ed718751 100644
--- a/modules/story/story.module
+++ b/modules/story/story.module
@@ -35,14 +35,14 @@ function story_view($node, $main = 0) {
 }
 
 function story_form($edit = array()) {
-  global $allowed_html, $REQUEST_URI, $user;
+  global $REQUEST_URI, $user;
 
   $form .= form_item(t("Your name"), format_username(($edit[userid] ? $edit[userid] : $user->userid)));
   $form .= form_hidden("userid", $edit[userid]);
   $form .= form_textfield(t("Subject"), "title", $edit[title], 50, 64);
   $form .= structure_form("story", $edit);
-  $form .= form_textarea(t("Abstract"), "abstract", $edit[abstract], 50, 10, t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html));
-  $form .= form_textarea(t("Body"), "body", $edit[body], 50, 15, t("Allowed HTML tags") .": ". htmlspecialchars($allowed_html));
+  $form .= form_textarea(t("Abstract"), "abstract", $edit[abstract], 50, 10, t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")));
+  $form .= form_textarea(t("Body"), "body", $edit[body], 50, 15, t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", "")));
 
   // hidden fields:
   if ($edit[nid] > 0) {
@@ -148,7 +148,7 @@ function story_admin() {
       print search_data($keys, $mod);
       break;
     case t("Preview"):
-      story_view(new Story($edit));
+      story_view(new Story(node_preview($edit)));
       print story_form($edit);
       break;
     case t("Submit"):
@@ -165,7 +165,7 @@ function story_user() {
 
   switch($op) {
     case t("Preview"):
-      story_view(new Story($edit));
+      story_view(new Story(node_preview($edit)));
       $theme->box(t("Submit"), story_form($edit));
       break;
     case t("Submit"):
diff --git a/modules/watchdog.module b/modules/watchdog.module
index 8397da6668b00de31929319db355f080d6621c60..6c40f7e140899125e409eb2d979f96124a4faf38 100644
--- a/modules/watchdog.module
+++ b/modules/watchdog.module
@@ -7,7 +7,7 @@ function watchdog_help() {
  <?php
 }
 
-function watchdog_conf() {
+function watchdog_conf_options() {
   $period = array(3600 => format_interval(3600), 10800 => format_interval(10800), 21600 => format_interval(21600), 32400 => format_interval(32400), 43200 => format_interval(43200), 86400 => format_interval(86400), 172800 => format_interval(172800), 259200 => format_interval(259200), 604800 => format_interval(604800), 1209600 => format_interval(1209600), 2419200 => format_interval(2419200));
   $output .= form_select(t("Discard entries older than"), "watchdog_clear", variable_get("watchdog_clear", 604800), $period, t("The time watchdog entries should be kept.  Older entries will be automatically discarded.  Requires crontab."));
   return $output;
diff --git a/modules/watchdog/watchdog.module b/modules/watchdog/watchdog.module
index 8397da6668b00de31929319db355f080d6621c60..6c40f7e140899125e409eb2d979f96124a4faf38 100644
--- a/modules/watchdog/watchdog.module
+++ b/modules/watchdog/watchdog.module
@@ -7,7 +7,7 @@ function watchdog_help() {
  <?php
 }
 
-function watchdog_conf() {
+function watchdog_conf_options() {
   $period = array(3600 => format_interval(3600), 10800 => format_interval(10800), 21600 => format_interval(21600), 32400 => format_interval(32400), 43200 => format_interval(43200), 86400 => format_interval(86400), 172800 => format_interval(172800), 259200 => format_interval(259200), 604800 => format_interval(604800), 1209600 => format_interval(1209600), 2419200 => format_interval(2419200));
   $output .= form_select(t("Discard entries older than"), "watchdog_clear", variable_get("watchdog_clear", 604800), $period, t("The time watchdog entries should be kept.  Older entries will be automatically discarded.  Requires crontab."));
   return $output;
diff --git a/node.php b/node.php
index d6c498e318df1cc19034bcf87ee647e779655b51..09534383fefaaf896c386eb410c014c373f593e4 100644
--- a/node.php
+++ b/node.php
@@ -2,7 +2,7 @@
 
 include_once "includes/common.inc";
 
-if (variable_get(dev_timing, 0)) timer_start();
+page_header();
 
 function node_render($node) {
   global $id, $cid, $op, $moderate, $pid, $subject, $comment, $theme, $mode, $order, $threshold, $PHP_SELF;
@@ -114,6 +114,6 @@ function node_history($node) {
   node_failure();
 }
 
-if (variable_get(dev_timing, 0)) timer_print();
+page_footer();
 
 ?>
\ No newline at end of file
diff --git a/search.php b/search.php
index 1fc46bc109e5c9156d4f260782228b83db1b98a5..59b5aace17b5e6b0ee0a3d06656421a7994f94d7 100644
--- a/search.php
+++ b/search.php
@@ -10,7 +10,7 @@ function find_module($name) {
 module_iterate("find_module");
 
 $search .= "<FORM ACTION=\"search.php\" METHOD=\"POST\">\n";
-$search .= " <INPUT SIZE=\"50\" VALUE=\"". check_textfield($keys) ."\" NAME=\"keys\" TYPE=\"text\">\n";
+$search .= " <INPUT SIZE=\"50\" VALUE=\"". check_form($keys) ."\" NAME=\"keys\" TYPE=\"text\">\n";
 $search .= " <SELECT NAME=\"type\">$options</SELECT>\n";
 $search .= " <INPUT TYPE=\"submit\" VALUE=\"". t("Search") ."\">\n";
 $search .= "</FORM>\n";
diff --git a/submit.php b/submit.php
index 484e532c855424a2a4e99e35020de1468c32c542..3d5d0af1931712f2c1206c497b7ea8c4bcc53895 100644
--- a/submit.php
+++ b/submit.php
@@ -2,8 +2,6 @@
 
 include_once "includes/common.inc";
 
-if (variable_get(dev_timing, 0)) timer_start();
-
 $theme->header();
 
 if ($user->id) {
@@ -32,6 +30,4 @@
 
 $theme->footer();
 
-if (variable_get(dev_timing, 0)) timer_print();
-
 ?>