protected function merge(array $configs)
    {
        $objects = array_filter($configs, 'is_object');

        if (!empty($objects)) {
            $listConfigs = [];

            foreach ($configs as $config) {
                if (!is_object($config)) {
                    throw new RuntimeException('Cannot merge object with other types');
                }

                $listConfigs[] = (array) $config;
            }

            $result = (object) $this->merge($listConfigs);
        } else {
            foreach ($configs as $config) {
                foreach ($config as $key => $value) {
                    $existed = isset($result[$key]);

                    switch (true) {
                        case ($existed && (is_object($result[$key]) || is_object($value))):
                        case ($existed && (is_array($result[$key]) && is_array($value))):
                            $result[$key] = $this->merge(array($result[$key], $value));
                            break;

                        default:
                            $result[$key] = $value;
                    }
                }
            }
        }

        return $result;
    }