function validatorsForFieldset($fieldsetOrType, $sContainerName, $oDocument = null, $bIncludeAuto = false)
 {
     // this is likely to be called repeatedly.
     if (is_null($this->oVF)) {
         $this->oVF =& KTValidatorFactory::getSingleton();
     }
     // FIXME delegate.
     $oFieldset =& $fieldsetOrType;
     if ($oFieldset->getIsConditional()) {
         $validators = array();
         $fields = $oFieldset->getFields();
         if ($bIncludeAuto) {
             $widgets = $this->widgetsForFieldset($oFieldset, $sContainerName, $sDocument);
             $validators = kt_array_merge($validators, $widgets[0]->getValidators());
         }
         foreach ($fields as $oField) {
             $fname = 'metadata_' . $oField->getId();
             // Change back to 'membership'
             $validators[] = $this->oVF->get('ktcore.validators.membership', array('test' => $fname, 'output' => $fname, 'vocab' => MetaData::getEnabledValuesByDocumentField($oField), 'id_method' => 'getName'));
         }
     } else {
         $validators = array();
         $fields = $oFieldset->getFields();
         if ($bIncludeAuto) {
             // we need to do *all* validation
             // since we may be used outside a form.
             //
             // to prevent code duplication, we cheat and get the autovalidators
             // this makes add/edit forms marginally less efficient, but we'll deal.
             $widgets = $this->widgetsForFieldset($oFieldset, $sContainerName, $sDocument);
             $validators = kt_array_merge($validators, $widgets[0]->getValidators());
         }
         $config = KTConfig::getSingleton();
         $maxLength = $config->get('KnowledgeTree/maxMetadataLength', 10240);
         foreach ($fields as $oField) {
             $type = '';
             if ($oField->getHasLookup()) {
                 if ($oField->getHasLookupTree()) {
                     $type = 'ktcore.fields.tree';
                 } else {
                     $type = 'ktcore.fields.lookup';
                 }
             } else {
                 $type = 'ktcore.fields.string';
             }
             $fname = 'metadata_' . $oField->getId();
             if ($type == 'ktcore.fields.string') {
                 $validators[] = $this->oVF->get('ktcore.validators.string', array('test' => $fname, 'max_length' => $maxLength, 'output' => $fname));
             } else {
                 if ($type == 'ktcore.fields.lookup') {
                     $validators[] = $this->oVF->get('ktcore.validators.membership', array('test' => $fname, 'output' => $fname, 'vocab' => MetaData::getEnabledValuesByDocumentField($oField), 'id_method' => 'getName'));
                 } else {
                     if ($type == 'ktcore.fields.tree') {
                         // FIXME we really need to make tree entries richer
                         $validators[] = $this->oVF->get('ktcore.validators.membership', array('test' => $fname, 'output' => $fname, 'vocab' => MetaData::getEnabledValuesByDocumentField($oField), 'id_method' => 'getName'));
                     } else {
                         $validators[] = PEAR::raiseError(sprintf(_kt("Unable to deal with field: id %d"), $oField->getId()));
                     }
                 }
             }
         }
     }
     return array($this->oVF->get('ktcore.validators.fieldset', array('test' => $sContainerName, 'output' => $sContainerName, 'validators' => $validators)));
 }