/**
  * Merges options from another epConfig instance or array
  * Same behavior as {@link epArrayMergeRecursive()}
  * @param mixed epConfig or array
  * @return bool
  * @throws epExceptionConfig
  * @access public
  */
 public function merge($config_or_options)
 {
     // if input config is invalid, do nothing
     if (!$config_or_options) {
         return false;
     }
     // get options in input config
     $options = null;
     $source = false;
     if ($config_or_options instanceof epConfig) {
         $options =& $config_or_options->options();
         $source = $config_or_options->getSource();
     } else {
         if (is_array($config_or_options)) {
             $options =& $config_or_options;
         } else {
             throw new epExceptionConfig('Argument unrecognized');
             return false;
         }
     }
     // check options
     if (empty($options)) {
         return false;
     }
     // merge options
     $this->options = epArrayMergeRecursive($this->options, epArrayStr2Bool($options));
     // set source file
     $this->setSource($source);
     return true;
 }
/**
 * Recursively merge two arrays. 
 * 
 * The non-array values of the first 
 * array are replaced with the values in the second array of the 
 * same keys. The difference between this method and the native 
 * PHP array_merge_recursive() is that instead of collecting all 
 * different values for the same key in both arrays, this method 
 * replaces the value with the value in the second array. This is 
 * useful, for example, for merging configuration options from 
 * different sources. 
 * 
 * Here is an example to show the difference. 
 * 
 * <pre>
 * $array0 = array(
 *                "a" => array(
 *                            "b" => array(
 *                                        "d" => "d",
 *                                        "e" => "f",
 *                                        ),
 *                            "c" => array(
 *                                        "g" => "g",
 *                                        )
 *                            )
 *                );
 *
 * $array1 = array(
 *                "a" => array(
 *                            "c" => array(
 *                                        "g" => "changed",
 *                                        "h" => "new",
 *                                        )
 *                            ),
 *                );
 *
 *
 * echo "array0:\n";
 * print_r($array0);
 *
 * echo "array1:\n";
 * print_r($array1);
 *
 * $array_m1 = array_merge_recursive($array0, $array1);
 * echo "array_m1:\n";
 * print_r($array_m1);
 *
 * $array_m2 = epArrayMergeRecursive($array0, $array1);
 * echo "array_m2:\n";
 * print_r($array_m2);
 * 
 * The output is 
 * 
 * array0:
 * Array
 * (
 *     [a] => Array
 *         (
 *             [b] => Array
 *                 (
 *                     [d] => d
 *                     [e] => f
 *                 )
 *             [c] => Array
 *                 (
 *                     [g] => g
 *                 )
 *         )
 * )
 * 
 * array1:
 * Array
 * (
 *     [a] => Array
 *         (
 *             [c] => Array
 *                 (
 *                     [g] => changed
 *                     [h] => new
 *                 )
 *         )
 * )
 * 
 * array_m1:
 * Array
 * (
 *     [a] => Array
 *         (
 *             [b] => Array
 *                 (
 *                     [d] => d
 *                     [e] => f
 *                 )
 *             [c] => Array
 *                 (
 *                     [g] => Array
 *                         (
 *                             [0] => g
 *                             [1] => changed
 *                         )
 *                     [h] => new
 *                 )
 *
 *         )
 *
 * )
 * 
 * array_m2:
 * Array
 * (
 *     [a] => Array
 *         (
 *             [b] => Array
 *                 (
 *                     [d] => d
 *                     [e] => f
 *                 )
 *
 *             [c] => Array
 *                 (
 *                     [g] => changed
 *                     [h] => new
 *                 )
 *
 *         )
 *
 * )
 * </pre>
 */
function epArrayMergeRecursive($array1, $array2)
{
    $merged = $array1;
    foreach ($array2 as $key => $value) {
        if (!is_array($value)) {
            if (!isset($array1[$key]) || $array2[$key] !== $array1[$key]) {
                $merged[$key] = $value;
            }
            continue;
        }
        if (!isset($array1[$key])) {
            $array1[$key] = array();
        }
        $merged[$key] = epArrayMergeRecursive($array1[$key], $value);
    }
    return $merged;
}