text: #include <cstdlib>
  #include <iostream>
  #include <string>
  #include <vector>
  
  #include "DetectorDescription/Core/interface/DDCompactView.h"
  #include "DetectorDescription/Parser/interface/DDLParser.h"
  #include "DetectorDescription/Parser/interface/DDLSAX2FileHandler.h"
  #include "DetectorDescription/Parser/interface/FIPConfiguration.h"
  #include "DetectorDescription/RegressionTest/interface/DDCompareTools.h"
  #include "FWCore/MessageLogger/interface/MessageLogger.h"
  #include "FWCore/PluginManager/interface/PluginManager.h"
  #include "FWCore/PluginManager/interface/standard.h"
  #include "FWCore/Utilities/interface/Exception.h"
  #include <boost/program_options.hpp>
  #include <boost/exception/all.hpp>
  
  int main(int argc, char *argv[])
  {
    try
    {
      edmplugin::PluginManager::configure(edmplugin::standard::config());
    }
    catch (cms::Exception& e)
    {
      edm::LogInfo("DDCompareCPV") << "Attempting to configure the plugin manager. Exception message: " << e.what();
      return 1;
    }
    
      // Process the command line arguments
      std::string descString("DDCompareCPV");
      descString += " [options] configurationFileName1 configurationFileName2 Compares two DDCompactViews\n";
      descString += "Allowed options";
      boost::program_options::options_description desc(descString);   
      desc.add_options()
        ("help,h", "Print this help message")
        ("file1,f", boost::program_options::value<std::string>(), "XML configuration file name. "
         "Default is DetectorDescription/RegressionTest/test/configuration.xml")
        ("file2,g", boost::program_options::value<std::string>(), "XML configuration file name. "
         "Default is DetectorDescription/RegressionTest/test/configuration.xml")
        ("dist-tolerance,t", boost::program_options::value<std::string>(), "Value tolerance for distances (in mm). "
         "Default value 0.0004 (anything larger is an error)")
        ("rot-tolerance,r", boost::program_options::value<std::string>(), "Value tolerance for rotation matrix elements. "
         "Default value is 0.0004 (anything larger is an error)")
        ("spec-tolerance,s", boost::program_options::value<std::string>(), "Value tolerance for rotation matrix elements. "
         "Default value is 0.0004 (anything larger is an error) NOT USED YET")
        ("user-ns,u", "Use the namespaces in each file and do NOT use the filename as namespace. "
         "Default is to use the filename of each file in the configuration.xml file as a filename")
        ("comp-rot,c", "Use the rotation name when comparing rotations. "
         "Default is to use the matrix only and not the name when comparing DDRotations")
        ("continue-on-error,e", "Continue after an error in values. "
         "Default is to stop at the first error. NOT IMPLEMENTED")
        ("attempt-resync,a", "Continue after an error in graph position, attempt to resync. "
         "Default is to stop at the first mis-match of the graph. NOT IMPLEMENTED");
      
      boost::program_options::positional_options_description p;
      p.add("file1", 1);
      p.add("file2", 2);
      
      boost::program_options::variables_map vm;
      try {
        store(boost::program_options::command_line_parser(argc,argv).options(desc).positional(p).run(),vm);
        notify(vm);
      } catch(boost::program_options::error const& iException) {
        std::cerr << "Exception from command line processing: "
                  << iException.what() << "\n";
        std::cerr << desc << std::endl;
        return 1;
      }
      if(vm.count("help")) {
        std::cout << desc << std::endl;
        return 0;
      }
  
      bool fullPath = false;
      std::string configfile("DetectorDescription/RegressionTest/test/configuration.xml");
      std::string configfile2("DetectorDescription/RegressionTest/test/configuration.xml");
      DDCompOptions ddco;
      //    double dtol(0.0004), rottol(0.0004);
      // bool usrns(false), comprot(false);
      bool usrns(false);
      try {
        if (vm.count("file1")) {
  	configfile = vm["file1"].as<std::string>();
  	if (vm.count("file2")) {
  	  configfile2 = vm["file2"].as<std::string>();
  	}
        }
        if (vm.count("dist-tolerance"))
  	ddco.distTol_ = vm["dist-tolerance"].as<double>();
        if (vm.count("rot-tolerance"))
  	ddco.rotTol_ = vm["rot-tolerance"].as<double>();
        if (vm.count("spec-tolerance"))
  	ddco.rotTol_ = vm["spec-tolerance"].as<double>();
        if (vm.count("user-ns")) 
  	usrns = true;
        if (vm.count("comp-rot")) 
  	ddco.compRotName_ = true;
        if (vm.count("continue-on-error")) 
  	ddco.contOnError_ = true;
        if (vm.count("attempt-resync"))
  	ddco.attResync_ = true;
      }
      catch(boost::exception& e)
      {
        edm::LogInfo("DDCompareCPV") << "Attempting to parse the options. Exception message: " << boost::diagnostic_information(e);
        return 1;
      }
  
      std::ios_base::fmtflags originalFlags = std::cout.flags();
      
      std::cout << "Settings are: " << std::endl;
      std::cout << "Configuration file 1: " << configfile << std::endl;
      std::cout << "Configuration file 2: " << configfile2 << std::endl;
      std::cout << "Length/distance tolerance: " << ddco.distTol_ << std::endl;
      std::cout << "Rotation matrix element tolerance: " << ddco.rotTol_ << std::endl;
      std::cout << "SpecPar tolerance: " << ddco.specTol_ << std::endl;
      std::cout << "User controlled namespace (both file sets)? " << std::boolalpha << usrns << std::endl;
      std::cout << "Compare Rotation names? " << ddco.compRotName_ << std::endl;
      std::cout << "Continue on error (data mismatch)? " << ddco.contOnError_ << std::endl;
      std::cout << "Attempt resyncronization of disparate graphs? " << ddco.attResync_ << std::endl;
  
      DDCompactView cpv1;
      DDLParser myP(cpv1);
      myP.getDDLSAX2FileHandler()->setUserNS(usrns);
  
      /* The configuration file tells the parser what to parse.
         The sequence of files to be parsed does not matter but for one exception:
         XML containing SpecPar-tags must be parsed AFTER all corresponding
         PosPart-tags were parsed. (Simply put all SpecPars-tags into seperate
         files and mention them at end of configuration.xml. Functional SW 
         will not suffer from this restriction).
      */  
  
      // Use the File-In-Path configuration document provider.
      FIPConfiguration fp(cpv1);
      try
      {
        fp.readConfig(configfile, fullPath);
      }
      catch (cms::Exception& e)
      {
        edm::LogInfo("DDCompareCPV") << "Attempting to read config. Exception message: " << e.what();
        return 1;
      }
      
      std::cout << "FILE 1: " << configfile << std::endl;
      if ( fp.getFileList().empty() ) {
        std::cout << "FILE 1: configuration file has no DDD xml files in it!" << std::endl;
        exit(1);
      }
      int parserResult = myP.parse(fp);
      if (parserResult != 0) {
        std::cout << "FILE 1: problem encountered during parsing. exiting ... " << std::endl;
        exit(1);
      }
      cpv1.lockdown();
  
      DDCompactView cpv2;
      DDLParser myP2(cpv2);
      myP2.getDDLSAX2FileHandler()->setUserNS(usrns);
  
      /* The configuration file tells the parser what to parse.
         The sequence of files to be parsed does not matter but for one exception:
         XML containing SpecPar-tags must be parsed AFTER all corresponding
         PosPart-tags were parsed. (Simply put all SpecPars-tags into seperate
         files and mention them at end of configuration.xml. Functional SW 
         will not suffer from this restriction).
      */  
  
      // Use the File-In-Path configuration document provider.
      FIPConfiguration fp2(cpv2);
      fp2.readConfig(configfile2, fullPath);
      std::cout << "FILE 2: " << configfile2 << std::endl;
      if ( fp2.getFileList().empty() ) {
        std::cout << "FILE 2: configuration file has no DDD xml files in it!" << std::endl;
        exit(1);
      }
      int parserResult2 = myP2.parse(fp2);
      if (parserResult2 != 0) {
        std::cout << "FILE 2: problem encountered during parsing. exiting ... " << std::endl;
        exit(1);
      }
      cpv2.lockdown();
  
      std::cout << "Parsing completed. Start comparing." << std::endl;
  
  //      DDErrorDetection ed(cpv1);
  
  //      bool noErrors = ed.noErrorsInTheReport(cpv1);
  //      if (noErrors && fullPath) {
  //        std::cout << "DDCompareCPV did not find any errors and is finished." << std::endl;
  //      }
  //     else {
  //       ed.report(cpv1, std::cout);
  //       if (!noErrors) {
  //         return 1;
  //       }
  //     }
  
      DDCompareCPV ddccpv(ddco);
      bool graphmatch = ddccpv(cpv1, cpv2);
  
      if (graphmatch) {
        std::cout << "DDCompactView graphs match" << std::endl;
      } else {
        std::cout << "DDCompactView graphs do NOT match" << std::endl;
      }
  
      // Now set everything back to defaults
      std::cout.flags( originalFlags );
  
      return 0;
  }
  