public function __call($method, $params)
 {
     //this is b/c of the laziness above
     //examples: I2CE_FormField_DB_STRING_DISPLAYFIELDSTYLE_in
     if (preg_match('/^([0-9a-zA-Z_]+)_([a-zA-Z]+)FIELDSTYLE_([0-9a-zA-Z_]+)$/', $method, $matches)) {
         //I2CE_FormField_XXX->getLimitMenu_YYY($template,$vals,$reportformfield)
         //becomes a vall to the method: $this->XXXX_DISPLAYFIELDSTYLE_YYY($fieldObj,$template,$vals)
         if ($matches[2] !== 'PROCESS' && $matches[2] !== 'DISPLAY') {
             return parent::__call($method, $params);
         }
         $m = $matches[2] . '_generic';
         //this is for example DISPLAY_generic
         array_unshift($params, $matches[3]);
         //put the style at the begining
         return call_user_func_array(array($this, $m), $params);
     } else {
         if (preg_match('/^DATE_([a-zA-Z]+)_DATE_([a-zA-Z]+)_([a-zA-Z_]+?)$/', $method, $matches)) {
             if (array_key_exists($matches[1], self::$dateActions) && array_key_exists('DATE_' . $matches[2], self::$dateTypes)) {
                 //we have something like DATE_generateLimit_{$key2}_{$key1} or  DATE_getLimitMenu_{$key2}_{$key1}
                 if ($matches[3] == 'between') {
                     $action = 'DATE_between_' . $matches[1];
                     array_unshift($params, self::$dateTypes['DATE_' . $matches[2]]);
                     //the first argument will be the I2CE_Date type
                     //the third arguement will be the field object, the rest will be the calling arguments in order
                     return call_user_func_array(array($this, $action), $params);
                 } else {
                     if (array_key_exists($matches[3], self::$dateOperatorMaps)) {
                         $action = self::$dateActions[$matches[1]];
                         array_unshift($params, self::$dateTypes['DATE_' . $matches[2]]);
                         //the second argument will be the I2CE_Date type
                         array_unshift($params, $matches[3]);
                         //the first arguement will be the opertator
                         //the third arguement will be the field object, the rest will be the calling arguments in order
                         return call_user_func_array(array($this, $action), $params);
                     }
                 }
             }
         }
     }
     return parent::__call($method, $params);
 }