const QStringList FileCompressDlg::GetSubFiles(const Path &path)
{
	QStringList sub_paths;
	QDir dir(QString::fromLocal8Bit(path.ParentPath().c_str()));
	auto entry_list = dir.entryInfoList(QDir::Files);
	auto file_name = path.Stem();
	for (int i = 0; i < entry_list.size(); i++) {
		QString entry_path = entry_list[i].absoluteFilePath();
		Path sub_path = Path(entry_path.toLocal8Bit().toStdString());
		if ((sub_path.Stem() == file_name
			|| QString::fromStdString(sub_path.Stem()).contains(path.FileName().c_str()))
			&& path.String() != sub_path.String())
			sub_paths.push_back(entry_path);
	}

	return sub_paths;
}
// returns 0 on success, -ve number of errors if there is an error and we should quit,
// positive number of errors if there is an error but we should continue
static int TestBuildFile( ICompilerLogger* pLog, RuntimeObjectSystem* pRTObjSys, const Path& file,
                          ITestBuildNotifier* callback, bool bTestFileTracking )
{
    assert( callback );

    if( pLog ) { pLog->LogInfo("Testing change to file: %s\n", file.c_str()); }

    int numErrors = 0;
    if( file.Exists() )
    {
        if( bTestFileTracking )
        {
            FileSystemUtils::filetime_t currTime = FileSystemUtils::GetCurrentTime();
            FileSystemUtils::filetime_t oldModTime = file.GetLastWriteTime();
            if( currTime == oldModTime )
            {
                // some files may be auto-generated by the program, so may have just been created so won't
                // get a time change unless we force it.
                currTime += 1;
            }
            file.SetLastWriteTime( currTime );
            // we must also change the directories time, as some of our watchers watch the dir
            Path directory = file.ParentPath();
            directory.SetLastWriteTime( currTime );
            for( int i=0; i<50; ++i )
            {
                // wait up to 100 seconds (make configurable?)
                pRTObjSys->GetFileChangeNotifier()->Update( 1.0f ); // force update by using very large time delta
                if( pRTObjSys->GetIsCompiling() ) { break; }
                if( !callback->TestBuildWaitAndUpdate() )
                {
                    return -0xD1E;
                }
            }
        }
        else
        {
            AUDynArray<const char*> filelist;
            filelist.Add( file.c_str() );
            pRTObjSys->OnFileChange( filelist );
        }
        if( pRTObjSys->GetIsCompiling() )
        {
            while( !pRTObjSys->GetIsCompiledComplete() )
            {
                if( !callback->TestBuildWaitAndUpdate() )
                {
                    return -0xD1E;
                }
            }
            int numCurrLoadedModules = pRTObjSys->GetNumberLoadedModules();
            if( pRTObjSys->LoadCompiledModule() )
            {
                if( !callback->TestBuildCallback( file.c_str(), TESTBUILDRRESULT_SUCCESS ) ) { return -0xD1E; }
                return 0;
            }
            else
            {
                ++numErrors;
                if( pRTObjSys->GetNumberLoadedModules() == numCurrLoadedModules )
                {
                    if( !callback->TestBuildCallback( file.c_str(), TESTBUILDRRESULT_BUILD_FAILED ) ) { return -numErrors; }
                }
                else
                {
                    // loaded the module but some other issue
                    if( !callback->TestBuildCallback( file.c_str(), TESTBUILDRRESULT_OBJECT_SWAP_FAIL ) ) { return -numErrors; }
                }
            }
        }
        else
        {
            ++numErrors;
           if( !callback->TestBuildCallback( file.c_str(), TESTBUILDRRESULT_BUILD_NOT_STARTED ) ) { return -numErrors; }
        }
    }
    else
    {
        ++numErrors;
        if( !callback->TestBuildCallback( file.c_str(), TESTBUILDRRESULT_BUILD_FILE_GONE ) ) { return -numErrors; }
    }
    return numErrors;
}