diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 0e3f3cc..ed14ffe 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,8 +1,9 @@
-ThemeKey 6.x-3.7, 2011-09-28
-----------------------------
+ThemeKey 6.x-4.0-beta1, 2011-xx-xx
+----------------------------------
 [#1290754] mkalkbrenner: ThemeKey not working for block detail configuration
 [#1252846] mkalkbrenner: Use of undefined constants when running install.php
 [#1293182] mkalkbrenner: disable theme switching during drupal installation or update
+[#1298644] mkalkbrenner: new operators "*", "!*", "!~"
 
 
 ThemeKey 6.x-3.6, 2011-09-19
diff --git a/themekey_admin.inc b/themekey_admin.inc
index 9f09533..ecb2d9d 100644
--- a/themekey_admin.inc
+++ b/themekey_admin.inc
@@ -1,3 +1,5 @@
++    '*' => '*',
++    '!*' => '!*',
 <?php
 
 /**
@@ -43,11 +45,14 @@ function themekey_rule_chain_form() {
   $operators = array(
     '=' => '=',
     '!' => '!',
+    '*' => '*',
+    '!*' => '!*',
     '<' => '<',
     '<=' => '<=',
     '>' => '>',
     '>=' => '>=',
     '~' => '~',
+    '!~' => '!~',
   );
 
   $form = array('#tree' => TRUE);
@@ -255,6 +260,18 @@ function themekey_form_alter(&$form, $form_state, $form_id) {
               themekey_rule_chain_form_set_error($form, $key_1, 'property', t('ThemeKey requested an unknown validator called %validator to validate property %property', array('%validator' => $validator, '%property' => $value_1['property']['#default_value'])));
             }
           }
+          elseif ('~' == $value_1['operator']['#default_value'] || '!~' == $value_1['operator']['#default_value']) {
+            $rule = array(
+              'property' => $value_1['property']['#default_value'],
+              'wildcard' => $value_1['wildcard']['#default_value'],
+              'operator' => $value_1['operator']['#default_value'],
+              'value' => $value_1['value']['#default_value'],
+            );
+            $errors = themekey_validator_regex($rule);
+            foreach ($errors as $element => $msg) {
+              themekey_rule_chain_form_set_error($form, $key_1, $element, $msg);
+            }
+          }
 
           foreach ($form['old_items'] as $key_2 => $value_2) {
             if ($key_2 == $key_1) {
diff --git a/themekey_base.inc b/themekey_base.inc
index 492bae1..1f639b6 100644
--- a/themekey_base.inc
+++ b/themekey_base.inc
@@ -353,26 +353,35 @@ function themekey_match_condition($condition, &$parameters) {
           // Supported operators for condition check:
           // smaller ('<'), greater ('>'), equal ('='), not equal ('!'), regex match ('~')
           if ($condition['operator'] == '<' && $single_value >= $condition['value']) {
-            return FALSE;
+            return FALSE; // all values need to not match
           }
           elseif ($condition['operator'] == '>' && $single_value <= $condition['value']) {
-            return FALSE;
+            return FALSE; // all values need to not match
           }
           elseif ($condition['operator'] == '<=' && $single_value > $condition['value']) {
-            return FALSE;
+            return FALSE; // all values need to not match
           }
           elseif ($condition['operator'] == '>=' && $single_value < $condition['value']) {
-            return FALSE;
+            return FALSE; // all values need to not match
           }
           elseif ($condition['operator'] == '=' && $single_value == $condition['value']) {
             return TRUE;
           }
           elseif ($condition['operator'] == '!' && $single_value == $condition['value']) {
-            return FALSE;
+            return FALSE; // all values need to not match
+          }
+          elseif ($condition['operator'] == '*' && strpos($single_value, $condition['value']) !== FALSE) {
+            return TRUE;
+          }
+          elseif ($condition['operator'] == '!*' && strpos($single_value, $condition['value']) !== FALSE) {
+            return FALSE; // all values need to not match
           }
           elseif ($condition['operator'] == '~' && preg_match($condition['value'], $single_value)) {
             return TRUE;
           }
+          elseif ($condition['operator'] == '!~' && preg_match($condition['value'], $single_value)) {
+            return FALSE; // all values need to not match
+          }
         }
         else {
           // value is NULL
@@ -380,7 +389,7 @@ function themekey_match_condition($condition, &$parameters) {
         }
       }
 
-      if ($condition['operator'] == '=' || $condition['operator'] == '~') {
+      if ($condition['operator'] == '=' || $condition['operator'] == '~' || $condition['operator'] == '*') {
         // no value matched
         return FALSE;
       }
diff --git a/themekey_help.inc b/themekey_help.inc
index 5863ac5..5f9ecf4 100644
--- a/themekey_help.inc
+++ b/themekey_help.inc
@@ -200,6 +200,16 @@ function themekey_help_operators_form($form_state, $collapsed = TRUE) {
     '#value' => t('<strong>!</strong><br />not equal to'),
   );
 
+  $form['themekey_help_operators']['*'] = array(
+    '#type' => 'item',
+    '#markup' => t('<strong>*</strong><br />contains'),
+  );
+
+  $form['themekey_help_operators']['!*'] = array(
+    '#type' => 'item',
+    '#markup' => t('<strong>!*</strong><br />not contains'),
+  );
+
   $form['themekey_help_operators']['<'] = array(
     '#type' => 'item',
     '#value' => t('<strong>&lt;</strong><br />less than (alphanumeric values are treated in alphabetical order: "A" is less than "B", but "B" is less than "a")'),
@@ -225,5 +235,10 @@ function themekey_help_operators_form($form_state, $collapsed = TRUE) {
     '#value' => t('<strong>~</strong><br />regular expression including delimiters and modifiers (see !link)', array('!link' => l(t('PHP Manual'), 'http://php.net/manual/en/pcre.pattern.php'))),
   );
 
+  $form['themekey_help_operators']['!~'] = array(
+    '#type' => 'item',
+    '#markup' => t('<strong>!~</strong><br />non matchting regular expression, including delimiters and modifiers (see !link)', array('!link' => l(t('PHP Manual'), 'http://php.net/manual/en/pcre.pattern.php'))),
+  );
+
   return $form;
 }
diff --git a/themekey_validators.inc b/themekey_validators.inc
index fa9ab14..915ded1 100644
--- a/themekey_validators.inc
+++ b/themekey_validators.inc
@@ -9,7 +9,7 @@
  * @author Markus Kalkbrenner | Cocomore AG
  *   @see http://drupal.org/user/124705
  *
- * @author Carsten MÃ¼ller | Cocomore AG
+ * @author Carsten MŸller | Cocomore AG
  *   @see http://drupal.org/user/124707
  */
 
@@ -24,7 +24,7 @@
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (e.g. "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
@@ -68,7 +68,7 @@ function themekey_validator_string_boolean($rule) {
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (p.e. "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
@@ -111,7 +111,7 @@ function themekey_validator_nummeric_boolean($rule) {
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (e.g., "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
@@ -130,7 +130,8 @@ function themekey_validator_ctype_digit($rule) {
   $errors = array();
   switch ($rule['operator']) {
     case '~':
-      $errors['operator'] = t('Possible operators are "=", "!", "<", "<=", ">" and ">="');
+    case '!~':
+      $errors['operator'] = t('Possible operators are "=", "!", "*", "!*", "<", "<=", ">" and ">="');
       break;
   }
 
@@ -155,7 +156,7 @@ function themekey_validator_ctype_digit($rule) {
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (e.g., "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
@@ -174,6 +175,7 @@ function themekey_validator_language($rule) {
   $errors = array();
   switch ($rule['operator']) {
     case '=':
+    case '!':
       $languages = language_list();
       // add 'neutral' to the list of languages
       $languages['neutral'] = TRUE;
@@ -183,6 +185,7 @@ function themekey_validator_language($rule) {
       break;
 
     case '~':
+    case '!~':
       $errors = themekey_validator_regex($rule);
       break;
   }
@@ -203,7 +206,7 @@ function themekey_validator_language($rule) {
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (e.g. "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
@@ -224,13 +227,21 @@ function themekey_validator_date_time($rule) {
     case '=':
     case '!':
       // It seems senseless to switch a theme for one second
-      $errors['operator'] = t('Possible operators are "<", "<=", ">", ">=" and "~"');
+      $errors['operator'] = t('Possible operators are "*", "!*", "<", "<=", ">", ">=", "~", "!~"');
       break;
 
     case '~':
+    case '!~':
       $errors = themekey_validator_regex($rule);
       break;
 
+    case '*':
+    case '!*':
+      if (!preg_match("/^[\d\- :]+$/", $rule['value'])) {
+        $errors['value'] = t("Value isn't suitable for checks against dates formatted like \"2009-12-24 23:56:17\"");
+      }
+      break;
+
     default:
       if (!preg_match("/^[0-9]{4}[0-9\- :]*$/", $rule['value'])) {
         $errors['value'] = t("Value isn't suitable for checks against dates formatted like \"2009-12-24 23:56:17\"");
@@ -255,7 +266,7 @@ function themekey_validator_date_time($rule) {
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (p.e. "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
@@ -281,9 +292,17 @@ function themekey_validator_date($rule) {
       break;
 
     case '~':
+    case '!~':
       $errors = themekey_validator_regex($rule);
       break;
 
+    case '*':
+    case '!*':
+      if (!preg_match("/^[\d\-]+$/", $rule['value'])) {
+        $errors['value'] = t("Value isn't suitable for checks against dates formatted like \"2009-12-24\"");
+      }
+      break;
+
     default:
       if (!preg_match("/^[0-9]{4}[0-9\-]*$/", $rule['value'])) {
         $errors['value'] = t("Value isn't suitable for checks against dates formatted like \"2009-12-24\"");
@@ -308,7 +327,7 @@ function themekey_validator_date($rule) {
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (p.e. "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
@@ -334,12 +353,20 @@ function themekey_validator_time($rule) {
       break;
 
     case '~':
+    case '!~':
       $errors = themekey_validator_regex($rule);
       break;
 
+    case '*':
+    case '!*':
+      if (!preg_match("/^[\d:]+$/", $rule['value'])) {
+        $errors['value'] = t("Value isn't suitable for checks against times formatted like \"23:56:17\"");
+      }
+      break;
+
     default:
       if (!preg_match("/^[0-2][0-9][0-9:]*$/", $rule['value'])) {
-        $errors['value'] = t("Value isn't suitable for checks against dates formatted like \"23:16:56\"");
+        $errors['value'] = t("Value isn't suitable for checks against times formatted like \"23:16:56\"");
       }
   }
 
@@ -361,7 +388,7 @@ function themekey_validator_time($rule) {
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (p.e. "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
@@ -388,6 +415,7 @@ function themekey_validator_node_type($rule) {
       break;
 
     case '~':
+    case '!~':
       $errors = themekey_validator_regex($rule);
       break;
 
@@ -414,7 +442,7 @@ function themekey_validator_node_type($rule) {
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (p.e. "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
@@ -433,6 +461,7 @@ function themekey_validator_http_host($rule) {
   $errors = array();
   switch ($rule['operator']) {
     case '~':
+    case '!~':
       $errors = themekey_validator_regex($rule);
       break;
 
@@ -456,7 +485,7 @@ function themekey_validator_http_host($rule) {
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (p.e. "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
@@ -492,7 +521,7 @@ function themekey_validator_no_whitespace($rule) {
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (p.e. "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
@@ -533,7 +562,7 @@ function themekey_validator_wildcard($rule) {
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (p.e. "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
@@ -552,6 +581,7 @@ function themekey_validator_regex($rule) {
   $errors = array();
   switch ($rule['operator']) {
     case '~':
+    case '!~':
       if (FALSE === @preg_match($rule['value'], 'dummy')) {
         $errors['value'] = t('Regular expression seems to be malformed. See !link for details', array('!link' => l(t('PHP Manual'), 'http://php.net/manual/en/pcre.pattern.php')));
       }
@@ -564,18 +594,6 @@ function themekey_validator_regex($rule) {
 
   return $errors;
 }
-/**
- * @file
- * Provides set of validators which can be used to validate
- * ThemeKey Theme Switching Rules.
- * @see themekey_admin.inc
- *
- * @author Markus Kalkbrenner | Cocomore AG
- *   @see http://drupal.org/user/124705
- *
- * @author Carsten MÃ¼ller | Cocomore AG
- *   @see http://drupal.org/user/124707
- */
 
 
 /**
@@ -588,7 +606,7 @@ function themekey_validator_regex($rule) {
  *   A Theme Switching Rule as associative array:
  *   - property: ThemeKey property as string (p.e. "drupal:path")
  *   - wildcard: optional string, only used if property is "drupal:path:wildcard"
- *   - operator: ThemeKey operator as string ("=", "!", "<". "<=", ">", ">=", "~")
+ *   - operator: ThemeKey operator as string ("=", "!", "*", "!*", "<", "<=", ">", ">=", "~", "!~")
  *   - value: ThemeKey property value as string
  *
  * @return
