public String managerConfigValidCtxRoot(HashMap<String, Object> config) {
		final StringBuffer result = new StringBuffer();
		final String appsFolder = Application.getAppFolderRootPath(config);
		//System.out.println(appsFolder);
		//System.out.println((String)config.get(Configurations.APPCLUSTER.getKey()));
		
		logger.log(LogLevel.INFO, "Get all application names.");
		final HashMap<String, String> appsMap = Application.getInstalledAppList(appsFolder, (String)config.get(Configurations.APPCLUSTER.getKey()));
		if (appsMap == null) {
			result.append("The path of applicaiton folder you specified is wrong:" 
			+ System.getProperty("line.separator")
			+ appsFolder
			+ System.getProperty("line.separator"));
			failedPoints = getPoints();
		}
		else {
			result.append("Succeed to get application list.");
			System.out.println(appsMap.size());
			
			logger.log(LogLevel.INFO, "Get and sort application exempt list.");
			HashMap<String, String> exemptMap = getExemptList();
			Iterator<Map.Entry<String, String>> iter = exemptMap.entrySet().iterator();
			while (iter.hasNext()) {
				Map.Entry<String, String> entry = (Map.Entry<String, String>)iter.next();
				String appName = (String) entry.getKey() + "_" + (String)config.get(Configurations.APPCLUSTER.getKey()) + ".ear";
				String filter = (String) entry.getValue();
				if (appsMap.containsKey(appName)) {
					if (filter.equals("*")) {
						appsMap.remove(appName);
						result.append("Applicaiton '" + appName 
								+ "' will be ignored" + System.getProperty("line.separator"));
						logger.log(LogLevel.INFO, "Applicaiton '" + appName 
								+ "' will be ignored" + System.getProperty("line.separator"));
					}
					else {
						appsMap.put(appName, filter);
					}
				}
			}
			
			logger.log(LogLevel.INFO, "Check context root for apps.");
			ExecutorService exec = Executors.newCachedThreadPool();
			final CountDownLatch runningThreadNum = new CountDownLatch(appsMap.size());
			Iterator<Map.Entry<String, String>> it = appsMap.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry<String, String> entry = (Map.Entry<String, String>)it.next();
				//String appName = (String) entry.getKey();
				//String filter = (String) entry.getValue();
				//result.append(checkAppCtxRoots(appsFolder, appName, filter));
				final String appName = (String) entry.getKey();
				final String filter = (String) entry.getValue();
				Runnable run = new Runnable() {
					public void run() {
						result.append(checkAppCtxRoots(appsFolder, appName, filter));
						runningThreadNum.countDown();
					}
				};
				exec.execute(run);
			}
			exec.shutdown();
			try {
				runningThreadNum.await();
			} catch (InterruptedException e) {
				logger.log(LogLevel.ERROR, "Met exception when waiting sub thread complete.", e);
			}
		}
		return result.toString();
	}