Exemple #1
0
void stack_temp(std::string outputFolder){

  setNCUStyle();
  gStyle->SetOptFit(0);
  gStyle->SetMarkerSize(0);
  gStyle->SetTitleSize(0.04,"XYZ");
  gStyle->SetLabelSize(0.03,"XYZ");
  gStyle->SetHistLineWidth(2);

  std::vector<string> infiles;
 
  TSystemDirectory *base = new TSystemDirectory("root","root");
  base->SetDirectory(outputFolder.data());
  TList *listOfFiles = base->GetListOfFiles();
  TIter fileIt(listOfFiles);
  TFile *fileH = new TFile();
  Long64_t nfiles = 0;

  while( (fileH = (TFile*)fileIt()) ){
    
    std::string fileN = fileH->GetName();
    std::string baseString = "root";
    if( fileN.find(baseString) == std::string::npos ) continue;
    infiles.push_back(Form("%s/%s",outputFolder.data(),fileN.data()));
    nfiles++;
    
  }

  TFile *f_DY100 = NULL;
  TFile *f_DY200 = NULL;
  TFile *f_DY400 = NULL;
  TFile *f_DY600 = NULL;
  TFile *f_TTbar = NULL;
  TFile *f_WW    = NULL;
  TFile *f_WZ    = NULL;
  TFile *f_ZZ    = NULL;

  TCanvas* c = new TCanvas("c","",0,0,1000,800);

  c->cd();
  stackSamples(infiles,"corrPRmassAll_pDA","Corrected pruned mass",f_DY100,f_DY200,f_DY400,f_DY600,f_TTbar,f_WW,f_WZ,f_ZZ);
  c->Print("stackCorrPRmass.pdf(");

  c->cd();
  stackSamples(infiles,"PRmassAll_pDA","Uncorrected pruned mass",f_DY100,f_DY200,f_DY400,f_DY600,f_TTbar,f_WW,f_WZ,f_ZZ);
  c->Print("stackCorrPRmass.pdf)");


}
Exemple #2
0
QStringList QTar::getFileNameList() const {
	QStringList fileList;

	QListIterator<FileInfo> fileIt(getFileInfoList());
	while (fileIt.hasNext()) {
		fileList << fileIt.next().fileName;
	}

	return fileList;
}
Exemple #3
0
int main(int argc, char* argv[]) {
    std::ifstream dataFile(argv[1]);
    dataFile >> std::noskipws;
    std::istream_iterator<char> fileIt(dataFile), eof;
    std::string res(fileIt, eof);
 
    for (int i = 2; i < argc; i++) {
        auto tx = [&argv, &i](char c) {
            return (tolower(c) == argv[i][0] ?
                    (isupper(c) ? tolower(c) : toupper(c)) : c);
        };
        std::transform(res.begin(), res.end(), res.begin(), tx);
    }
    std::cout << res << std::endl;
    return 0;
}
Exemple #4
0
void BrowseThread::populateModel() {
    m_path_mutex.lock();
    QString thisPath = m_path;
    BrowseTableModel* thisModelObserver = m_model_observer;
    m_path_mutex.unlock();

    // Refresh the name filters in case we loaded new SoundSource plugins.
    QStringList nameFilters(SoundSourceProxy::supportedFileExtensionsString().split(" "));

    QDirIterator fileIt(thisPath, nameFilters, QDir::Files | QDir::NoDotAndDotDot);

    // remove all rows
    // This is a blocking operation
    // see signal/slot connection in BrowseTableModel
    emit(clearModel(thisModelObserver));

    QList< QList<QStandardItem*> > rows;

    int row = 0;
    // Iterate over the files
    while (fileIt.hasNext()) {
        // If a user quickly jumps through the folders
        // the current task becomes "dirty"
        m_path_mutex.lock();
        QString newPath = m_path;
        m_path_mutex.unlock();

        if(thisPath != newPath) {
            qDebug() << "Abort populateModel()";
            return populateModel();
        }

        QString filepath = fileIt.next();
        TrackInfoObject tio(filepath);
        QList<QStandardItem*> row_data;

        QStandardItem* item = new QStandardItem(tio.getFilename());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_FILENAME, item);

        item = new QStandardItem(tio.getArtist());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_ARTIST, item);

        item = new QStandardItem(tio.getTitle());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_TITLE, item);

        item = new QStandardItem(tio.getAlbum());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_ALBUM, item);

        item = new QStandardItem(tio.getAlbumArtist());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_ALBUMARTIST, item);

        item = new QStandardItem(tio.getTrackNumber());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_TRACK_NUMBER, item);

        item = new QStandardItem(tio.getYear());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_YEAR, item);

        item = new QStandardItem(tio.getGenre());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_GENRE, item);

        item = new QStandardItem(tio.getComposer());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_COMPOSER, item);

        item = new QStandardItem(tio.getGrouping());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_GROUPING, item);

        item = new QStandardItem(tio.getComment());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_COMMENT, item);

        QString duration = Time::formatSeconds(qVariantValue<int>(
                tio.getDuration()), false);
        item = new QStandardItem(duration);
        item->setToolTip(item->text());
        row_data.insert(COLUMN_DURATION, item);

        item = new QStandardItem(tio.getBpmStr());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_BPM, item);

        item = new QStandardItem(tio.getKeyText());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_KEY, item);

        item = new QStandardItem(tio.getType());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_TYPE, item);

        item = new QStandardItem(tio.getBitrateStr());
        item->setToolTip(item->text());
        row_data.insert(COLUMN_BITRATE, item);

        item = new QStandardItem(filepath);
        item->setToolTip(item->text());
        row_data.insert(COLUMN_LOCATION, item);

        rows.append(row_data);
        ++row;
        // If 10 tracks have been analyzed, send it to GUI
        // Will limit GUI freezing
        if(row % 10 == 0){
            // this is a blocking operation
            emit(rowsAppended(rows, thisModelObserver));
            //qDebug() << "Append " << rows.count() << " from " << filepath;
            rows.clear();
        }
        // Sleep additionally for 10ms which prevents us from GUI freezes
        msleep(20);
    }
    emit(rowsAppended(rows, thisModelObserver));
    //qDebug() << "Append last " << rows.count() << " from " << thisPath;
}
Exemple #5
0
void BrowseThread::populateModel() {
    m_path_mutex.lock();
    MDir thisPath = m_path;
    BrowseTableModel* thisModelObserver = m_model_observer;
    m_path_mutex.unlock();

    // Refresh the name filters in case we loaded new SoundSource plugins.
    QStringList nameFilters(SoundSourceProxy::getSupportedFileNamePatterns());

    QDirIterator fileIt(thisPath.dir().absolutePath(), nameFilters,
                        QDir::Files | QDir::NoDotAndDotDot);

    // remove all rows
    // This is a blocking operation
    // see signal/slot connection in BrowseTableModel
    emit(clearModel(thisModelObserver));

    QList< QList<QStandardItem*> > rows;

    int row = 0;
    // Iterate over the files
    while (fileIt.hasNext()) {
        // If a user quickly jumps through the folders
        // the current task becomes "dirty"
        m_path_mutex.lock();
        MDir newPath = m_path;
        m_path_mutex.unlock();

        if (thisPath.dir() != newPath.dir()) {
            qDebug() << "Abort populateModel()";
            return populateModel();
        }

        QList<QStandardItem*> row_data;

        QStandardItem* item = new QStandardItem("0");
        item->setData("0", Qt::UserRole);
        row_data.insert(COLUMN_PREVIEW, item);

        const QString filepath = fileIt.next();
        {
            const TrackPointer pTrack =
                    SoundSourceProxy::importTemporaryTrack(
                            filepath,
                            thisPath.token());

            item = new QStandardItem(pTrack->getFileName());
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_FILENAME, item);

            item = new QStandardItem(pTrack->getArtist());
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_ARTIST, item);

            item = new QStandardItem(pTrack->getTitle());
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_TITLE, item);

            item = new QStandardItem(pTrack->getAlbum());
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_ALBUM, item);

            item = new QStandardItem(pTrack->getAlbumArtist());
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_ALBUMARTIST, item);

            item = new QStandardItem(pTrack->getTrackNumber());
            item->setToolTip(item->text());
            item->setData(item->text().toInt(), Qt::UserRole);
            row_data.insert(COLUMN_TRACK_NUMBER, item);

            const QString year(pTrack->getYear());
            item = new YearItem(year);
            item->setToolTip(year);
            // The year column is sorted according to the numeric calendar year
            item->setData(mixxx::TrackMetadata::parseCalendarYear(year), Qt::UserRole);
            row_data.insert(COLUMN_YEAR, item);

            item = new QStandardItem(pTrack->getGenre());
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_GENRE, item);

            item = new QStandardItem(pTrack->getComposer());
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_COMPOSER, item);

            item = new QStandardItem(pTrack->getGrouping());
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_GROUPING, item);

            item = new QStandardItem(pTrack->getComment());
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_COMMENT, item);

            QString duration = pTrack->getDurationText(mixxx::Duration::Precision::SECONDS);
            item = new QStandardItem(duration);
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_DURATION, item);

            item = new QStandardItem(pTrack->getBpmText());
            item->setToolTip(item->text());
            item->setData(pTrack->getBpm(), Qt::UserRole);
            row_data.insert(COLUMN_BPM, item);

            item = new QStandardItem(pTrack->getKeyText());
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_KEY, item);

            item = new QStandardItem(pTrack->getType());
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_TYPE, item);

            item = new QStandardItem(pTrack->getBitrateText());
            item->setToolTip(item->text());
            item->setData(pTrack->getBitrate(), Qt::UserRole);
            row_data.insert(COLUMN_BITRATE, item);

            QString location = pTrack->getLocation();
            QString nativeLocation = QDir::toNativeSeparators(location);
            item = new QStandardItem(nativeLocation);
            item->setToolTip(nativeLocation);
            item->setData(location, Qt::UserRole);
            row_data.insert(COLUMN_NATIVELOCATION, item);

            QDateTime modifiedTime = pTrack->getFileModifiedTime().toLocalTime();
            item = new QStandardItem(modifiedTime.toString(Qt::DefaultLocaleShortDate));
            item->setToolTip(item->text());
            item->setData(modifiedTime, Qt::UserRole);
            row_data.insert(COLUMN_FILE_MODIFIED_TIME, item);

            QDateTime creationTime = pTrack->getFileCreationTime().toLocalTime();
            item = new QStandardItem(creationTime.toString(Qt::DefaultLocaleShortDate));
            item->setToolTip(item->text());
            item->setData(creationTime, Qt::UserRole);
            row_data.insert(COLUMN_FILE_CREATION_TIME, item);

            const mixxx::ReplayGain replayGain(pTrack->getReplayGain());
            item = new QStandardItem(
                    mixxx::ReplayGain::ratioToString(replayGain.getRatio()));
            item->setToolTip(item->text());
            item->setData(item->text(), Qt::UserRole);
            row_data.insert(COLUMN_REPLAYGAIN, item);
        } // implicitly release track pointer and unlock cache

        rows.append(row_data);
        ++row;
        // If 10 tracks have been analyzed, send it to GUI
        // Will limit GUI freezing
        if (row % 10 == 0) {
            // this is a blocking operation
            emit(rowsAppended(rows, thisModelObserver));
            qDebug() << "Append " << rows.count() << " from " << filepath;
            rows.clear();
        }
        // Sleep additionally for 10ms which prevents us from GUI freezes
        msleep(20);
    }
    emit(rowsAppended(rows, thisModelObserver));
    qDebug() << "Append last " << rows.count();
}
Exemple #6
0
std::vector<FileData> getFileDataFrom(const FS_NAMESPACE::path & inPath, const FS_NAMESPACE::path & outPath, const FS_NAMESPACE::path & parentDir, const bool recurse)
{
	// get all files from directory
	std::vector<FileData> files;
	// check for infinite symlinks
	if (FS_NAMESPACE::is_symlink(inPath))
	{
		// check if the symlink points somewhere in the path. this would recurse
		if (inPath.string().find(FS_NAMESPACE::canonical(inPath).string()) == 0)
		{
			std::cout << "Warning: Path " << inPath << " contains recursive symlink! Skipping." << std::endl;
			return files;
		}
	}
	// iterate through source directory searching for files
	const FS_NAMESPACE::directory_iterator dirEnd;
	for (FS_NAMESPACE::directory_iterator fileIt(inPath); fileIt != dirEnd; ++fileIt)
	{
		FS_NAMESPACE::path filePath = (*fileIt).path();
		if (!FS_NAMESPACE::is_directory(filePath))
		{
			if (beVerbose)
			{
				std::cout << "Found input file " << filePath << std::endl;
			}
			// add file to list
			FileData temp;
			temp.inPath = filePath;
			// replace dots in file name with '_' and add a .c/.cpp extension
			std::string newFileName = filePath.filename().generic_string();
			std::replace(newFileName.begin(), newFileName.end(), '.', '_');
			if (useC)
			{
				newFileName.append(".c");
			}
			else
			{
				newFileName.append(".cpp");
			}
			// remove parent directory of file from path for internal name. This could surely be done in a safer way
			FS_NAMESPACE::path subPath(filePath.generic_string().substr(parentDir.generic_string().size() + 1));
			// add a ":/" before the name to mark internal resources (Yes. Hello Qt!)
			temp.internalName = ":/" + subPath.generic_string();
			// add subdir below parent path to name to enable multiple files with the same name
			std::string subDirString(subPath.remove_filename().generic_string());
			if (!subDirString.empty())
			{
				// replace dir separators by underscores
				std::replace(subDirString.begin(), subDirString.end(), '/', '_');
				// add in front of file name
				newFileName = subDirString + "_" + newFileName;
			}
			// build new output file name
			temp.outPath = outPath / newFileName;
			if (beVerbose)
			{
				std::cout << "Internal name will be \"" << temp.internalName << "\"" << std::endl;
				std::cout << "Output path is " << temp.outPath << std::endl;
			}
			// get file size
			try
			{
				temp.size = static_cast<uint64_t>(FS_NAMESPACE::file_size(filePath));
				if (beVerbose)
				{
					std::cout << "Size is " << temp.size << " bytes." << std::endl;
				}
			}
			catch (...)
			{
				std::cout << "Error: Failed to get size of " << filePath << "!" << std::endl;
				temp.size = 0;
			}
			// add file to list
			files.push_back(temp);
		}
	}
	// does the user want subdirectories?
	if (recurse)
	{
		// iterate through source directory again searching for directories
		for (FS_NAMESPACE::directory_iterator dirIt(inPath); dirIt != dirEnd; ++dirIt)
		{
			FS_NAMESPACE::path dirPath = (*dirIt).path();
			if (FS_NAMESPACE::is_directory(dirPath))
			{
				if (beVerbose)
				{
					std::cout << "Found subdirectory " << dirPath << std::endl;
				}
				// subdirectory found. recurse.
				std::vector<FileData> subFiles = getFileDataFrom(dirPath, outPath, parentDir, recurse);
				// add returned result to file list
				files.insert(files.end(), subFiles.cbegin(), subFiles.cend());
			}
		}
	}
	// return result
	return files;
}
Exemple #7
0
void dataMCplots(std::string outputFolder, std::string pdfName){

  std::vector<string> infiles;
 
  TSystemDirectory *base = new TSystemDirectory("root","root");
  base->SetDirectory(outputFolder.data());
  TList *listOfFiles = base->GetListOfFiles();
  TIter fileIt(listOfFiles);
  TFile *fileH = new TFile();
  Long64_t nfiles = 0;

  while( (fileH = (TFile*)fileIt()) ){
    
    std::string fileN = fileH->GetName();
    std::string baseString = "root";
    if( fileN.find(baseString) == std::string::npos ) continue;
    infiles.push_back(Form("%s/%s",outputFolder.data(),fileN.data()));
    nfiles++;
    
  }

  TFile *f_DY100 = NULL;
  TFile *f_DY200 = NULL;
  TFile *f_DY400 = NULL;
  TFile *f_DY600 = NULL;
  TFile *f_TTbar = NULL;
  TFile *f_WW    = NULL;
  TFile *f_WZ    = NULL;
  TFile *f_ZZ    = NULL;
  TFile *f_data0 = NULL;
  TFile *f_data1 = NULL;

  Double_t xSecDY100 = 147.4;
  Double_t xSecDY200 = 40.99;
  Double_t xSecDY400 = 5.678;
  Double_t xSecDY600 = 2.198;
  Double_t xSecTTbar = 831.76;
  Double_t xSecWW    = 118.7;
  Double_t xSecWZ    = 47.13;
  Double_t xSecZZ    = 16.523;

//  xSecDY100 = xSecDY100 * 1.23;
//  xSecDY200 = xSecDY200 * 1.23;
//  xSecDY400 = xSecDY400 * 1.23;
//  xSecDY600 = xSecDY600 * 1.23;

  xSecDY100 = xSecDY100 * 1.588;
  xSecDY200 = xSecDY200 * 1.438;
  xSecDY400 = xSecDY400 * 1.494;
  xSecDY600 = xSecDY600 * 1.139;

  Double_t scaleDY100 = 0;
  Double_t scaleDY200 = 0;
  Double_t scaleDY400 = 0;
  Double_t scaleDY600 = 0;
  Double_t scaleTTbar = 0;
  Double_t scaleWW    = 0;
  Double_t scaleWZ    = 0;
  Double_t scaleZZ    = 0;

  Double_t dummy = -1;

  for(unsigned int i = 0; i < infiles.size(); i++){

    cout << "Input file: " << infiles[i] << endl;

    if( infiles[i].find("HT-100") != std::string::npos )    
      f_DY100 = getFile(infiles[i].data(), xSecDY100, &scaleDY100);

    if( infiles[i].find("HT-200") != std::string::npos )
      f_DY200 = getFile(infiles[i].data(), xSecDY200, &scaleDY200);

    if( infiles[i].find("HT-400") != std::string::npos )
      f_DY400 = getFile(infiles[i].data(), xSecDY400, &scaleDY400); 

    if( infiles[i].find("HT-600") != std::string::npos )
      f_DY600 = getFile(infiles[i].data(), xSecDY600, &scaleDY600);

    if( infiles[i].find("TT_") != std::string::npos )
      f_TTbar = getFile(infiles[i].data(), xSecTTbar, &scaleTTbar);

    if( infiles[i].find("WW_") != std::string::npos )
      f_WW = getFile(infiles[i].data(), xSecWW, &scaleWW);

    if( infiles[i].find("WZ_") != std::string::npos )
      f_WZ = getFile(infiles[i].data(), xSecWZ, &scaleWZ);

    if( infiles[i].find("ZZ_") != std::string::npos )
      f_ZZ = getFile(infiles[i].data(), xSecZZ, &scaleZZ);

    if( infiles[i].find("V12015") != std::string::npos )
      f_data0 = getFile(infiles[i].data(), dummy, &dummy);

    if( infiles[i].find("V42015") != std::string::npos )
      f_data1 = getFile(infiles[i].data(), dummy, &dummy);

  }

  setNCUStyle(true);

  Double_t up_height     = 0.8;
  Double_t dw_correction = 1.455;
  Double_t dw_height     = (1-up_height)*dw_correction;

  TCanvas c("c","",0,0,1000,900);
  c.Divide(1,2);

  TPad* c_up = (TPad*) c.GetListOfPrimitives()->FindObject("c_1");
  TPad* c_dw = (TPad*) c.GetListOfPrimitives()->FindObject("c_2"); 

  c_up->SetPad(0,1-up_height,1,1);
  c_dw->SetPad(0,0,1,dw_height);
  c_dw->SetBottomMargin(0.25);

  // To get the name of histograms
  
  TFile *f_ = TFile::Open(infiles[0].data());
  f_->cd();
  
  TDirectory *current_sourcedir = gDirectory;
  TIter nextkey( current_sourcedir->GetListOfKeys() );
  TKey *key;

  vector<std::string> h_name;

  while ( (key = (TKey*)nextkey()) ) {

    TObject *obj = key->ReadObj();

    if ( obj->IsA()->InheritsFrom("TH1") ) 
      h_name.push_back(obj->GetTitle());

  }

  // Draw and output
  
  for(unsigned int i = 0; i < h_name.size()-1; i++){

    if( h_name[i]=="eleHoverE" || h_name[i]=="eleMiniIsoEA" || h_name[i]=="muMiniIsoEA" )
      c_up->cd()->SetLogy(1);
    else
      c_up->cd()->SetLogy(0);
    
    TH1D *h_data = (TH1D*)(f_data1->Get(h_name[i].data()))->Clone("h_data");
    TH1D *h_bkg  = (TH1D*)(f_data1->Get(h_name[i].data()))->Clone("h_bkg");
    
    myPlot(((TH1D*)(f_DY100->Get(h_name[i].data()))),
	   ((TH1D*)(f_DY200->Get(h_name[i].data()))),
	   ((TH1D*)(f_DY400->Get(h_name[i].data()))),
	   ((TH1D*)(f_DY600->Get(h_name[i].data()))),
	   ((TH1D*)(f_TTbar->Get(h_name[i].data()))),
	   ((TH1D*)(f_WW->Get(h_name[i].data()))),
	   ((TH1D*)(f_WZ->Get(h_name[i].data()))),
	   ((TH1D*)(f_ZZ->Get(h_name[i].data()))),
	   ((TH1D*)(f_data0->Get(h_name[i].data()))),
	   ((TH1D*)(f_data1->Get(h_name[i].data()))),
	   scaleDY100,
	   scaleDY200,
	   scaleDY400,
	   scaleDY600,
	   scaleTTbar,
	   scaleWW,
	   scaleWZ,
	   scaleZZ,
	   h_data,
	   h_bkg);

    c_up->RedrawAxis();

    c_dw->cd();

    myRatio(h_data, h_bkg);

    c.Draw();
    
    if( i == 0 ) c.Print(Form("%s.pdf(", pdfName.data()), "pdf");
    else if( i == h_name.size()-2 ) c.Print(Form("%s.pdf)", pdfName.data()), "pdf");
    else c.Print(Form("%s.pdf", pdfName.data()), "pdf");
    
  }

}
Exemple #8
0
void InternalScanPluginDir (iStringArray*& messages,
			    const char* dir, 
			    csRef<iStringArray>& plugins,
			    bool recursive)
{
  csStringHash files;
  csStringHash dirs;

  csString filemask;

  // The directory sometimes has a trailing path separator attached.
  if (!strlen(dir) || dir[strlen(dir)-1] == CS_PATH_SEPARATOR)
      filemask << dir  << "*.*";
  else
      filemask << dir << CS_PATH_SEPARATOR << "*.*";

  WIN32_FIND_DATA findData;
  HANDLE hSearch = FindFirstFile (filemask, &findData);
  if (hSearch != INVALID_HANDLE_VALUE)
  {
    do
    {
      if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      {
	/*
	  instead of processing them immediately, first a list of
	  directories is filled.
	 */
	if (recursive && (strcmp (findData.cFileName, ".") != 0)
	  && (strcmp (findData.cFileName, "..") != 0))
	{
	  // Add file names in lower case, as Win32 doesn't care about FS case.
	  AddLower (dirs, findData.cFileName);
	}
      }
      else
      {
	/*
	  instead of processing them immediately, first a list of
	  plugin files is created.
	 */
	char* ext = strrchr (findData.cFileName, '.');
        if (ext && ((strcasecmp (ext, ".dll") == 0) || 
	  (strcasecmp (ext, ".csplugin") == 0)))
	{
	  AddLower (files, findData.cFileName);
	}
      }
    }
    while (FindNextFile (hSearch, &findData));
    FindClose (hSearch);
  }
  else
  {
    DWORD errorCode = GetLastError();

    /*
      The plugin paths list also contains non-existent entries -
      don't emit an error for those.
     */
    if (errorCode != ERROR_PATH_NOT_FOUND)
    {
      AppendWin32Error ("FindFirst() call failed",
	errorCode,
	messages);
    }
  }

  // Now go over all the files.  This way files in a dir will have precedence
  // over files a subdir.
  {
    csStringHash::GlobalIterator fileIt(files.GetIterator());
    csString fullPath;

    csRef<iString> msg;

    while (fileIt.HasNext())
    {
      csStringID id = fileIt.Next();

      const char* fileName = files.Request (id);

      const char* ext = strrchr (fileName, '.');
      // ignore .csplugins, there are checked explicitly.
      if ((strcasecmp (ext, ".dll") == 0))
      {
	fullPath.Clear();
	// The directory sometimes has a trailing path separator attached.
	if (!strlen(dir) || dir[strlen(dir)-1] == CS_PATH_SEPARATOR)
	  fullPath << dir << fileName;
	else
	  fullPath << dir << CS_PATH_SEPARATOR << fileName;

	/*
	  Check whether the DLL has a companion .csplugin.
	 */
	char cspluginFile [MAX_PATH + 10];

	strcpy (cspluginFile, fileName);
	char* dot = strrchr (cspluginFile, '.');
	strcpy (dot, ".csplugin");

	csStringID cspID = files.Request (cspluginFile);
	if (cspID != csInvalidStringID)
	{
	  char cspluginPath [MAX_PATH + 10];

	  strcpy (cspluginPath, fullPath);
	  char* dot = strrchr (cspluginPath, '.');
	  strcpy (dot, ".csplugin");

          plugins->Push (cspluginPath);
	}
	else
	{
          plugins->Push (fullPath);
	}
      }
    }

    // release some memory.
    files.Clear();
  }
  {
    csStringHash::GlobalIterator dirIt(dirs.GetIterator());
    csString fullPath;

    while (dirIt.HasNext())
    {
      csStringID id = dirIt.Next();

      fullPath.Clear();
      fullPath << dir << CS_PATH_SEPARATOR << dirs.Request (id);

      iStringArray* subdirMessages = 0;
      InternalScanPluginDir (subdirMessages, fullPath, plugins,
	recursive);
      
      if (subdirMessages != 0)
      {
	for (size_t i = 0; i < subdirMessages->GetSize (); i++)
	{
	  AppendStrVecString (messages, subdirMessages->Get (i));
	}

	subdirMessages->DecRef();
      }
    }
  }
}