function xoRegisterComponent($registry, $bundleInfo, $bundleRoot)
{
    global $xoops;
    $services = array();
    if (isset($bundleInfo['xoServices'])) {
        foreach ($bundleInfo['xoServices'] as $localId => $localInfo) {
            if (@($subRoot = $localInfo['xoBundleRoot'])) {
                if ($localInfo = @(include $xoops->path($bundleRoot . $subRoot . '/xo-info.php'))) {
                    $localInfo = xoRegisterComponent(array(), $localInfo, $bundleRoot . $subRoot);
                    $services = array_merge($services, $localInfo);
                }
            } else {
                $localInfo['xoBundleRoot'] = $bundleRoot;
                if (is_array($localInfo)) {
                    $services[$localId] = $localInfo;
                }
            }
        }
        unset($bundleInfo['xoServices']);
    }
    $bundleId = $bundleInfo['xoBundleIdentifier'];
    unset($bundleInfo['xoBundleIdentifier']);
    $bundleInfo['xoBundleRoot'] = $bundleRoot;
    $services[$bundleId] = $bundleInfo;
    return array_merge($registry, $services);
}
function xoRegisterComponent($registry, $bundleInfo, $bundleRoot, $prefix = '')
{
    global $xoops;
    $isModule = substr($bundleInfo['xoBundleIdentifier'], 0, 4) == 'mod_';
    $services = array();
    if (isset($bundleInfo['xoServices'])) {
        foreach ($bundleInfo['xoServices'] as $localId => $localInfo) {
            if (@($subRoot = $localInfo['xoBundleRoot'])) {
                if ($localInfo = @(include $xoops->path($bundleRoot . $subRoot . '/xo-info.php'))) {
                    if (!$isModule) {
                        $localInfo = xoRegisterComponent(array(), $localInfo, $bundleRoot . $subRoot);
                    } else {
                        $localInfo = xoRegisterComponent(array(), $localInfo, $bundleRoot . $subRoot, $bundleInfo['xoBundleIdentifier'] . '#');
                    }
                    foreach ($localInfo as $k => $v) {
                        if (substr($k, 0, 2) != 'xo') {
                            unset($localInfo[$k]);
                        }
                    }
                    $services = array_merge($services, $localInfo);
                }
            } else {
                $localInfo['xoBundleRoot'] = $bundleRoot;
                if ($isModule) {
                    $localInfo['xoBundleIdentifier'] = $localId;
                    $localId = $bundleInfo['xoBundleIdentifier'] . '#' . $localId;
                }
                if (is_array($localInfo)) {
                    $services[$localId] = $localInfo;
                }
            }
        }
        unset($bundleInfo['xoServices']);
    }
    $bundleId = $bundleInfo['xoBundleIdentifier'];
    unset($bundleInfo['xoBundleIdentifier']);
    $bundleInfo['xoBundleRoot'] = $bundleRoot;
    foreach ($bundleInfo as $k => $v) {
        if (substr($k, 0, 2) != 'xo') {
            unset($bundleInfo[$k]);
        }
    }
    $services[$bundleId] = $bundleInfo;
    return array_merge($registry, $services);
}