--- framework/Horde/Horde/Config.php	2008-04-02 13:04:02.000000000 -0400
+++ /usr/local/lib/php/Horde/Config.php	2008-04-02 14:01:46.000000000 -0400
@@ -109,6 +109,24 @@
     var $_configEnd = "/* CONFIG END. DO NOT CHANGE ANYTHING IN OR BEFORE THIS LINE. */\n";
 
     /**
+     * The applications this configuration requires be installed.  The format is array (app => version).
+     * If true === version, then no minimum version required.  Otherwise, if is_string(version), then that
+     * application version, or higher, must be configured.
+     *
+     * @var array
+     */
+    var $_requiredApps = array ();
+
+    /**
+     * The PHP extensions this configuration requires be installed.  The format is array (extension => version).
+     * If true === version, then no minimum version required.  Otherwise, if is_string(version), then that
+     * extension version, or higher, must be installed.
+     *
+     * @var array
+     */
+    var $_requiredExtensions = array ();
+
+    /**
      * Constructor.
      *
      * @param string $app  The name of the application to be configured.
@@ -556,6 +574,42 @@
                 $conf[md5(microtime())] = 'placeholder';
                 break;
 
+            case 'requires':
+                // descend into all the children of the <requires> element
+                if ($node->has_child_nodes()) {
+                    $this->_parseLevel($cur, $node->child_nodes(), 'requires');
+                }
+                break;
+
+            case 'require':
+                // if we're not inside of a <requires>, this is a bad element: move along
+                if ('requires' != $ctx) {
+                    break;
+                }
+
+                // if we have a requirement for a given app
+                if ($requiredApp = $node->get_attribute('app')) {
+                    // make note that we're requiring this application
+                    $this->_requiredApps[$requiredApp] = true;
+
+                    // if we also have a minimum version, make note of the needed version
+                    if ($minimumVersion = $node->get_attribute('version')) {
+                        $this->_requiredApps[$requiredApp] = $minimumVersion;
+                    }
+                }
+
+                // if we have a requirement for a given PHP extension
+                if ($requiredExtension = $node->get_attribute('extension')) {
+                    // make note that we're requiring this extension
+                    $this->_requiredExtensions[$requiredExtension] = true;
+
+                    // if we also have a minimum version, make note of the needed version
+                    if ($minimumVersion = $node->get_attribute('version')) {
+                        $this->_requiredExtensions[$requiredExtension] = $minimumVersion;
+                    }
+                }
+                break;
+
             default:
                 $conf[$name] = array();
                 $cur = &$conf[$name];
@@ -1283,6 +1337,90 @@
         return str_replace("'", "\'", $string);
     }
 
+    /**
+     * Does this installation meet all the requirements this configuration mandates?
+     *
+     * @access public
+     *
+     * @return boolean  Whether or not this installation meets the requirements.
+     */
+    function areRequirementsSatisfied()
+    {
+        return (0 === count($this->getMissingRequirements()) ? true : false);
+    }
+
+    /**
+     * Get the list of missing requirements this configuration mandates.
+     *
+     * @access public
+     *
+     * @return array  The specific list of requirements NOT satisifed.  If any empty
+     * array, then all requirements are satisfied.  The format is array ('description', ...);
+     */
+    function getMissingRequirements()
+    {
+        // memoize the missing requirements, as it may be called a few times
+        static $missing = null;
+        if (is_null($missing)) {
+            // assume all is well
+            $missing = array ();
+
+            // get the list of *available* applications
+            // NOTE: if the application isn't available, that's considered a non-installed & unusuable
+            // NOTE: application, so it's not a candidate for checking
+            // FIXME: does the registry offer a method that tells me just the apps installed?
+            global $registry;
+            $installedApps = $registry->listApps();
+            foreach ($installedApps as $key => $app) {
+                $root = $registry->get('fileroot', $app);
+                if (! file_exists($root)) {
+                    unset($installedApps[$key]);
+                }
+            }
+
+            // check the applications
+            foreach ($this->_requiredApps as $app => $version) {
+                // check that the application is installed
+                if (! in_array($app, $installedApps)) {
+                    $missing[] = "Missing required application $app; please install and configure it";
+                }
+
+                // if any version will suffice, move on
+                if (true === $version) {
+                    continue;
+                } else {
+                    // check that the installed version meets the requested version 
+                    // FIXME: how do you get the installed version for an application?
+                }
+            }
+
+            // check the extensions
+            foreach ($this->_requiredExtensions as $extension => $version) {
+                // check that the extension is loaded
+                if (! extension_loaded($extension)) {
+                    // not there, try to load it ourself
+                    // NOTE: be quiet about failures
+                    $prefix = ((PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '');
+                    @dl($prefix . $extensions . PHP_SHLIB_SUFFIX);
+
+                    // if it's still not loaded, sorry
+                    if (! extension_loaded($extension)) {
+                        $missing[] = "Missing required extension $extension; please install it from binary or recompile PHP with support";
+                    }
+                }
+
+                // if any version will suffice, move on
+                if (true === $version) {
+                    continue;
+                } else {
+                    // check that the loaded version meets the requested version 
+                    // FIXME: how do you get the version for an extension?
+                }
+            }
+        }
+
+        return $missing;
+    }
 }
 
 /**
@@ -1334,6 +1472,19 @@
         $config = $this->_xmlConfig->readXMLConfig();
         $this->addHidden('', 'app', 'text', true);
         $this->_buildVariables($config);
+
+        // check to make sure the requirements are satisfied
+        if (! $this->_xmlConfig->areRequirementsSatisfied()) {
+            global $notification;
+            $notification->push(
+                sprintf(
+                    _('You have not installed all required Horde applications and PHP extensions; %s may fail to work. Reasons: %s'),
+                    $app,
+                    implode('. ', $this->_xmlConfig->getMissingRequirements())
+                ),
+                'horde.warning'
+            );
+        }
     }
 
     /**