bool PathMatch::Match(const std::string &path) const
{
    if (path.empty())
        return false;

    for (std::vector<std::string>::const_iterator iterMask = _masks.begin(); iterMask != _masks.end(); ++iterMask) {
        const std::string& mask(*iterMask);

        std::string findpath(path);
        if (!_caseSensitive)
            std::transform(findpath.begin(), findpath.end(), findpath.begin(), ::tolower);

        // Filtering directory name
        if (mask[mask.length() - 1] == '/') {
            if (findpath[findpath.length() - 1] != '/')
                findpath = RemoveFilename(findpath);

            if (mask.length() > findpath.length())
                continue;
            // Match relative paths starting with mask
            // -isrc matches src/foo.cpp
            if (findpath.compare(0, mask.size(), mask) == 0)
                return true;
            // Match only full directory name in middle or end of the path
            // -isrc matches myproject/src/ but does not match
            // myproject/srcfiles/ or myproject/mysrc/
            if (findpath.find("/" + mask) != std::string::npos)
                return true;
        }
        // Filtering filename
        else {
            if (mask.length() > findpath.length())
                continue;
            // Check if path ends with mask
            // -ifoo.cpp matches (./)foo.c, src/foo.cpp and proj/src/foo.cpp
            // -isrc/file.cpp matches src/foo.cpp and proj/src/foo.cpp
            if (findpath.compare(findpath.size() - mask.size(), findpath.size(), mask) == 0)
                return true;

        }
    }
    return false;
}
ERcExitCode CResourceCompilerHelper::InvokeResourceCompiler(const char* szSrcFilePath, const char* szDstFilePath, const bool bUserDialog) 
{
	const char* szAdjustedFilename = szSrcFilePath;
#if defined(USE_GAMESTREAM)
	char szFullSrcPathBuf[ICryPak::g_nMaxPath];
	if (gEnv && gEnv->pGameStream)
	{
		szAdjustedFilename = gEnv->pCryPak->AdjustFileName(szSrcFilePath, szFullSrcPathBuf, ICryPak::FLAGS_RESOLVE_TO_CACHE);
	}
#endif

	ERcExitCode eRet = eRcExitCode_Pending;

	// make command for execution
	wchar_t szProjectDir[512];
	GetCurrentDirectoryW(sizeof(szProjectDir) / sizeof(szProjectDir[0]), szProjectDir);

	SettingsManagerHelpers::CFixedString<wchar_t, 512> wRemoteCmdLine;
	SettingsManagerHelpers::CFixedString<wchar_t, 512> wDir;
	CSettingsManagerTools smTools = CSettingsManagerTools();

	const char* const szRcParentDir =
		(smTools.Is64bitWindows() && (DirectoryExists(L"Bin64/rc") || !DirectoryExists(L"Bin32/rc")))
		? "Bin64" 
		: "Bin32";

	wchar_t szRegSettingsBuffer[1024];
	smTools.GetEngineSettingsManager()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(szRegSettingsBuffer, sizeof(szRegSettingsBuffer)));

	wRemoteCmdLine.appendAscii(szRcParentDir);
	wRemoteCmdLine.appendAscii("/rc/");
	wRemoteCmdLine.appendAscii(RC_EXECUTABLE);
	wRemoteCmdLine.appendAscii(" \"");
	wRemoteCmdLine.append(szProjectDir);
	wRemoteCmdLine.appendAscii("\\");
	wRemoteCmdLine.appendAscii(szAdjustedFilename);
	wRemoteCmdLine.appendAscii("\" /userdialog=0 ");
	wRemoteCmdLine.append(szRegSettingsBuffer);

	// make it write to a filename of our choice
	char szDstFilename[512];
	char szDstPath[512];

	RemovePath(szDstFilePath, szDstFilename, 512);
	RemoveFilename(szDstFilePath, szDstPath, 512);

	wRemoteCmdLine.appendAscii(" /overwritefilename=\"");
	wRemoteCmdLine.appendAscii(szDstFilename);
	wRemoteCmdLine.appendAscii("\"");
	wRemoteCmdLine.appendAscii(" /targetroot=\"");
	wRemoteCmdLine.append(szProjectDir);
	wRemoteCmdLine.appendAscii("\\");
	wRemoteCmdLine.appendAscii(szDstPath);
	wRemoteCmdLine.appendAscii("\"");

	wDir.append(szProjectDir);
	wDir.appendAscii("\\");
	wDir.appendAscii(szRcParentDir);
	wDir.appendAscii("\\rc");

	STARTUPINFOW si;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwX = 100;
	si.dwY = 100;
	si.dwFlags = STARTF_USEPOSITION;

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));

#if defined(DEBUG) && !defined(NDEBUG) && defined(_RENDERER)
	extern ILog *iLog;

	char tmp1[512];
	char tmp2[512];
	SettingsManagerHelpers::CCharBuffer dst1(tmp1, 512); SettingsManagerHelpers::ConvertUtf16ToUtf8(wDir.c_str(), dst1);
	SettingsManagerHelpers::CCharBuffer dst2(tmp2, 512); SettingsManagerHelpers::ConvertUtf16ToUtf8(wRemoteCmdLine.c_str(), dst2);

	iLog->Log("Debug: RC: dir \"%s\", cmd \"%s\"\n", tmp1, tmp2);
#endif

	if (!CreateProcessW( 
		NULL,     // No module name (use command line). 
		const_cast<wchar_t*>(wRemoteCmdLine.c_str()), // Command line. 
		NULL,     // Process handle not inheritable. 
		NULL,     // Thread handle not inheritable. 
		FALSE,    // Set handle inheritance to FALSE. 
		BELOW_NORMAL_PRIORITY_CLASS + (bUserDialog ? 0 : CREATE_NO_WINDOW),	// creation flags. 
		NULL,     // Use parent's environment block. 
		wDir.c_str(),  // Set starting directory. 
		&si,      // Pointer to STARTUPINFO structure.
		&pi))     // Pointer to PROCESS_INFORMATION structure.
	{
		eRet = eRcExitCode_FatalError;
	}
	else
	{
		// Wait until child process exits.
		WaitForSingleObject(pi.hProcess, INFINITE);

		DWORD exitCode;
		if (GetExitCodeProcess(pi.hProcess, &exitCode) == 0)
		{
			eRet = eRcExitCode_Error;
		}
		else
		{
			eRet = (ERcExitCode)exitCode;
		}
	}

	// Close process and thread handles. 
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);

	return eRet;
}