diff --git a/lib/plugins/authldap/lang/en/settings.php b/lib/plugins/authldap/lang/en/settings.php
index e3f385f99d513f9343991bf644ad8c75f2035dc5..b73166ab2205b12bd27c3bf2be1d54d347ab9049 100644
--- a/lib/plugins/authldap/lang/en/settings.php
+++ b/lib/plugins/authldap/lang/en/settings.php
@@ -20,4 +20,4 @@ $lang['debug']       = 'Display additional debug information on errors';
 $lang['deref_o_0']   = 'LDAP_DEREF_NEVER';
 $lang['deref_o_1']   = 'LDAP_DEREF_SEARCHING';
 $lang['deref_o_2']   = 'LDAP_DEREF_FINDING';
-$lang['deref_o_3']   = 'LDAP_DEREF_ALWAYS';
\ No newline at end of file
+$lang['deref_o_3']   = 'LDAP_DEREF_ALWAYS';
diff --git a/lib/plugins/config/settings/config.class.php b/lib/plugins/config/settings/config.class.php
index 63be3a7261fb071910e354952627dd38563d9351..6d582ad3077ae668df36211e28182f9c91e529c8 100644
--- a/lib/plugins/config/settings/config.class.php
+++ b/lib/plugins/config/settings/config.class.php
@@ -366,12 +366,11 @@ if (!class_exists('setting')) {
     var $_pattern = '';
     var $_error = false;            // only used by those classes which error check
     var $_input = null;             // only used by those classes which error check
+    var $_caution = null;           // used by any setting to provide an alert along with the setting
+                                    // valid alerts, 'warning', 'danger', 'security'
+                                    // images matching the alerts are in the plugin's images directory
 
-    var $_cautionList = array(
-        'basedir' => 'danger', 'baseurl' => 'danger', 'savedir' => 'danger', 'cookiedir' => 'danger', 'useacl' => 'danger', 'authtype' => 'danger', 'superuser' => 'danger', 'userewrite' => 'danger',
-        'start' => 'warning', 'camelcase' => 'warning', 'deaccent' => 'warning', 'sepchar' => 'warning', 'compression' => 'warning', 'xsendfile' => 'warning', 'renderer_xhtml' => 'warning', 'fnencode' => 'warning',
-        'allowdebug' => 'security', 'htmlok' => 'security', 'phpok' => 'security', 'iexssprotect' => 'security', 'remote' => 'security', 'fullpath' => 'security'
-    );
+    static protected $_validCautions = array('warning','danger','security');
 
     function setting($key, $params=null) {
         $this->_key = $key;
@@ -473,8 +472,22 @@ if (!class_exists('setting')) {
     function error() { return $this->_error; }
 
     function caution() {
-        if (!array_key_exists($this->_key, $this->_cautionList)) return false;
-        return $this->_cautionList[$this->_key];
+        if (!empty($this->_caution)) {
+            if (!in_array($this->_caution, setting::$_validCautions)) {
+                trigger_error('Invalid caution string ('.$this->_caution.') in metadata for setting "'.$this->_key.'"', E_USER_WARNING);
+                return false;
+            }
+            return $this->_caution;
+        }
+        // compatibility with previous cautionList
+        // TODO: check if any plugins use; remove
+        if (!empty($this->_cautionList[$this->_key])) {
+            $this->_caution = $this->_cautionList[$this->_key];
+            unset($this->_cautionList);
+
+            return $this->caution();
+        }
+        return false;
     }
 
     function _out_key($pretty=false,$url=false) {
@@ -659,10 +672,8 @@ if (!class_exists('setting_password')) {
 }
 
 if (!class_exists('setting_email')) {
-  if (!defined('SETTING_EMAIL_PATTERN')) define('SETTING_EMAIL_PATTERN','<^'.PREG_PATTERN_VALID_EMAIL.'$>');
 
   class setting_email extends setting_string {
-    var $_pattern = SETTING_EMAIL_PATTERN;       // no longer required, retained for backward compatibility - FIXME, may not be necessary
     var $_multiple = false;
     var $_placeholders = false;
 
@@ -1107,96 +1118,39 @@ if (!class_exists('setting_multicheckbox')) {
   }
 }
 
-/**
- *  Provide php_strip_whitespace (php5 function) functionality
- *
- *  @author   Chris Smith <chris@jalakai.co.uk>
- */
-if (!function_exists('php_strip_whitespace'))  {
-
-  if (function_exists('token_get_all')) {
-
-    if (!defined('T_ML_COMMENT')) {
-      define('T_ML_COMMENT', T_COMMENT);
-    } else {
-      define('T_DOC_COMMENT', T_ML_COMMENT);
-    }
+if (!class_exists('setting_regex')){
+   class setting_regex extends setting_string {
 
-    /**
-     * modified from original
-     * source Google Groups, php.general, by David Otton
-     */
-    function php_strip_whitespace($file) {
-        if (!@is_readable($file)) return '';
+        var $_delimiter = '/';    // regex delimiter to be used in testing input
+        var $_pregflags = 'ui';   // regex pattern modifiers to be used in testing input
 
-        $in = join('',@file($file));
-        $out = '';
+        /**
+         *  update changed setting with user provided value $input
+         *  - if changed value fails error check, save it to $this->_input (to allow echoing later)
+         *  - if changed value passes error check, set $this->_local to the new value
+         *
+         *  @param  mixed   $input   the new value
+         *  @return boolean          true if changed, false otherwise (incl. on error)
+         */
+        function update($input) {
 
-        $tokens = token_get_all($in);
+            // let parent do basic checks, value, not changed, etc.
+            $local = $this->_local;
+            if (!parent::update($input)) return false;
+            $this->_local = $local;
 
-        foreach ($tokens as $token) {
-          if (is_string ($token)) {
-            $out .= $token;
-          } else {
-            list ($id, $text) = $token;
-            switch ($id) {
-              case T_COMMENT : // fall thru
-              case T_ML_COMMENT : // fall thru
-              case T_DOC_COMMENT : // fall thru
-              case T_WHITESPACE :
-                break;
-              default : $out .= $text; break;
+            // see if the regex compiles and runs (we don't check for effectiveness)
+            $regex = $this->_delimiter . $input . $this->_delimiter . $this->_pregflags;
+            $lastError = error_get_last();
+            $ok = @preg_match($regex,'testdata');
+            if (preg_last_error() != PREG_NO_ERROR || error_get_last() != $lastError) {
+                $this->_input = $input;
+                $this->_error = true;
+                return false;
             }
-          }
-        }
-        return ($out);
-    }
-
-  } else {
-
-    function is_whitespace($c) { return (strpos("\t\n\r ",$c) !== false); }
-    function is_quote($c) { return (strpos("\"'",$c) !== false); }
-    function is_escaped($s,$i) {
-        $idx = $i-1;
-        while(($idx>=0) && ($s{$idx} == '\\')) $idx--;
-        return (($i - $idx + 1) % 2);
-    }
-
-    function is_commentopen($str, $i) {
-        if ($str{$i} == '#') return "\n";
-        if ($str{$i} == '/') {
-          if ($str{$i+1} == '/') return "\n";
-          if ($str{$i+1} == '*') return "*/";
-        }
-
-        return false;
-    }
-
-    function php_strip_whitespace($file) {
-
-        if (!@is_readable($file)) return '';
 
-        $contents = join('',@file($file));
-        $out = '';
-
-        $state = 0;
-        for ($i=0; $i<strlen($contents); $i++) {
-          if (!$state && is_whitespace($contents{$i})) continue;
-
-          if (!$state && ($c_close = is_commentopen($contents, $i))) {
-            $c_open_len = ($contents{$i} == '/') ? 2 : 1;
-            $i = strpos($contents, $c_close, $i+$c_open_len)+strlen($c_close)-1;
-            continue;
-          }
-
-          $out .= $contents{$i};
-          if (is_quote($contents{$i})) {
-              if (($state == $contents{$i}) && !is_escaped($contents, $i)) { $state = 0; continue; }
-            if (!$state) {$state = $contents{$i}; continue; }
-          }
+            $this->_local = $input;
+            return true;
         }
-
-        return $out;
     }
-  }
 }
diff --git a/lib/plugins/config/settings/config.metadata.php b/lib/plugins/config/settings/config.metadata.php
index 5d9b049a43339f652ec268f6f100de7d3ec5f240..f4c2ed2651a373753d9734a4ee510a1e4d6b3afb 100644
--- a/lib/plugins/config/settings/config.metadata.php
+++ b/lib/plugins/config/settings/config.metadata.php
@@ -34,6 +34,9 @@
  *   'array'        - a simple (one dimensional) array of string values, shown as comma separated list in the
  *                    config manager but saved as PHP array(). Values may not contain commas themselves.
  *                    _pattern matching on the array values supported.
+ *   'regex'        - regular expression string, normally without delimiters; as for string, in addition tested
+ *                    to see if will compile & run as a regex.  in addition to _pattern, also accepts _delimiter
+ *                    (default '/') and _pregflags (default 'ui')
  *
  *  Single Setting (source: settings/extra.class.php)
  *  -------------------------------------------------
@@ -43,10 +46,13 @@
  *   'im_convert'  - as 'setting', input must exist and be an im_convert module
  *   'disableactions' - as 'setting'
  *   'compression' - no additional parameters. checks php installation supports possible compression alternatives
+ *   'licence'     - as multichoice, selection constructed from licence strings in language files
+ *   'renderer'    - as multichoice, selection constructed from enabled renderer plugins which canRender()
  *
  *  Any setting commented or missing will use 'setting' class - text input, minimal validation, quoted output
  *
  * Defined parameters:
+ *   '_caution'    - no value (default) or 'warning', 'danger', 'security'. display an alert along with the setting
  *   '_pattern'    - string, a preg pattern. input is tested against this pattern before being accepted
  *                   optional all classes, except onoff & multichoice which ignore it
  *   '_choices'    - array of choices. used to populate a selection box. choice will be replaced by a localised
@@ -59,6 +65,9 @@
  *   '_code'       - encoding method to use, accepted values: 'base64','uuencode','plain'.  defaults to plain.
  *   '_min'        - minimum numeric value, optional for 'numeric' and 'numericopt', ignored by others
  *   '_max'        - maximum numeric value, optional for 'numeric' and 'numericopt', ignored by others
+ *   '_delimiter'  - string, default '/', a single character used as a delimiter for testing regex input values
+ *   '_pregflags'  - string, default 'ui', valid preg pattern modifiers used when testing regex input values, for more
+ *                   information see http://uk1.php.net/manual/en/reference.pcre.pattern.modifiers.php
  *   '_multiple'   - bool, allow multiple comma separated email values; optional for 'email', ignored by others
  *
  * @author    Chris Smith <chris@jalakai.co.uk>
@@ -83,26 +92,26 @@ $config['heading'] = 'Dokuwiki\'s Main Configuration File - Local Settings';
 
 $meta['_basic']   = array('fieldset');
 $meta['title']    = array('string');
-$meta['start']    = array('string','_pattern' => '!^[^:;/]+$!'); // don't accept namespaces
+$meta['start']    = array('string','_caution' => 'warning','_pattern' => '!^[^:;/]+$!'); // don't accept namespaces
 $meta['lang']     = array('dirchoice','_dir' => DOKU_INC.'inc/lang/');
 $meta['template'] = array('dirchoice','_dir' => DOKU_INC.'lib/tpl/','_pattern' => '/^[\w-]+$/');
 $meta['tagline']  = array('string');
 $meta['sidebar']  = array('string');
 $meta['license']  = array('license');
-$meta['savedir']  = array('savedir');
-$meta['basedir']  = array('string');
-$meta['baseurl']  = array('string');
-$meta['cookiedir'] = array('string');
+$meta['savedir']  = array('savedir','_caution' => 'danger');
+$meta['basedir']  = array('string','_caution' => 'danger');
+$meta['baseurl']  = array('string','_caution' => 'danger');
+$meta['cookiedir'] = array('string','_caution' => 'danger');
 $meta['dmode']    = array('numeric','_pattern' => '/0[0-7]{3,4}/'); // only accept octal representation
 $meta['fmode']    = array('numeric','_pattern' => '/0[0-7]{3,4}/'); // only accept octal representation
-$meta['allowdebug']  = array('onoff');
+$meta['allowdebug']  = array('onoff','_caution' => 'security');
 
 $meta['_display']    = array('fieldset');
 $meta['recent']      = array('numeric');
 $meta['recent_days'] = array('numeric');
 $meta['breadcrumbs'] = array('numeric','_min' => 0);
 $meta['youarehere']  = array('onoff');
-$meta['fullpath']    = array('onoff');
+$meta['fullpath']    = array('onoff','_caution' => 'security');
 $meta['typography']  = array('multichoice','_choices' => array(0,1,2));
 $meta['dformat']     = array('string');
 $meta['signature']   = array('string');
@@ -111,19 +120,19 @@ $meta['toptoclevel'] = array('multichoice','_choices' => array(1,2,3,4,5));   //
 $meta['tocminheads'] = array('multichoice','_choices' => array(0,1,2,3,4,5,10,15,20));
 $meta['maxtoclevel'] = array('multichoice','_choices' => array(0,1,2,3,4,5));
 $meta['maxseclevel'] = array('multichoice','_choices' => array(0,1,2,3,4,5)); // 0 for no sec edit buttons
-$meta['camelcase']   = array('onoff');
-$meta['deaccent']    = array('multichoice','_choices' => array(0,1,2));
+$meta['camelcase']   = array('onoff','_caution' => 'warning');
+$meta['deaccent']    = array('multichoice','_choices' => array(0,1,2),'_caution' => 'warning');
 $meta['useheading']  = array('multichoice','_choices' => array(0,'navigation','content',1));
 $meta['sneaky_index'] = array('onoff');
-$meta['hidepages']   = array('string');
+$meta['hidepages']   = array('regex');
 
 $meta['_authentication'] = array('fieldset');
-$meta['useacl']      = array('onoff');
+$meta['useacl']      = array('onoff','_caution' => 'danger');
 $meta['autopasswd']  = array('onoff');
-$meta['authtype']    = array('authtype');
+$meta['authtype']    = array('authtype','_caution' => 'danger');
 $meta['passcrypt']   = array('multichoice','_choices' => array('smd5','md5','apr1','sha1','ssha','lsmd5','crypt','mysql','my411','kmd5','pmd5','hmd5','mediawiki','bcrypt','djangomd5','djangosha1','sha512'));
 $meta['defaultgroup']= array('string');
-$meta['superuser']   = array('string');
+$meta['superuser']   = array('string','_caution' => 'danger');
 $meta['manager']     = array('string');
 $meta['profileconfirm'] = array('onoff');
 $meta['rememberme'] = array('onoff');
@@ -132,7 +141,7 @@ $meta['disableactions'] = array('disableactions',
                                 '_combine' => array('subscription' => array('subscribe','unsubscribe'), 'wikicode' => array('source','export_raw')));
 $meta['auth_security_timeout'] = array('numeric');
 $meta['securecookie'] = array('onoff');
-$meta['remote']       = array('onoff');
+$meta['remote']       = array('onoff','_caution' => 'security');
 $meta['remoteuser']   = array('string');
 
 $meta['_anti_spam']  = array('fieldset');
@@ -140,12 +149,12 @@ $meta['usewordblock']= array('onoff');
 $meta['relnofollow'] = array('onoff');
 $meta['indexdelay']  = array('numeric');
 $meta['mailguard']   = array('multichoice','_choices' => array('visible','hex','none'));
-$meta['iexssprotect']= array('onoff');
+$meta['iexssprotect']= array('onoff','_caution' => 'security');
 
 $meta['_editing']    = array('fieldset');
 $meta['usedraft']    = array('onoff');
-$meta['htmlok']      = array('onoff');
-$meta['phpok']       = array('onoff');
+$meta['htmlok']      = array('onoff','_caution' => 'security');
+$meta['phpok']       = array('onoff','_caution' => 'security');
 $meta['locktime']    = array('numeric');
 $meta['cachetime']   = array('numeric');
 
@@ -184,20 +193,20 @@ $meta['rss_show_summary'] = array('onoff');
 
 $meta['_advanced']   = array('fieldset');
 $meta['updatecheck'] = array('onoff');
-$meta['userewrite']  = array('multichoice','_choices' => array(0,1,2));
+$meta['userewrite']  = array('multichoice','_choices' => array(0,1,2),'_caution' => 'danger');
 $meta['useslash']    = array('onoff');
-$meta['sepchar']     = array('sepchar');
+$meta['sepchar']     = array('sepchar','_caution' => 'warning');
 $meta['canonical']   = array('onoff');
-$meta['fnencode']    = array('multichoice','_choices' => array('url','safe','utf-8'));
+$meta['fnencode']    = array('multichoice','_choices' => array('url','safe','utf-8'),'_caution' => 'warning');
 $meta['autoplural']  = array('onoff');
 $meta['compress']    = array('onoff');
 $meta['cssdatauri']  = array('numeric','_pattern' => '/^\d+$/');
 $meta['gzip_output'] = array('onoff');
 $meta['send404']     = array('onoff');
-$meta['compression'] = array('compression');
+$meta['compression'] = array('compression','_caution' => 'warning');
 $meta['broken_iua']  = array('onoff');
-$meta['xsendfile']   = array('multichoice','_choices' => array(0,1,2,3));
-$meta['renderer_xhtml'] = array('renderer','_format' => 'xhtml','_choices' => array('xhtml'));
+$meta['xsendfile']   = array('multichoice','_choices' => array(0,1,2,3),'_caution' => 'warning');
+$meta['renderer_xhtml'] = array('renderer','_format' => 'xhtml','_choices' => array('xhtml'),'_caution' => 'warning');
 $meta['readdircache'] = array('numeric');
 
 $meta['_network']    = array('fieldset');