static function cacheMap($servicePath, $cacheFilePath)
 {
     if (!is_dir($servicePath)) {
         throw new Exception('Invalid directory [' . $servicePath . ']');
     }
     $servicePath = realpath($servicePath);
     $serviceMap = array();
     $classMap = KAutoloader::getClassMap();
     $checkedClasses = array();
     //Retrieve all service classes from the classMap.
     $serviceClasses = array();
     foreach ($classMap as $class => $classFilePath) {
         $classFilePath = realpath($classFilePath);
         if (strpos($classFilePath, $servicePath) === 0) {
             $reflectionClass = new ReflectionClass($class);
             if ($reflectionClass->isSubclassOf('KalturaBaseService')) {
                 $serviceDoccomment = new KalturaDocCommentParser($reflectionClass->getDocComment());
                 $serviceClasses[$serviceDoccomment->serviceName] = $class;
             }
         }
     }
     //Retrieve all plugin service classes.
     $pluginInstances = KalturaPluginManager::getPluginInstances('IKalturaServices');
     foreach ($pluginInstances as $pluginName => $pluginInstance) {
         $pluginServices = $pluginInstance->getServicesMap();
         foreach ($pluginServices as $serviceName => $serviceClass) {
             $serviceName = strtolower($serviceName);
             $serviceId = "{$pluginName}_{$serviceName}";
             $serviceClasses[$serviceId] = $serviceClass;
         }
     }
     //Add core & plugin services to the services map
     $aliasActions = array();
     foreach ($serviceClasses as $serviceId => $serviceClass) {
         $serviceReflectionClass = KalturaServiceReflector::constructFromClassName($serviceClass);
         $serviceMapEntry = new KalturaServiceActionItem();
         $serviceMapEntry->serviceId = $serviceId;
         $serviceMapEntry->serviceClass = $serviceClass;
         $serviceMapEntry->serviceInfo = $serviceReflectionClass->getServiceInfo();
         $actionMap = array();
         $nativeActions = $serviceReflectionClass->getActions();
         foreach ($nativeActions as $actionId => $actionName) {
             $actionMap[strtolower($actionId)] = array("serviceClass" => $serviceClass, "actionMethodName" => $actionName, "serviceId" => $serviceId, "actionName" => $actionId);
         }
         $serviceMapEntry->actionMap = $actionMap;
         $serviceMap[strtolower($serviceId)] = $serviceMapEntry;
         foreach ($serviceReflectionClass->getAliasActions() as $alias => $methodName) {
             $aliasActions[$alias] = "{$serviceId}.{$methodName}";
         }
     }
     // add aliases
     foreach ($aliasActions as $aliasAction => $sourceAction) {
         list($aliasService, $aliasAction) = explode('.', $aliasAction);
         list($sourceService, $sourceAction) = explode('.', $sourceAction);
         $aliasService = strtolower($aliasService);
         $sourceService = strtolower($sourceService);
         $extServiceClass = $serviceClasses[$sourceService];
         $serviceMap[$aliasService]->actionMap[strtolower($aliasAction)] = array("serviceClass" => $extServiceClass, "actionMethodName" => $sourceAction, "serviceId" => $sourceService, "actionName" => $aliasAction);
     }
     // filter out services that have no actions
     $serviceMap = array_filter($serviceMap, array('KalturaServicesMap', 'filterEmptyServices'));
     if (!is_dir(dirname($cacheFilePath))) {
         mkdir(dirname($cacheFilePath));
         chmod(dirname($cacheFilePath), 0755);
     }
     kFile::safeFilePutContents($cacheFilePath, serialize($serviceMap), 0644);
 }