/**
  * @param array $props array of properties
  * @param string $appenderName
  * @return LoggerAppender
  */
 function &parseAppender($props, $appenderName)
 {
     $appender =& LoggerAppender::singleton($appenderName);
     if ($appender !== null) {
         LoggerLog::debug("LoggerPropertyConfigurator::parseAppender() " . "Appender [{$appenderName}] was already parsed.");
         return $appender;
     }
     // Appender was not previously initialized.
     $prefix = LOG4PHP_LOGGER_PROPERTY_CONFIGURATOR_APPENDER_PREFIX . $appenderName;
     $layoutPrefix = $prefix . ".layout";
     $appenderClass = @$props[$prefix];
     if (!empty($appenderClass)) {
         $appender =& LoggerAppender::singleton($appenderName, $appenderClass);
         if ($appender === null) {
             LoggerLog::warn("LoggerPropertyConfigurator::parseAppender() " . "Could not instantiate appender named [{$appenderName}].");
             return null;
         }
     } else {
         LoggerLog::warn("LoggerPropertyConfigurator::parseAppender() " . "Could not instantiate appender named [{$appenderName}] with null className.");
         return null;
     }
     $appender->setName($appenderName);
     if ($appender->requiresLayout()) {
         LoggerLog::debug("LoggerPropertyConfigurator::parseAppender() " . "Parsing layout section for [{$appenderName}].");
         $layoutClass = @$props[$layoutPrefix];
         $layoutClass = LoggerOptionConverter::substVars($layoutClass, $props);
         if (empty($layoutClass)) {
             LoggerLog::warn("LoggerPropertyConfigurator::parseAppender() " . "layout class is empty in '{$layoutPrefix}'. Using Simple layout");
             $layout = LoggerLayout::factory('LoggerLayoutSimple');
         } else {
             $layout = LoggerLayout::factory($layoutClass);
             if ($layout === null) {
                 LoggerLog::warn("LoggerPropertyConfigurator::parseAppender() " . "cannot create layout '{$layoutClass}'. Using Simple layout");
                 $layout = LoggerLayout::factory('LoggerLayoutSimple');
             }
         }
         LoggerLog::debug("LoggerPropertyConfigurator::parseAppender() " . "Parsing layout options for [{$appenderName}].");
         LoggerPropertySetter::setPropertiesByObject($layout, $props, $layoutPrefix . ".");
         LoggerLog::debug("LoggerPropertyConfigurator::parseAppender() " . "End Parsing layout options for [{$appenderName}].");
         $appender->setLayout($layout);
     }
     LoggerPropertySetter::setPropertiesByObject($appender, $props, $prefix . ".");
     LoggerLog::debug("LoggerPropertyConfigurator::parseAppender() " . "Parsed [{$appenderName}] options.");
     return $appender;
 }
 /**
  * Set the properties of an object passed as a parameter in one
  * go. The <code>properties</code> are parsed relative to a
  * <code>prefix</code>.
  *
  * @param object &$obj The object to configure.
  * @param array $properties An array containing keys and values.
  * @param string $prefix Only keys having the specified prefix will be set.
  * @static
  */
 function setPropertiesByObject(&$obj, $properties, $prefix)
 {
     $pSetter = new LoggerPropertySetter($obj);
     return $pSetter->setProperties($properties, $prefix);
 }