text: from __future__ import print_function
  
  import os
  import shutil
  import sys
  import time
  import glob
  import importlib
  import logging
  import subprocess
  
  # as we need to load the shared lib from here, make sure it's in our path:
  if os.path.join( os.environ['CMSSW_BASE'], 'src') not in sys.path:
      sys.path.append( os.path.join( os.environ['CMSSW_BASE'], 'src') )
  
  # -------------------------------------------------------------------------------------------------------
  
  payload2xmlCodeTemplate = """
  
  #include "CondCore/Utilities/interface/Payload2XMLModule.h"
  #include "CondCore/Utilities/src/CondFormats.h"
  
  PAYLOAD_2XML_MODULE( %s ){
    PAYLOAD_2XML_CLASS( %s );
  }
  
  """ 
  
  buildFileTemplate = """
  <flags CXXFLAGS="-Wno-sign-compare -Wno-unused-variable -Os"/>
  <library   file="%s" name="%s">
    <use   name="CondCore/Utilities"/>
    <use name="py3-pybind11"/>
    <use name="python3"/>
  </library>
  <export>
    <lib   name="1"/>
  </export>
  """
  
  # helper function
  def sanitize(typeName):
      return typeName.replace(' ','').replace('<','_').replace('>','')
  
  def localLibName( payloadType ):
      # required to avoid ( unlikely ) clashes between lib names from templates and lib names from classes
      prefix = ''
      if '<' in payloadType and '>' in payloadType:
          prefix = 't'
      ptype = payloadType
      if '::' in payloadType:
          ptype = payloadType.replace('::','_')
      return "%s_%spayload2xml" %(sanitize(ptype),prefix)
  
  class CondXmlProcessor(object):
  
      def __init__(self, condDBIn):
          self.conddb = condDBIn
  
          if not os.path.exists( os.path.join( os.environ['CMSSW_BASE'], 'src') ):
              raise Exception("Looks like you are not running in a CMSSW developer area, $CMSSW_BASE/src/ does not exist")
  
          self.fakePkgName = "fakeSubSys4pl/fakePkg4pl"
          self._pl2xml_tmpDir = os.path.join( os.environ['CMSSW_BASE'], 'src', self.fakePkgName )
  
          self.doCleanup = False
  
      def __del__(self):
  
          if self.doCleanup: 
              shutil.rmtree( '/'.join( self._pl2xml_tmpDir.split('/')[:-1] ) )
          return 
  
      def discover(self, payloadType):
  
          libName = 'pluginUtilities_payload2xml.so'
          # first search: developer area or main release
          libDir = os.path.join( os.environ["CMSSW_BASE"], 'lib', os.environ["SCRAM_ARCH"] )
          devLibDir = libDir
          libPath = os.path.join( devLibDir, libName )
          releaseBase = os.environ["CMSSW_RELEASE_BASE"]
          devCheckout = (releaseBase != '')
          if not devCheckout:
              logging.debug('Looks like the current working environment is a read-only release')
          if not os.path.exists( libPath ) and devCheckout:
              # main release ( for dev checkouts )
              libDir = os.path.join( releaseBase, 'lib', os.environ["SCRAM_ARCH"] )
              libPath = os.path.join( libDir, libName )
              if not os.path.exists( libPath ):
                  if "CMSSW_FULL_RELEASE_BASE" in os.environ:
                      libDir = os.path.join( os.environ["CMSSW_FULL_RELEASE_BASE"], 'lib', os.environ["SCRAM_ARCH"] )
                      libPath = os.path.join( libDir, libName )
          if not os.path.exists( libPath ):
              # it should never happen!
              raise Exception('No built-in library %s found with XML converters.' %libPath)
          logging.debug("Importing built-in library %s" %libPath)
          module = importlib.import_module( libName.replace('.so', '') )
          functors = dir(module)
          funcName = payloadType+'2xml'
          if funcName in functors:
              logging.info('XML converter for payload class %s found in the built-in library.' %payloadType)
              return getattr( module, funcName)
          if not devCheckout:
              # give-up if it is a read-only release...
              raise Exception('No XML converter suitable for payload class %s has been found in the built-in library.')
          libName = 'plugin%s.so' %localLibName( payloadType )
          libPath = os.path.join( devLibDir, libName )
          if os.path.exists( libPath ):
              logging.info('Found local library with XML converter for class %s' %payloadType )
              module = importlib.import_module( libName.replace('.so', '') )
              return getattr( module, funcName)
          logging.warning('No XML converter for payload class %s found in the built-in library.' %payloadType)
          return None
  
      def prepPayload2xml(self, payloadType):
  
          converter = self.discover(payloadType)
          if converter: return converter
  
          #otherwise, go for the code generation in the local checkout area.
          startTime = time.time()
  
          libName = localLibName( payloadType )
          pluginName = 'plugin%s' % libName
          tmpLibName = "Tmp_payload2xml"
          tmpPluginName = 'plugin%s' %tmpLibName
  
          libDir = os.path.join( os.environ["CMSSW_BASE"], 'lib', os.environ["SCRAM_ARCH"] )
          tmpLibFile = os.path.join( libDir,tmpPluginName+'.so' )
          code = payload2xmlCodeTemplate %(pluginName,payloadType) 
  
          tmpSrcFileName = 'Local_2XML.cpp' 
          tmpDir = self._pl2xml_tmpDir
          if ( os.path.exists( tmpDir ) ) :
              msg = '\nERROR: %s already exists, please remove if you did not create that manually !!' % tmpDir
              raise Exception(msg)
  
          logging.debug('Creating temporary package %s' %self._pl2xml_tmpDir)
          os.makedirs( tmpDir+'/plugins' )
  
          buildFileName = "%s/plugins/BuildFile.xml" % (tmpDir,)
          with open(buildFileName, 'w') as buildFile:
              buildFile.write( buildFileTemplate %(tmpSrcFileName,tmpLibName) )
              buildFile.close()
  
          tmpSrcFilePath = "%s/plugins/%s" % (tmpDir, tmpSrcFileName,)
          with open(tmpSrcFilePath, 'w') as codeFile:
              codeFile.write(code)
              codeFile.close()
  
          cmd = "source $CMS_PATH/cmsset_default.sh;"
          cmd += "(cd %s ; scram b 2>&1 >build.log)" %tmpDir
          pipe = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
          out, err = pipe.communicate()
          ret = pipe.returncode
  
          buildTime = time.time()-startTime
          logging.info("Building done in %s sec., return code from build: %s" %(buildTime,ret) )
  
          if (ret != 0):
              logging.error("Local build for xml dump failed.")
              return None
  
          libFile = os.path.join(libDir,pluginName + '.so')
          shutil.copyfile(tmpLibFile,libFile)
  
          module =  importlib.import_module( pluginName )
          funcName = payloadType+'2xml'
          functor = getattr( module, funcName ) 
          self.doCleanup = True
          return functor
  
      def payload2xml(self, session, payloadHash, destFile):
  
          Payload = session.get_dbtype(self.conddb.Payload)
          # get payload from DB:
          result = session.query(Payload.data, Payload.object_type).filter(Payload.hash == payloadHash).one()
          data, plType = result
          logging.info('Found payload of type %s' %plType)
  
          convFuncName = sanitize(plType)+'2xml'
          xmlConverter = self.prepPayload2xml(plType)
  
          if xmlConverter is not None:
              obj = xmlConverter()
              resultXML = obj.write( data )
              if destFile is None:
                  print(resultXML)    
              else:
                  with open(destFile, 'w') as outFile:
                      outFile.write(resultXML)
                      outFile.close()
  