static
void BuildFolderPath (const XBOX::VFilePath& inBaseFolder, const XBOX::VString& inPath, XBOX::VFilePath& outPath)
{
	if (inPath.IsEmpty())
	{
		outPath.FromFilePath (inBaseFolder);
	}
	else
	{
		XBOX::VString	pathString (inPath);
		
		if ((pathString[0] == CHAR_SOLIDUS) // POSIX Path ?
#if VERSIONWIN
			|| ((pathString.GetLength() > 2) && (pathString[1] == CHAR_COLON) && (pathString[2] == CHAR_SOLIDUS)) // POSIX path like c:/blahblah/
#endif
		)
		{
			if (!pathString.IsEmpty() && (pathString[pathString.GetLength()-1] != CHAR_SOLIDUS))
				pathString.AppendUniChar (CHAR_SOLIDUS);
			
			outPath.FromFullPath (pathString, XBOX::FPS_POSIX);
		}
		else if ((pathString[0] != CHAR_FULL_STOP) && (pathString.FindUniChar (XBOX::FOLDER_SEPARATOR) > 0))
		{
			if (!pathString.IsEmpty() && (pathString[pathString.GetLength()-1] != XBOX::FOLDER_SEPARATOR))
				pathString.AppendUniChar (XBOX::FOLDER_SEPARATOR);
			
			outPath.FromFullPath (pathString, XBOX::FPS_SYSTEM);
		}
		else
		{
			XBOX::VFilePath baseFolder (inBaseFolder);
			
			if ((pathString[0] == CHAR_FULL_STOP) && (pathString[1] == CHAR_SOLIDUS))
				pathString.Remove (1, 2);
			
			while ((pathString[0] == CHAR_FULL_STOP) && (pathString[1] == CHAR_FULL_STOP) && (pathString[2] == CHAR_SOLIDUS))
			{
				pathString.Remove (1, 3);
				baseFolder = baseFolder.ToParent();
			}
			
			pathString.ExchangeAll (CHAR_SOLIDUS, XBOX::FOLDER_SEPARATOR);
			
			if (!pathString.IsEmpty() && (pathString[pathString.GetLength()-1] != XBOX::FOLDER_SEPARATOR))
				pathString.AppendUniChar (XBOX::FOLDER_SEPARATOR);
			
			outPath.FromRelativePath (baseFolder, pathString);
		}
	}
}
XBOX::VError VVirtualFolder::GetFilePathFromURL (const XBOX::VString& inURL, XBOX::VString& outLocationPath)
{
	if (!fLocalFolder)
	{
		XBOX::VString URL (inURL);
		sLONG pos = HTTPServerTools::FindASCIIVString (URL, fName);

		if (pos > 0)
			URL.Remove (1, pos + fName.GetLength() - 1);

		if ((URL.GetLength() == 1) && (URL.GetUniChar (1) == CHAR_SOLIDUS) && (!fIndexFileName.IsEmpty()))
			URL.AppendString (fIndexFileName);
		
		outLocationPath.FromString (fLocationPath);
		if (outLocationPath.GetUniChar (outLocationPath.GetLength()) == CHAR_SOLIDUS)
			outLocationPath.Truncate (outLocationPath.GetLength() - 1);
		outLocationPath.AppendString (URL);

		return VE_HTTP_PROTOCOL_FOUND;
	}

	XBOX::VError	error = XBOX::VE_FILE_NOT_FOUND;
	XBOX::VFilePath	path (fFolder->GetPath());
	XBOX::VString	pathString (inURL);
	XBOX::VString	folder;
	XBOX::VString	docName;

	if ((pathString.GetLength() == 1) && (pathString.GetUniChar (1) == CHAR_SOLIDUS))
	{
		docName.FromString (fIndexFileName);
	}
	else
	{
		bool	notDone = true;
		sLONG	folderLen = 0;
		sLONG	pos = 0;
		sLONG	curPos = 0;

		// YT 16-Nov-2011 - ACI0073914
		if (pathString.FindUniChar (CHAR_COLON) > 0) // ':'
			pathString.ExchangeAll (CHAR_COLON, CHAR_SOLIDUS);

		if (pathString.FindUniChar (CHAR_REVERSE_SOLIDUS) > 0) // '\'
			pathString.ExchangeAll (CHAR_REVERSE_SOLIDUS, CHAR_SOLIDUS);

		while (notDone)
		{
			if ((pos = pathString.FindUniChar (CHAR_SOLIDUS, curPos + 1)) > 0)	// '/'
			{
				HTTPServerTools::GetSubString (pathString, curPos, pos - 2, folder);
				folderLen = folder.GetLength();
				if (folderLen > 0)
				{
					/* If URL first folder equals Virtual Folder Name or Project Pattern... Do nothing... */
					if ((curPos == 1) && !fName.IsEmpty() && HTTPServerTools::EqualASCIIVString (fName, folder))
						;
					/* YT 24-Feb-2011 - ACI0069901 - Project Pattern is already removed from URL in VHTTPResponse::_UpdateRequestURL()
					else if ((curPos == 1) && !fProjectPattern.IsEmpty() && HTTPServerTools::EqualASCIIVString (fProjectPattern, folder))
					{
						pathString.SubString (curPos + fProjectPattern.GetLength() + 1, pathString.GetLength() - fProjectPattern.GetLength() + 1); // YT 24-Nov-2010 - ACI0068942 - Remove Project Pattern from URL...
						folderLen = 0;
						curPos = -1;
					}
					*/
					else if ((folderLen == 2) && (folder[0] == CHAR_FULL_STOP) && (folder[1] == CHAR_FULL_STOP)) // ".."
						path = path.ToParent();
					else if  ((folderLen == 1) && (folder[0] == CHAR_FULL_STOP)) // "."
						;	// unchanged
					else
						path = path.ToSubFolder (folder);

					curPos += (folderLen + 1);
				}
				else
					curPos += 1;
			}
			else
				notDone = false;

			if (curPos >= pathString.GetLength())
				break;
		}
		
		if (curPos < pathString.GetLength())
			HTTPServerTools::GetSubString (pathString, curPos, pathString.GetLength() - 1, docName);
	}

	/* if URL does not include a filename, try using the index file name set in prefs */
	if (docName.IsEmpty())
		docName.FromString (fIndexFileName);

	path = path.ToSubFile (docName);

	/*
		at this stage path should contain a full path pointing to the wanted file
		check that this is inside the web folder (if it's a web connection)
	*/
	// SECURITY CHECK - change it with great care
	if (path.GetPath().BeginsWith (fFolder->GetPath().GetPath()))
	{
		outLocationPath.FromString (path.GetPath());
		error = VE_OK;
	}
	else
	{
		// UNDER ATTACK !!!
		path.Clear();
		error = VE_HTTP_PROTOCOL_FORBIDDEN;
	}

	return error;
}
/*
	static
*/
DialectCode	VComponentManager::GetLocalizationLanguage(VFolder * inLocalizationResourcesFolder,bool inGotoResourceFolder)
{
	DialectCode sResult = XBOX::DC_NONE;	// sc 19/05/2008 was XBOX::DC_ENGLISH_US
	VFolder * localizationResourcesFolder = NULL;
	
	if(testAssert(inLocalizationResourcesFolder != NULL && inLocalizationResourcesFolder->Exists()))
	{
		if (inGotoResourceFolder)
		{
			XBOX::VFilePath componentOrPluginFolderPath = inLocalizationResourcesFolder->GetPath();
			componentOrPluginFolderPath.ToSubFolder(CVSTR("Contents")).ToSubFolder(CVSTR("Resources"));
			localizationResourcesFolder = new XBOX::VFolder(componentOrPluginFolderPath);
		}
		else
		{
			localizationResourcesFolder = inLocalizationResourcesFolder;
			localizationResourcesFolder->Retain();
		}

		bool englishFolderDetected = false;
		XBOX::DialectCode dialectCode = XBOX::DC_NONE;
		
		//Detect what is the favorite language of the OS/App
#if VERSIONWIN
		LCID lcid = ::GetUserDefaultLCID();
		XBOX::DialectCode currentDialectCode = (XBOX::DialectCode)LANGIDFROMLCID(lcid);

#elif VERSION_LINUX

		//jmo - Be coherent with code in VIntlMgr.cpp
		XBOX::DialectCode currentDialectCode=XBOX::DC_ENGLISH_US;   // Postponed Linux Implementation !
		
#else

		CFBundleRef	bundle = ::CFBundleGetMainBundle();
		XBOX::DialectCode currentDialectCode = XBOX::DC_ENGLISH_US;
		if ( bundle != nil ){
			CFArrayRef array_ref = ::CFBundleCopyBundleLocalizations(bundle);			
			if (array_ref != nil){
				CFArrayRef usedLanguages = ::CFBundleCopyPreferredLocalizationsFromArray(array_ref);
				CFStringRef cfPrimaryLanguage = (CFStringRef)CFArrayGetValueAtIndex(usedLanguages, 0);
				XBOX::VString xboxPrimaryLanguage;
				xboxPrimaryLanguage.MAC_FromCFString(cfPrimaryLanguage);
				::CFRelease(usedLanguages);
				if(!XBOX::VIntlMgr::GetDialectCodeWithISOLanguageName(xboxPrimaryLanguage, currentDialectCode))
					if(!XBOX::VIntlMgr::GetDialectCodeWithRFC3066BisLanguageCode(xboxPrimaryLanguage, currentDialectCode))
						currentDialectCode = XBOX::DC_ENGLISH_US;
				CFRelease(array_ref);
			}
		}
#endif
		//Try to see if we have this language. If not, take english
		for ( XBOX::VFolderIterator folderIter( localizationResourcesFolder ); folderIter.IsValid() && currentDialectCode != dialectCode ; ++folderIter )
		{
			XBOX::VString folderName;
			folderIter->GetName(folderName);
			uLONG posStr = folderName.Find(CVSTR(".lproj"), 1, false);
			if ( posStr > 0 )
			{
				folderName.Remove(posStr, folderName.GetLength() - posStr + 1);
				if( XBOX::VIntlMgr::GetDialectCodeWithRFC3066BisLanguageCode(folderName, dialectCode ) || XBOX::VIntlMgr::GetDialectCodeWithISOLanguageName(folderName, dialectCode)){
					if(dialectCode == XBOX::DC_ENGLISH_US)
						englishFolderDetected = true;
					
					if(currentDialectCode == dialectCode)
						sResult = dialectCode;
				}
			}
		}
		
		if ( sResult == XBOX::DC_NONE ){
			if ( englishFolderDetected ) 
				sResult = XBOX::DC_ENGLISH_US;
			else 
				sResult = dialectCode;
		}
		
		ReleaseRefCountable(&localizationResourcesFolder);
	}
	
	return sResult;
}