/**
  * Recursively load all models from a directory or array of directories
  *
  * @param  string   $directory      Path to directory of models or array of directory paths
  * @param  integer  $modelLoading   Pass value of Doctrine_Core::ATTR_MODEL_LOADING to force a certain style of model loading
  *                                  Allowed Doctrine_Core::MODEL_LOADING_AGGRESSIVE(default) or Doctrine_Core::MODEL_LOADING_CONSERVATIVE
  * @param  string  $classPrefix     The class prefix of the models to load. This is useful if the class name and file name are not the same
  */
 public static function loadModels($directory, $modelLoading = null, $classPrefix = null)
 {
     self::$_loadedModelFiles = array();
     $manager = Doctrine_Manager::getInstance();
     $modelLoading = $modelLoading === null ? $manager->getAttribute(Doctrine_Core::ATTR_MODEL_LOADING) : $modelLoading;
     $classPrefix = $classPrefix === null ? $manager->getAttribute(Doctrine_Core::ATTR_MODEL_CLASS_PREFIX) : $classPrefix;
     $loadedModels = array();
     if ($directory !== null) {
         foreach ((array) $directory as $dir) {
             $dir = rtrim($dir, '/');
             if (!is_dir($dir)) {
                 throw new Doctrine_Exception('You must pass a valid path to a directory containing Doctrine models');
             }
             $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir), RecursiveIteratorIterator::LEAVES_ONLY);
             foreach ($it as $file) {
                 $e = explode('.', $file->getFileName());
                 if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false) {
                     if ($modelLoading == Doctrine_Core::MODEL_LOADING_PEAR) {
                         $className = str_replace($dir . DIRECTORY_SEPARATOR, null, $file->getPathName());
                         $className = str_replace(DIRECTORY_SEPARATOR, '_', $className);
                         $className = substr($className, 0, strpos($className, '.'));
                     } else {
                         $className = $e[0];
                     }
                     if ($classPrefix) {
                         $className = $classPrefix . $className;
                     }
                     if (!class_exists($className, false)) {
                         if ($modelLoading == Doctrine_Core::MODEL_LOADING_CONSERVATIVE || $modelLoading == Doctrine_Core::MODEL_LOADING_PEAR) {
                             self::loadModel($className, $file->getPathName());
                             $loadedModels[$className] = $className;
                         } else {
                             $declaredBefore = get_declared_classes();
                             require_once $file->getPathName();
                             $declaredAfter = get_declared_classes();
                             // Using array_slice because array_diff is broken is some PHP versions
                             $foundClasses = array_slice($declaredAfter, count($declaredBefore));
                             if ($foundClasses) {
                                 foreach ($foundClasses as $className) {
                                     if (self::isValidModelClass($className)) {
                                         $loadedModels[$className] = $className;
                                         self::loadModel($className, $file->getPathName());
                                     }
                                 }
                             }
                             $previouslyLoaded = array_keys(self::$_loadedModelFiles, $file->getPathName());
                             if (!empty($previouslyLoaded)) {
                                 $previouslyLoaded = array_combine(array_values($previouslyLoaded), array_values($previouslyLoaded));
                                 $loadedModels = array_merge($loadedModels, $previouslyLoaded);
                             }
                         }
                     } else {
                         if (self::isValidModelClass($className)) {
                             $loadedModels[$className] = $className;
                         }
                     }
                 }
             }
         }
     }
     asort($loadedModels);
     return $loadedModels;
 }