/**
  * Generates a limit expression for a field based on  limit data
  * @param I2CE_FormField $fieldObj
  * @param mixed $limit_data
  * @param callback $ref.  A callback function whose first arguement is the form, the second arguements
  * is the field and which returns the way the field value should be references as a field.  If the callback is null (the default) then
  * the reference used is "$form+$field"
  * @param string $parent_ref.  Defaults to null.  If not null, it is the referent to the parent id of the form
  * @returns string SQL statement false on failure
  */
 public function generateFieldLimit($fieldObj, $limit_data, $ref, $parent_ref = null)
 {
     if (!is_array($limit_data)) {
         I2CE::raiseError("Expected array for generating field limit, but not received");
         return false;
     }
     if (!array_key_exists('style', $limit_data) || !is_string($limit_data['style'])) {
         I2CE::raiseError("Style is not given at 'style' ");
         return false;
     }
     if (!array_key_exists('data', $limit_data) || !is_array($limit_data['data'])) {
         $limit_data['data'] = array();
     }
     $method = 'generateLimit_' . $limit_data['style'];
     if (!$fieldObj->_hasMethod($method)) {
         I2CE::raiseError("Not able to generate limit for style  " . $limit_data['style'] . " by method ({$method}) for class " . get_class($fieldObj));
         return false;
     }
     $ret = $fieldObj->{$method}($limit_data['data'], $ref, $parent_ref);
     if (is_string($ret)) {
         return $ret;
     } else {
         I2CE::raiseError("Unexpected return from limit {$style}:" . print_r($ret, true));
         return false;
     }
 }