text:
//////////////////////////////////////////////////////////////////
// (c) Copyright 2003-  by Jeongnim Kim
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
//   National Center for Supercomputing Applications &
//   Materials Computation Center
//   University of Illinois, Urbana-Champaign
//   Urbana, IL 61801
//   e-mail: jnkim@ncsa.uiuc.edu
//
// Supported by
//   National Center for Supercomputing Applications, UIUC
//   Materials Computation Center, UIUC
//////////////////////////////////////////////////////////////////
#include "QMCWaveFunctions/BasisSetFactory.h"
#include "QMCWaveFunctions/Fermion/SlaterDetBuilder.h"
#include "Utilities/ProgressReportEngine.h"
#include "OhmmsData/AttributeSet.h"

#include "QMCWaveFunctions/Fermion/MultiSlaterDeterminant.h"
#include "QMCWaveFunctions/Fermion/MultiSlaterDeterminantFast.h"
//this is only for Bryan
#if defined(BRYAN_MULTIDET_TRIAL)
#include "QMCWaveFunctions/Fermion/DiracDeterminantIterative.h"
#include "QMCWaveFunctions/Fermion/DiracDeterminantTruncation.h"
#include "QMCWaveFunctions/Fermion/MultiDiracDeterminantBase.h"
#endif
//Cannot use complex and released node
#if !defined(QMC_COMPLEX)
#include "QMCWaveFunctions/Fermion/RNDiracDeterminantBase.h"
#include "QMCWaveFunctions/Fermion/RNDiracDeterminantBaseAlternate.h"
#endif
#ifdef QMC_CUDA
#include "QMCWaveFunctions/Fermion/DiracDeterminantCUDA.h"
#endif
#include "QMCWaveFunctions/Fermion/BackflowBuilder.h"
#include "QMCWaveFunctions/Fermion/SlaterDetWithBackflow.h"
#include "QMCWaveFunctions/Fermion/MultiSlaterDeterminantWithBackflow.h"
#include "QMCWaveFunctions/Fermion/DiracDeterminantWithBackflow.h"
#include<vector>
//#include "QMCWaveFunctions/Fermion/ci_node.h"
#include "QMCWaveFunctions/Fermion/ci_configuration.h"
#include "QMCWaveFunctions/Fermion/ci_configuration2.h"
#include "QMCWaveFunctions/Fermion/SPOSetProxy.h"
#include "QMCWaveFunctions/Fermion/SPOSetProxyForMSD.h"
#include "QMCWaveFunctions/Fermion/DiracDeterminantOpt.h"
#include "QMCWaveFunctions/Fermion/DiracDeterminantAFM.h"

#include <bitset>

namespace qmcplusplus
{

SlaterDetBuilder::SlaterDetBuilder(ParticleSet& els, TrialWaveFunction& psi,
                                   PtclPoolType& psets)
  : OrbitalBuilderBase(els,psi), ptclPool(psets)
  , myBasisSetFactory(0), slaterdet_0(0), multislaterdet_0(0)
  , multislaterdetfast_0(0)
{
  ClassName="SlaterDetBuilder";
  BFTrans=0;
  UseBackflow=false;
}
SlaterDetBuilder::~SlaterDetBuilder()
{
  DEBUG_MEMORY("SlaterDetBuilder::~SlaterDetBuilder");
  if (myBasisSetFactory)
  {
    delete myBasisSetFactory;
  }
}

/** process <determinantset>
 *
 * determinantset
 * - basiset 0..1
 * - sposet 0..*
 * - slaterdeterminant
 *   - determinant 0..*
 * - ci
 */
bool SlaterDetBuilder::put(xmlNodePtr cur)
{
  ReportEngine PRE(ClassName,"put(xmlNodePtr)");
  ///save the current node
  xmlNodePtr curRoot=cur;
  xmlNodePtr BFnode;
  bool success=true, FastMSD=true;
  string cname, tname;
  std::map<string,SPOSetBasePtr> spomap;
  bool multiDet=false;

  if (myBasisSetFactory == 0)
  {//always create one, using singleton and just to access the member functions
    myBasisSetFactory = new BasisSetFactory(targetPtcl,targetPsi, ptclPool);
    myBasisSetFactory->setReportLevel(ReportLevel);
  }

  //check the basis set
  cur = curRoot->children;
  while (cur != NULL)//check the basis set
  {
    getNodeName(cname,cur);
    if (cname == basisset_tag)
    {
      myBasisSetFactory->createBasisSet(cur,curRoot);
    }
    else if ( cname == sposet_tag )
    {
      app_log() << "Creating SPOSet in SlaterDetBuilder::put(xmlNodePtr cur).\n";
      string spo_name;
      OhmmsAttributeSet spoAttrib;
      spoAttrib.add (spo_name, "name");
      spoAttrib.put(cur);
      app_log() << "spo_name = " << spo_name << endl;
      SPOSetBasePtr spo = myBasisSetFactory->createSPOSet(cur);
      //spo->put(cur, spomap);
      if (spomap.find(spo_name) != spomap.end())
      {
        app_error() << "SPOSet name \"" << spo_name << "\" is already in use.\n";
        abort();
      }
      spomap[spo_name] = spo;
      spo->objectName=spo_name;
      assert(spomap.find(spo_name) != spomap.end());
      //	slaterdet_0->add(spo,spo_name);
    }
    else if(cname == backflow_tag)
    {
      app_log() <<"Creating Backflow transformation in SlaterDetBuilder::put(xmlNodePtr cur).\n";
      // to simplify the logic inside DiracDeterminantWithBackflow,
      // I'm requiring that only a single <backflow> block appears
      // in the xml file
      if(BFTrans != 0)
      {
        APP_ABORT("Only a single backflow block is allowed in the xml. Please collect all transformations into a single block. \n");
      }
      UseBackflow=true;
      // creating later due to problems with ParticleSets
      //BFTrans = new BackflowTransformation(targetPtcl,ptclPool);
      BFTrans = NULL;
      BFnode=cur;
      // read xml later, in case some ParticleSets are read from hdf5 file.
      //BFTrans->put(cur);
    }
    cur = cur->next;
  }

  //missing basiset, e.g. einspline
// mmorales: this should not be allowed now, either basisset or sposet must exist
  //if (myBasisSetFactory == 0)
  //{
  //  myBasisSetFactory = new BasisSetFactory(targetPtcl,targetPsi, ptclPool);
  //  myBasisSetFactory->setReportLevel(ReportLevel);
  //  myBasisSetFactory->createBasisSet(curRoot,curRoot);
  //}

  //sposet_builder is defined outside <determinantset/>
  if(spomap.empty())
  {
    bool needbb=true;
    cur = curRoot->children;
    while (cur != NULL)//check the basis set
    {
      getNodeName(cname,cur);
      if (cname == sd_tag)
      {
        xmlNodePtr cur1=cur->children;
        while(cur1!=NULL)
        {
          getNodeName(tname,cur1);
          if(tname == det_tag)
          {
            string aspo,did;
            OhmmsAttributeSet a;
            a.add(did,"id");
            a.add(aspo,"sposet");
            a.put(cur1);
            if(aspo.empty()) aspo=did;
            SPOSetBase* aset=get_sposet(aspo);
            if(aset)
              spomap[aspo]=aset;
            else
            {
              myBasisSetFactory->createBasisSet(cur1,curRoot);
              aset = myBasisSetFactory->createSPOSet(cur1);
              if(aset) spomap[aspo]=aset;
            }
          }
          cur1=cur1->next;
        }
      }
      else if(cname == multisd_tag)
      {
        string spo_alpha;
        string spo_beta;
        OhmmsAttributeSet a;
        a.add (spo_alpha, "spo_up");
        a.add (spo_beta, "spo_dn");
        a.put(cur);
        SPOSetBase* alpha=get_sposet(spo_alpha);
        SPOSetBase* beta=get_sposet(spo_beta);
        if(alpha && beta)
        {
          spomap[spo_alpha]=alpha;
          spomap[spo_beta]=beta;
        }
      }
      cur=cur->next;
    }
  }

  if(spomap.empty())
  {
    APP_ABORT_TRACE(__FILE__,__LINE__," No sposet is found to build slaterdeterminant or multideterminant");
  }

  cur = curRoot->children;
  while (cur != NULL)//check the basis set
  {
    getNodeName(cname,cur);
    if (cname == sd_tag)
    {
      multiDet=false;
      if(slaterdet_0)
      {
        APP_ABORT("slaterdet is already instantiated.");
      }
      if(UseBackflow)
        slaterdet_0 = new SlaterDetWithBackflow(targetPtcl,BFTrans);
      else
        slaterdet_0 = new SlaterDeterminant_t(targetPtcl);

      // Copy any entries in sposetmap into slaterdet_0
      std::map<string,SPOSetBasePtr>::iterator iter;
      for (iter=spomap.begin(); iter!=spomap.end(); iter++)
      {
        slaterdet_0->add(iter->second,iter->first);
      }
      int spin_group = 0;
      xmlNodePtr tcur = cur->children;
      while (tcur != NULL)
      {
        getNodeName(tname,tcur);
        if (tname == det_tag || tname == rn_tag)
        {
          if(putDeterminant(tcur, spin_group))
            spin_group++;
        }
        tcur = tcur->next;
      }
    }
    else if(cname == multisd_tag)
    {
      multiDet=true;
      if(slaterdet_0)
      {
        APP_ABORT("can't combine slaterdet with multideterminant.");
      }
      if(multislaterdet_0 || multislaterdetfast_0)
      {
        APP_ABORT("multideterminant is already instantiated.");
      }
      string spo_alpha;
      string spo_beta;
      string fastAlg("yes");
      OhmmsAttributeSet spoAttrib;
      spoAttrib.add (spo_alpha, "spo_up");
      spoAttrib.add (spo_beta, "spo_dn");
      spoAttrib.add (fastAlg, "Fast");
      spoAttrib.put(cur);
      if(spo_alpha == spo_beta)
      {
        app_error() << "In SlaterDetBuilder: In MultiSlaterDeterminant construction, SPO sets must be different. spo_up: " <<spo_alpha <<"  spo_dn: " <<spo_beta <<"\n";
        abort();
      }
      if (spomap.find(spo_alpha) == spomap.end())
      {
        app_error() << "In SlaterDetBuilder: SPOSet \"" << spo_alpha << "\" is not found. Expected for MultiSlaterDeterminant.\n";
        abort();
      }
      if (spomap.find(spo_beta) == spomap.end())
      {
        app_error() << "In SlaterDetBuilder: SPOSet \"" << spo_beta << "\" is not found. Expected for MultiSlaterDeterminant.\n";
        abort();
      }
      FastMSD = (fastAlg=="yes");
      if(FastMSD)
      {
        if(UseBackflow)
        {
          APP_ABORT("Backflow is not implemented with multi determinants.");
        }
        app_log() <<"Using Bryan's algorithm for MultiSlaterDeterminant expansion. \n";
        MultiDiracDeterminantBase* up_det=0;
        MultiDiracDeterminantBase* dn_det=0;
        app_log() <<"Creating base determinant (up) for MSD expansion. \n";
        up_det = new MultiDiracDeterminantBase((SPOSetBasePtr) spomap.find(spo_alpha)->second,0);
        app_log() <<"Creating base determinant (down) for MSD expansion. \n";
        dn_det = new MultiDiracDeterminantBase((SPOSetBasePtr) spomap.find(spo_beta)->second,1);
        multislaterdetfast_0 = new MultiSlaterDeterminantFast(targetPtcl,up_det,dn_det);
        //          up_det->usingBF = UseBackflow;
        //          dn_det->usingBF = UseBackflow;
        //          multislaterdetfast_0->usingBF = UseBackflow;
        success = createMSDFast(multislaterdetfast_0,cur);
        // debug, erase later
        //          SPOSetProxyForMSD* spo_up;
        //          SPOSetProxyForMSD* spo_dn;
        //          spo_up=new SPOSetProxyForMSD(spomap.find(spo_alpha)->second,targetPtcl.first(0),targetPtcl.last(0));
        //          spo_dn=new SPOSetProxyForMSD(spomap.find(spo_beta)->second,targetPtcl.first(1),targetPtcl.last(1));
        //
        //          multislaterdetfast_0->msd = new MultiSlaterDeterminant(targetPtcl,spo_up,spo_dn);
        //          success = createMSD(multislaterdetfast_0->msd,cur);
      }
      else
      {
        SPOSetProxyForMSD* spo_up;
        SPOSetProxyForMSD* spo_dn;
        spo_up=new SPOSetProxyForMSD(spomap.find(spo_alpha)->second,targetPtcl.first(0),targetPtcl.last(0));
        spo_dn=new SPOSetProxyForMSD(spomap.find(spo_beta)->second,targetPtcl.first(1),targetPtcl.last(1));
        if(UseBackflow)
        {
          app_log() <<"Multi-Slater Determinant expansion with Backflow. \n";
          app_log() <<"Using a list of dirac determinants for MultiSlaterDeterminant expansion. \n";
          multislaterdet_0 = new MultiSlaterDeterminantWithBackflow(targetPtcl,spo_up,spo_dn,BFTrans);
          success = createMSD(multislaterdet_0,cur);
        }
        else
        {
          app_log() <<"Using a list of dirac determinants for MultiSlaterDeterminant expansion. \n";
          multislaterdet_0 = new MultiSlaterDeterminant(targetPtcl,spo_up,spo_dn);
          success = createMSD(multislaterdet_0,cur);
        }
      }
    }
    cur = cur->next;
  }

  if (!multiDet && !slaterdet_0)
  {
    //fatal
    PRE.error("Failed to create a SlaterDeterminant.",true);
    return false;
  }
  if(multiDet && (!multislaterdet_0 && !multislaterdetfast_0 ) )
  {
    //fatal
    PRE.error("Failed to create a MultiSlaterDeterminant.",true);
    return false;
  }
  // change DistanceTables if using backflow
  if(UseBackflow)
  {
    BackflowBuilder* bfbuilder = new BackflowBuilder(targetPtcl,ptclPool,targetPsi);
    bfbuilder->put(BFnode);
    BFTrans = bfbuilder->getBFTrans();
    delete bfbuilder;
    if(multiDet)
    {
      if(FastMSD)
      {
        multislaterdetfast_0->setBF(BFTrans);
        multislaterdetfast_0->resetTargetParticleSet(BFTrans->QP);
//           if(BFTrans->isOptimizable()) multislaterdetfast_0->Optimizable = true;
      }
      else
      {
        multislaterdet_0->setBF(BFTrans);
        multislaterdet_0->resetTargetParticleSet(BFTrans->QP);
//           if(BFTrans->isOptimizable()) multislaterdet_0->Optimizable = true;
      }
    }
    else
    {
      slaterdet_0->setBF(BFTrans);
      slaterdet_0->resetTargetParticleSet(targetPtcl);
      if(BFTrans->isOptimizable())
        slaterdet_0->Optimizable = true;
    }
  }
  //only single slater determinant
  if(multiDet)
    if(FastMSD)
      targetPsi.addOrbital(multislaterdetfast_0,"MultiSlaterDeterminantFast",true);
    else
      targetPsi.addOrbital(multislaterdet_0,"MultiSlaterDeterminant",true);
  else
    targetPsi.addOrbital(slaterdet_0,"SlaterDet",true);
  delete myBasisSetFactory;
  myBasisSetFactory=0;
  return success;
}

/** process determiment element
 *
 * determinant has
 * - id unique name
 * - sposet reference to the pre-defined sposet; when missing, use id
 * - group electron species name, u or d
 * - type variantion of a determinant, type="AFM" uses a specialized determinant builder for Anti-Ferromagnetic system
 * Extra attributes to handled the original released-node case
 */
bool SlaterDetBuilder::putDeterminant(xmlNodePtr cur, int spin_group)
{
  ReportEngine PRE(ClassName,"putDeterminant(xmlNodePtr,int)");

  SpeciesSet& myspecies=targetPtcl.mySpecies;

  string spin_name=myspecies.speciesName[spin_group];
  string sposet;
  string basisName("invalid");
  string detname("0"), refname("0");
  string s_detSize("0");
  string afm("no");

  OhmmsAttributeSet aAttrib;
  aAttrib.add(basisName,basisset_tag);
  aAttrib.add(detname,"id");
  aAttrib.add(sposet,"sposet");
  aAttrib.add(refname,"ref");
  aAttrib.add(afm,"type");
  aAttrib.add(s_detSize,"DetSize");
  string s_cutoff("0.0");
  string s_radius("0.0");
  int s_smallnumber(-999999);
  int rntype(0);
  aAttrib.add(s_cutoff,"Cutoff");
  aAttrib.add(s_radius,"Radius");
  aAttrib.add(s_smallnumber,"smallnumber");
  aAttrib.add(s_smallnumber,"eps");
  aAttrib.add(rntype,"primary");
  aAttrib.add(spin_name,"group");
  aAttrib.put(cur);

  { //check determinant@group
    int spin_group_in=spin_group;
    if(isdigit(spin_name[0]))
      spin_group_in=atoi(spin_name.c_str());
    else
      spin_group_in=myspecies.findSpecies(spin_name);
    if(spin_group_in<myspecies.size() && spin_group_in != spin_group)
    {
      spin_group=spin_group_in;
      app_log() << "  Overwrite group = " << spin_group << endl;
    }
  }

  //old input does not have sposet
  if(sposet.empty()) sposet=detname;

  app_log() << "  Creating a determinant " << detname << " group=" << spin_group << " sposet=" << sposet << endl;

  map<string,SPOSetBasePtr>& spo_ref(slaterdet_0->mySPOSet);
  map<string,SPOSetBasePtr>::iterator lit(spo_ref.find(sposet));
  SPOSetBasePtr psi=0;
  if (lit == spo_ref.end())
  {
    psi=get_sposet(sposet); //check if the named sposet exists
    if(psi==0)
    {
      //SPOSet[detname]=psi;
      app_log() << "  Create a new SPO set " << sposet << endl;
#if defined(ENABLE_SMARTPOINTER)
      psi.reset(myBasisSetFactory->createSPOSet(cur));
#else
      psi = myBasisSetFactory->createSPOSet(cur);
#endif
    }
    //psi->put(cur);
    psi->checkObject();
    slaterdet_0->add(psi,detname);
  }
  else
  {
    app_log() << "  Reusing a SPO set " << sposet << endl;
    psi = (*lit).second;
  }

  int firstIndex=targetPtcl.first(spin_group);
  int lastIndex=targetPtcl.last(spin_group);
  if(firstIndex==lastIndex)
    return true;
//    app_log() << "  Creating DiracDeterminant " << detname << " group=" << spin_group << " First Index = " << firstIndex << endl;
//    app_log() <<"   My det method is "<<detMethod<<endl;
//#if defined(BRYAN_MULTIDET_TRIAL)
//    if (detMethod=="Iterative")
//    {
//      //   string s_cutoff("0.0");
//      //   aAttrib.add(s_cutoff,"Cutoff");
//      app_log()<<"My cutoff is "<<s_cutoff<<endl;
//
//      double cutoff=std::atof(s_cutoff.c_str());
//      DiracDeterminantIterative *adet= new DiracDeterminantIterative(psi,firstIndex);
//      adet->set_iterative(firstIndex,psi->getOrbitalSetSize(),cutoff);
//      slaterdet_0->add(adet,spin_group);
//    }
//    else if (detMethod=="Truncation")
//    {
//      //   string s_cutoff("0.0");
//      //   aAttrib.add(s_cutoff,"Cutoff");
//      DiracDeterminantTruncation *adet= new DiracDeterminantTruncation(psi,firstIndex);
//      double cutoff=std::atof(s_cutoff.c_str());
//      double radius=std::atof(s_radius.c_str());
//      //   adet->set(firstIndex,psi->getOrbitalSetSize());
//      adet->set_truncation(firstIndex,psi->getOrbitalSetSize(),cutoff,radius);
//      slaterdet_0->add(adet,spin_group);
//    }
//    else if (detMethod=="Multi")
//    {
//      app_log()<<"BUILDING DIRAC DETERM "<<firstIndex<<endl;
//      MultiDiracDeterminantBase *adet = new MultiDiracDeterminantBase(psi,firstIndex);
//      int detSize=std::atof(s_detSize.c_str());
//      adet-> set_Multi(firstIndex,detSize,psi->getOrbitalSetSize());
//      slaterdet_0->add(adet,spin_group);
//    }
//    else
//      slaterdet_0->add(new Det_t(psi,firstIndex),spin_group);
//    }
//#else
  string dname;
  getNodeName(dname,cur);
  DiracDeterminantBase* adet=0;
#if !defined(QMC_COMPLEX)
  if (rn_tag == dname)
  {
    double bosonicEpsilon=s_smallnumber;
    app_log()<<"  BUILDING Released Node Determinant logepsilon="<<bosonicEpsilon<<endl;
    if (rntype==0)
      adet = new RNDiracDeterminantBase(psi,firstIndex);
    else
      adet = new RNDiracDeterminantBaseAlternate(psi,firstIndex);
    adet->setLogEpsilon(bosonicEpsilon);
  }
  else
#endif
  {
#ifdef QMC_CUDA
    adet = new DiracDeterminantCUDA(psi,firstIndex);
#else
    if(UseBackflow)
      adet = new DiracDeterminantWithBackflow(targetPtcl,psi,BFTrans,firstIndex);
    else if (afm=="AFM")
    {
      app_log()<<"Using the AFM determinant"<<endl;
      adet = new DiracDeterminantAFM(targetPtcl, psi, firstIndex);
    }
    else if (psi->Optimizable)
      adet = new DiracDeterminantOpt(targetPtcl, psi, firstIndex);
    else
      adet = new DiracDeterminantBase(psi,firstIndex);
#endif
  }
  adet->set(firstIndex,lastIndex-firstIndex);
  slaterdet_0->add(adet,spin_group);
  if (psi->Optimizable)
    slaterdet_0->Optimizable = true;

  app_log() << endl;
  app_log().flush();
  return true;
}

bool SlaterDetBuilder::createMSDFast(MultiSlaterDeterminantFast* multiSD, xmlNodePtr cur)
{
  bool success=true;
  vector<ci_configuration> uniqueConfg_up, uniqueConfg_dn;
  vector<std::string> CItags;
  bool optimizeCI;
  int nels_up = multiSD->nels_up;
  int nels_dn = multiSD->nels_dn;
  success = readDetList(cur,uniqueConfg_up,uniqueConfg_dn,multiSD->C2node_up, multiSD->C2node_dn,CItags,multiSD->C,optimizeCI,nels_up,nels_dn,multiSD->CSFcoeff,multiSD->DetsPerCSF,multiSD->CSFexpansion,multiSD->usingCSF);
  if(!success)
    return false;
// you should choose the det with highest weight for reference
  multiSD->Dets[0]->ReferenceDeterminant = 0; // for now
  multiSD->Dets[0]->NumDets=uniqueConfg_up.size();
  vector<ci_configuration2>& list_up = multiSD->Dets[0]->confgList;
  list_up.resize(uniqueConfg_up.size());
  for(int i=0; i<list_up.size(); i++)
  {
    list_up[i].occup.resize(nels_up);
    int cnt=0;
    for(int k=0; k<uniqueConfg_up[i].occup.size(); k++)
      if(uniqueConfg_up[i].occup[k])
        list_up[i].occup[cnt++]=k;
    if(cnt!=nels_up)
    {
      APP_ABORT("Error in SlaterDetBuilder::createMSDFast, problems with ci configuration list. \n");
    }
  }
  multiSD->Dets[0]->set(multiSD->FirstIndex_up,nels_up,multiSD->Dets[0]->Phi->getOrbitalSetSize());
  multiSD->Dets[1]->ReferenceDeterminant = 0; // for now
  multiSD->Dets[1]->NumDets=uniqueConfg_dn.size();
  vector<ci_configuration2>& list_dn = multiSD->Dets[1]->confgList;
  list_dn.resize(uniqueConfg_dn.size());
  for(int i=0; i<list_dn.size(); i++)
  {
    list_dn[i].occup.resize(nels_dn);
    int cnt=0;
    for(int k=0; k<uniqueConfg_dn[i].occup.size(); k++)
      if(uniqueConfg_dn[i].occup[k])
        list_dn[i].occup[cnt++]=k;
    if(cnt!=nels_dn)
    {
      APP_ABORT("Error in SlaterDetBuilder::createMSDFast, problems with ci configuration list. \n");
    }
  }
  multiSD->Dets[1]->set(multiSD->FirstIndex_dn,nels_dn,multiSD->Dets[1]->Phi->getOrbitalSetSize());
  if (multiSD->CSFcoeff.size()==1)
    optimizeCI=false;
  if(optimizeCI)
  {
    app_log() <<"CI coefficients are optimizable. \n";
    string resetCI("no");
    OhmmsAttributeSet spoAttrib;
    spoAttrib.add (resetCI, "reset_coeff");
    spoAttrib.put(cur);
    if (resetCI=="yes")
    {
      if(multiSD->usingCSF)
        for(int i=1; i<multiSD->CSFcoeff.size(); i++)
          multiSD->CSFcoeff[i]=0;
      else
        for(int i=1; i<multiSD->C.size(); i++)
          multiSD->C[i]=0;
      app_log() <<"CI coefficients are reset. \n";
    }
    multiSD->Optimizable=true;
    if(multiSD->usingCSF)
    {
//          multiSD->myVars.insert(CItags[0],multiSD->CSFcoeff[0],false,optimize::LINEAR_P);
      for(int i=1; i<multiSD->CSFcoeff.size(); i++)
      {
        //std::stringstream sstr;
        //sstr << "CIcoeff" << "_" << i;
        multiSD->myVars.insert(CItags[i],multiSD->CSFcoeff[i],true,optimize::LINEAR_P);
      }
    }
    else
    {
//          multiSD->myVars.insert(CItags[0],multiSD->C[0],false,optimize::LINEAR_P);
      for(int i=1; i<multiSD->C.size(); i++)
      {
        //std::stringstream sstr;
        //sstr << "CIcoeff" << "_" << i;
        multiSD->myVars.insert(CItags[i],multiSD->C[i],true,optimize::LINEAR_P);
      }
    }
  }
  else
  {
    app_log() <<"CI coefficients are not optimizable. \n";
    multiSD->Optimizable=false;
  }
  return success;
}
/*
  bool SlaterDetBuilder::createMSD(MultiSlaterDeterminant* multiSD, xmlNodePtr cur)
  {
     bool success=true;

     vector<ci_configuration> uniqueConfg_up, uniqueConfg_dn;
     vector<std::string> CItags;
     bool optimizeCI;

     success = readDetList(cur,uniqueConfg_up,uniqueConfg_dn,multiSD->C2node_up, multiSD->C2node_dn,CItags,multiSD->C,optimizeCI,multiSD->nels_up,multiSD->nels_dn);
     if(!success) return false;

     multiSD->resize(uniqueConfg_up.size(),uniqueConfg_dn.size());
     SPOSetProxyForMSD* spo = multiSD->spo_up;
     spo->occup.resize(uniqueConfg_up.size(),multiSD->nels_up);
     for(int i=0; i<uniqueConfg_up.size(); i++)
     {
       int nq=0;
       ci_configuration& ci = uniqueConfg_up[i];
       for(int k=0; k<ci.occup.size(); k++) {
         if(ci.occup[k]) {
           spo->occup(i,nq++) = k;
         }
       }
       DiracDeterminantBase* adet = new DiracDeterminantBase((SPOSetBasePtr) spo,0);
       adet->set(multiSD->FirstIndex_up,multiSD->nels_up);
       multiSD->dets_up.push_back(adet);
     }
     spo = multiSD->spo_dn;
     spo->occup.resize(uniqueConfg_dn.size(),multiSD->nels_dn);
     for(int i=0; i<uniqueConfg_dn.size(); i++)
     {
       int nq=0;
       ci_configuration& ci = uniqueConfg_dn[i];
       for(int k=0; k<ci.occup.size(); k++) {
         if(ci.occup[k]) {
           spo->occup(i,nq++) = k;
         }
       }
       DiracDeterminantBase* adet = new DiracDeterminantBase((SPOSetBasePtr) spo,0);
       adet->set(multiSD->FirstIndex_dn,multiSD->nels_dn);
       multiSD->dets_dn.push_back(adet);
     }

     if(optimizeCI) {
       app_log() <<"CI coefficients are optimizable. ";
       multiSD->Optimizable=true;
       multiSD->myVars.insert(CItags[0],multiSD->C[0],false,optimize::LINEAR_P);
       for(int i=1; i<multiSD->C.size(); i++) {
         //std::stringstream sstr;
         //sstr << "CIcoeff" << "_" << i;
         multiSD->myVars.insert(CItags[i],multiSD->C[i],true,optimize::LINEAR_P);
       }
     }
     return success;
  }
*/
bool SlaterDetBuilder::createMSD(MultiSlaterDeterminant* multiSD, xmlNodePtr cur)
{
  bool success=true;
  vector<ci_configuration> uniqueConfg_up, uniqueConfg_dn;
  vector<std::string> CItags;
  bool optimizeCI;
  int nels_up = multiSD->nels_up;
  int nels_dn = multiSD->nels_dn;
  success = readDetList(cur,uniqueConfg_up,uniqueConfg_dn,multiSD->C2node_up, multiSD->C2node_dn,CItags,multiSD->C,optimizeCI,nels_up,nels_dn,multiSD->CSFcoeff,multiSD->DetsPerCSF,multiSD->CSFexpansion,multiSD->usingCSF);
  if(!success)
    return false;
  multiSD->resize(uniqueConfg_up.size(),uniqueConfg_dn.size());
  SPOSetProxyForMSD* spo = multiSD->spo_up;
  spo->occup.resize(uniqueConfg_up.size(),multiSD->nels_up);
  for(int i=0; i<uniqueConfg_up.size(); i++)
  {
    int nq=0;
    ci_configuration& ci = uniqueConfg_up[i];
    for(int k=0; k<ci.occup.size(); k++)
    {
      if(ci.occup[k])
      {
        spo->occup(i,nq++) = k;
      }
    }
    DiracDeterminantBase* adet;
    if(UseBackflow)
    {
      adet = new DiracDeterminantWithBackflow(targetPtcl,(SPOSetBasePtr) spo,0,0);
    }
    else
    {
      adet = new DiracDeterminantBase((SPOSetBasePtr) spo,0);
    }
    adet->set(multiSD->FirstIndex_up,multiSD->nels_up);
    multiSD->dets_up.push_back(adet);
  }
  spo = multiSD->spo_dn;
  spo->occup.resize(uniqueConfg_dn.size(),multiSD->nels_dn);
  for(int i=0; i<uniqueConfg_dn.size(); i++)
  {
    int nq=0;
    ci_configuration& ci = uniqueConfg_dn[i];
    for(int k=0; k<ci.occup.size(); k++)
    {
      if(ci.occup[k])
      {
        spo->occup(i,nq++) = k;
      }
    }
    DiracDeterminantBase* adet;
    if(UseBackflow)
    {
      adet = new DiracDeterminantWithBackflow(targetPtcl,(SPOSetBasePtr) spo,0,0);
    }
    else
    {
      adet = new DiracDeterminantBase((SPOSetBasePtr) spo,0);
    }
    adet->set(multiSD->FirstIndex_dn,multiSD->nels_dn);
    multiSD->dets_dn.push_back(adet);
  }
  if (multiSD->CSFcoeff.size()==1 || multiSD->C.size()==1)
    optimizeCI=false;
  if(optimizeCI)
  {
    app_log() <<"CI coefficients are optimizable. \n";
    string resetCI("no");
    OhmmsAttributeSet spoAttrib;
    spoAttrib.add (resetCI, "reset_coeff");
    spoAttrib.put(cur);
    if (resetCI=="yes")
    {
      if(multiSD->usingCSF)
        for(int i=1; i<multiSD->CSFcoeff.size(); i++)
          multiSD->CSFcoeff[i]=0;
      else
        for(int i=1; i<multiSD->C.size(); i++)
          multiSD->C[i]=0;
      app_log() <<"CI coefficients are reset. \n";
    }
    multiSD->Optimizable=true;
    if(multiSD->usingCSF)
    {
//          multiSD->myVars.insert(CItags[0],multiSD->CSFcoeff[0],false,optimize::LINEAR_P);
      for(int i=1; i<multiSD->CSFcoeff.size(); i++)
      {
        //std::stringstream sstr;
        //sstr << "CIcoeff" << "_" << i;
        multiSD->myVars.insert(CItags[i],multiSD->CSFcoeff[i],true,optimize::LINEAR_P);
      }
    }
    else
    {
//          multiSD->myVars.insert(CItags[0],multiSD->C[0],false,optimize::LINEAR_P);
      for(int i=1; i<multiSD->C.size(); i++)
      {
        //std::stringstream sstr;
        //sstr << "CIcoeff" << "_" << i;
        multiSD->myVars.insert(CItags[i],multiSD->C[i],true,optimize::LINEAR_P);
      }
    }
  }
  else
  {
    app_log() <<"CI coefficients are not optimizable. \n";
    multiSD->Optimizable=false;
  }
  return success;
}

bool SlaterDetBuilder::readDetList(xmlNodePtr cur, vector<ci_configuration>& uniqueConfg_up, vector<ci_configuration>& uniqueConfg_dn, vector<int>& C2node_up, vector<int>& C2node_dn, vector<std::string>& CItags, vector<RealType>& coeff, bool& optimizeCI, int nels_up, int nels_dn,  vector<RealType>& CSFcoeff, vector<int>& DetsPerCSF, vector<RealType>& CSFexpansion, bool& usingCSF)
{
  bool success=true;
  uniqueConfg_up.clear();
  uniqueConfg_dn.clear();
  C2node_up.clear();
  C2node_dn.clear();
  CItags.clear();
  coeff.clear();
  CSFcoeff.clear();
  DetsPerCSF.clear();
  CSFexpansion.clear();
  vector<ci_configuration> confgList_up;
  vector<ci_configuration> confgList_dn;
  string optCI="no";
  RealType cutoff=0.0;
  RealType zero_cutoff=0.0;
  OhmmsAttributeSet ciAttrib;
  ciAttrib.add (optCI,"optimize");
  ciAttrib.add (optCI,"Optimize");
  ciAttrib.put(cur);
  optimizeCI = (optCI=="yes");
  xmlNodePtr curRoot=cur,DetListNode;
  string cname,cname0;
  cur = curRoot->children;
  while (cur != NULL)//check the basis set
  {
    getNodeName(cname,cur);
    if(cname == "detlist")
    {
      DetListNode=cur;
      app_log() <<"Found determinant list. \n";
    }
    cur = cur->next;
  }
  int NCA,NCB,NEA,NEB,nstates,ndets=0,count=0,cnt0=0;
  string Dettype="DETS";
  string CSFChoice="qchem_coeff";
  OhmmsAttributeSet spoAttrib;
  spoAttrib.add (NCA, "nca");
  spoAttrib.add (NCB, "ncb");
  spoAttrib.add (NEA, "nea");
  spoAttrib.add (NEB, "neb");
  spoAttrib.add (ndets, "size");
  spoAttrib.add (Dettype, "type");
  spoAttrib.add (nstates, "nstates");
  spoAttrib.add (cutoff,"cutoff");
  spoAttrib.add (zero_cutoff,"zero_cutoff");
  spoAttrib.add (zero_cutoff,"zerocutoff");
  spoAttrib.add (CSFChoice,"sortby");
  spoAttrib.put(DetListNode);
  if(ndets==0)
  {
    APP_ABORT("size==0 in detlist is not allowed. Use slaterdeterminant in this case.\n");
  }
  if(Dettype == "DETS" || Dettype == "Determinants")
    usingCSF=false;
  else
    if(Dettype == "CSF")
      usingCSF=true;
    else
    {
      APP_ABORT("Only allowed type in detlist is DETS or CSF.\n");
    }
  if(zero_cutoff>0)
    app_log()<<"  Initializing CI coeffs less than "<<zero_cutoff<<" to zero."<<endl;
// cheating until I fix the converter
  NCA = nels_up-NEA;
  NCB = nels_dn-NEB;
// mmorales: a little messy for now, clean up later
  cur = DetListNode->children;
  ci_configuration dummyC_alpha;
  ci_configuration dummyC_beta;
  dummyC_alpha.occup.resize(NCA+nstates,false);
  for(int i=0; i<NCA+NEA; i++)
    dummyC_alpha.occup[i]=true;
  dummyC_beta.occup.resize(NCB+nstates,false);
  for(int i=0; i<NCB+NEB; i++)
    dummyC_beta.occup[i]=true;
  RealType sumsq_qc=0.0;
  //app_log() <<"alpha reference: \n" <<dummyC_alpha;
  //app_log() <<"beta reference: \n" <<dummyC_beta;
  int ntot=0;
  if(usingCSF)
  {
    app_log() <<"Reading CSFs." <<endl;
    while (cur != NULL)//check the basis set
    {
      getNodeName(cname,cur);
      if(cname == "csf")
      {
        RealType exctLvl,ci=0.0,qc_ci=0.0;
        OhmmsAttributeSet confAttrib;
        string tag,OccString;
        confAttrib.add(ci,"coeff");
        confAttrib.add(qc_ci,"qchem_coeff");
        confAttrib.add(tag,"id");
        confAttrib.add(OccString,"occ");
        confAttrib.add(exctLvl,"exctLvl");
        confAttrib.put(cur);
        if(qc_ci == 0.0)
          qc_ci = ci;
        //Can discriminate based on any of 3 criterion
        if(((abs(qc_ci) < cutoff)&&(CSFChoice=="qchem_coeff"))||((CSFChoice=="exctLvl")&&(exctLvl>cutoff))||((CSFChoice=="coeff")&&(abs(ci) < cutoff)))
        {
          cur = cur->next;
          cnt0++;
          continue;
        }
        cnt0++;
        if(abs(qc_ci)<zero_cutoff)
          ci=0.0;
        CSFcoeff.push_back(ci);
        sumsq_qc += qc_ci*qc_ci;
        DetsPerCSF.push_back(0);
        CItags.push_back(tag);
        count++;
        xmlNodePtr csf=cur->children;
        while(csf != NULL)
        {
          getNodeName(cname0,csf);
          if(cname0 == "det")
          {
            string alpha,beta,tag0;
            RealType coef=0.0;
            OhmmsAttributeSet detAttrib;
            detAttrib.add(tag0,"id");
            detAttrib.add(coef,"coeff");
            detAttrib.add(beta,"beta");
            detAttrib.add(alpha,"alpha");
            detAttrib.put(csf);
            int nq=0,na,nr;
            if(alpha.size() < nstates)
            {
              cerr<<"alpha: " <<alpha <<endl;
              APP_ABORT("Found incorrect alpha determinant label. size < nca+nstates");
            }
            for(int i=0; i<nstates; i++)
            {
              if(alpha[i] != '0' && alpha[i] != '1')
              {
                cerr<<alpha <<endl;
                APP_ABORT("Found incorrect determinant label.");
              }
              if(alpha[i] == '1')
                nq++;
            }
            if(nq != NEA)
            {
              cerr<<"alpha: " <<alpha <<endl;
              APP_ABORT("Found incorrect alpha determinant label. noccup != nca+nea");
            }
            nq=0;
            if(beta.size() < nstates)
            {
              cerr<<"beta: " <<beta <<endl;
              APP_ABORT("Found incorrect beta determinant label. size < ncb+nstates");
            }
            for(int i=0; i<nstates; i++)
            {
              if(beta[i] != '0' && beta[i] != '1')
              {
                cerr<<beta <<endl;
                APP_ABORT("Found incorrect determinant label.");
              }
              if(beta[i] == '1')
                nq++;
            }
            if(nq != NEB)
            {
              cerr<<"beta: " <<beta <<endl;
              APP_ABORT("Found incorrect beta determinant label. noccup != ncb+neb");
            }
//app_log() <<" <ci id=\"coeff_" <<ntot++ <<"\" coeff=\"" <<ci*coef <<"\" alpha=\"" <<alpha <<"\" beta=\"" <<beta <<"\" />" <<endl;
            DetsPerCSF.back()++;
            CSFexpansion.push_back(coef);
            coeff.push_back(coef*ci);
            confgList_up.push_back(dummyC_alpha);
            for(int i=0; i<NCA; i++)
              confgList_up.back().occup[i]=true;
            for(int i=NCA; i<NCA+nstates; i++)
              confgList_up.back().occup[i]= (alpha[i-NCA]=='1');
            confgList_dn.push_back(dummyC_beta);
            for(int i=0; i<NCB; i++)
              confgList_dn.back().occup[i]=true;
            for(int i=NCB; i<NCB+nstates; i++)
              confgList_dn.back().occup[i]=(beta[i-NCB]=='1');
          } // if(name=="det")
          csf = csf->next;
        } // csf loop
        if(DetsPerCSF.back() == 0)
        {
          APP_ABORT("Found empty CSF (no det blocks).");
        }
      } // if (name == "csf")
      cur = cur->next;
    }
  }
  else
  {
    app_log() <<"Reading CI expansion." <<endl;
    while (cur != NULL)//check the basis set
    {
      getNodeName(cname,cur);
      if(cname == "configuration" || cname == "ci")
      {
        RealType ci=0.0, qc_ci=0.0;
        string alpha,beta,tag;
        OhmmsAttributeSet confAttrib;
        confAttrib.add(ci,"coeff");
        confAttrib.add(qc_ci,"qchem_coeff");
        confAttrib.add(alpha,"alpha");
        confAttrib.add(beta,"beta");
        confAttrib.add(tag,"id");
        confAttrib.put(cur);
        if(qc_ci == 0.0)
          qc_ci = ci;
        if(abs(qc_ci) < cutoff)
        {
          cur = cur->next;
          cnt0++;
          continue;
        }
        cnt0++;
        if(abs(qc_ci) < zero_cutoff)
          ci=0.0;
        int nq=0,na,nr;
        if(alpha.size() < nstates)
        {
          cerr<<"alpha: " <<alpha <<endl;
          APP_ABORT("Found incorrect alpha determinant label. size < nca+nstates");
        }
        for(int i=0; i<nstates; i++)
        {
          if(alpha[i] != '0' && alpha[i] != '1')
          {
            cerr<<alpha <<endl;
            APP_ABORT("Found incorrect determinant label.");
          }
          if(alpha[i] == '1')
            nq++;
        }
        if(nq != NEA)
        {
          cerr<<"alpha: " <<alpha <<endl;
          APP_ABORT("Found incorrect alpha determinant label. noccup != nca+nea");
        }
        nq=0;
        if(beta.size() < nstates)
        {
          cerr<<"beta: " <<beta <<endl;
          APP_ABORT("Found incorrect beta determinant label. size < ncb+nstates");
        }
        for(int i=0; i<nstates; i++)
        {
          if(beta[i] != '0' && beta[i] != '1')
          {
            cerr<<beta <<endl;
            APP_ABORT("Found incorrect determinant label.");
          }
          if(beta[i] == '1')
            nq++;
        }
        if(nq != NEB)
        {
          cerr<<"beta: " <<beta <<endl;
          APP_ABORT("Found incorrect beta determinant label. noccup != ncb+neb");
        }
        count++;
        coeff.push_back(ci);
        sumsq_qc += qc_ci*qc_ci;
        CItags.push_back(tag);
        confgList_up.push_back(dummyC_alpha);
        for(int i=0; i<NCA; i++)
          confgList_up.back().occup[i]=true;
        for(int i=NCA; i<NCA+nstates; i++)
          confgList_up.back().occup[i]= (alpha[i-NCA]=='1');
        confgList_dn.push_back(dummyC_beta);
        for(int i=0; i<NCB; i++)
          confgList_dn.back().occup[i]=true;
        for(int i=NCB; i<NCB+nstates; i++)
          confgList_dn.back().occup[i]=(beta[i-NCB]=='1');
      }
      cur = cur->next;
    }
  } //usingCSF
  //if(count != ndets) {
  if(cnt0 != ndets)
  {
    cerr<<"count, ndets: " <<cnt0 <<"  " <<ndets <<endl;
    APP_ABORT("Problems reading determinant ci_configurations. Found a number of determinants inconsistent with xml file size parameter.\n");
  }
  //if(!usingCSF)
  //  if(confgList_up.size() != ndets || confgList_dn.size() != ndets || coeff.size() != ndets) {
  //    APP_ABORT("Problems reading determinant ci_configurations.");
  //  }
  C2node_up.resize(coeff.size());
  C2node_dn.resize(coeff.size());
  app_log() <<"Found " <<coeff.size() <<" terms in the MSD expansion.\n";
  RealType sumsq=0.0;
  for(int i=0; i<coeff.size(); i++)
    sumsq += coeff[i]*coeff[i];
  app_log() <<"Norm of ci vector (sum of ci^2): " <<sumsq <<endl;
  app_log() <<"Norm of qchem ci vector (sum of qchem_ci^2): " <<sumsq_qc <<endl;
  for(int i=0; i<confgList_up.size(); i++)
  {
    bool found=false;
    int k=-1;
    for(int j=0; j<uniqueConfg_up.size(); j++)
    {
      if(confgList_up[i] == uniqueConfg_up[j])
      {
        found=true;
        k=j;
        break;
      }
    }
    if(found)
    {
      C2node_up[i]=k;
    }
    else
    {
      uniqueConfg_up.push_back(confgList_up[i]);
      C2node_up[i]=uniqueConfg_up.size()-1;
    }
  }
  for(int i=0; i<confgList_dn.size(); i++)
  {
    bool found=false;
    int k=-1;
    for(int j=0; j<uniqueConfg_dn.size(); j++)
    {
      if(confgList_dn[i] == uniqueConfg_dn[j])
      {
        found=true;
        k=j;
        break;
      }
    }
    if(found)
    {
      C2node_dn[i]=k;
    }
    else
    {
      uniqueConfg_dn.push_back(confgList_dn[i]);
      C2node_dn[i]=uniqueConfg_dn.size()-1;
    }
  }
  app_log() <<"Found " <<uniqueConfg_up.size() <<" unique up determinants.\n";
  app_log() <<"Found " <<uniqueConfg_dn.size() <<" unique down determinants.\n";
  return success;
}

// void SlaterDetBuilder::buildMultiSlaterDetermiant()
// {
//   MultiSlaterDeterminant *multidet= new MultiSlaterDeterminant;
//   for (int i=0; i<SlaterDetSet.size(); i++)
//     {
//       multidet->add(SlaterDetSet[i],sdet_coeff[i]);
//     }
//   // multidet->setOptimizable(true);
//   //add a MultiDeterminant to the trial wavefuntion
//   targetPsi.addOrbital(multidet,"MultiSlateDet");
// }
}
/***************************************************************************
 * $RCSfile$   $Author: jnkim $
 * $Revision: 6158 $   $Date: 2014-01-13 13:39:43 -0500 (Mon, 13 Jan 2014) $
 * $Id: SlaterDetBuilder.cpp 6158 2014-01-13 18:39:43Z jnkim $
 ***************************************************************************/


text:
package actions

import (
	"github.com/taitan-org/inflog/filebeat/libbeat/common"
	"github.com/taitan-org/inflog/filebeat/libbeat/processors"
)

type dropEvent struct{}

func init() {
	processors.RegisterPlugin("drop_event",
		configChecked(newDropEvent, allowedFields("when")))
}

func newDropEvent(c common.Config) (processors.Processor, error) {
	return dropEvent{}, nil
}

func (f dropEvent) Run(event common.MapStr) (common.MapStr, error) {
	// return event=nil to delete the entire event
	return nil, nil
}

func (f dropEvent) String() string { return "drop_event" }

redpajama_set_name: RedPajamaGithub


text:
import core from 'core-js';

var originStorage = new Map(),
    unknownOrigin = Object.freeze({moduleId:undefined,moduleMember:undefined});

/**
* A metadata annotation that describes the origin module of the function to which it's attached.
*
* @class Origin
* @constructor
* @param {string} moduleId The origin module id.
* @param {string} moduleMember The name of the export in the origin module.
*/
export class Origin {
  constructor(moduleId:string, moduleMember:string){
    this.moduleId = moduleId;
    this.moduleMember = moduleMember;
  }

  /**
  * Get the Origin annotation for the specified function.
  *
  * @method get
  * @static
  * @param {Function} fn The function to inspect for Origin metadata.
  * @return {Origin} Returns the Origin metadata.
  */
  static get(fn:Function){
    var origin = originStorage.get(fn);

    if(origin === undefined){
      System.forEachModule((key, value) => {
        for(var name in value){
          var exp = value[name];
          if(exp === fn){
            originStorage.set(fn, origin = new Origin(key, name));
            return true;
          }
        }

        if(value === fn){
          originStorage.set(fn, origin = new Origin(key, 'default'));
          return true;
        }
      });
    }

    return origin || unknownOrigin;
  }

  /**
  * Set the Origin annotation for the specified function.
  *
  * @method set
  * @static
  * @param {Function} fn The function to set the Origin metadata on.
  * @param {origin} fn The Origin metadata to store on the function.
  * @return {Origin} Returns the Origin metadata.
  */
  static set(fn:Function, origin:Origin){
    originStorage.set(fn, origin);
  }
}


text:
@implementation UIControl (TFEasyCoder)

+( UIControl *)easyCoder:(UIControlEasyCoderBlock)block{
    return [NSObject tf_execute:[self class] back:^(id ins) {
        if (block) {
            block(( UIControl *)ins);
        }
    }];
}

-( UIControl *)easyCoder:(UIControlEasyCoderBlock)block{
    if (block) {
        __weak typeof(self) weakSelf = self;
        block(weakSelf);
    }
    return self;
}

-(UIControl  *(^)(BOOL  enabled))set_enabled{
    __weak typeof(self) weakSelf = self;
    return ^(BOOL  enabled){
        weakSelf.enabled = enabled;
        return weakSelf;
    };
}

-(UIControl  *(^)(BOOL  selected))set_selected{
    __weak typeof(self) weakSelf = self;
    return ^(BOOL  selected){
        weakSelf.selected = selected;
        return weakSelf;
    };
}

-(UIControl  *(^)(BOOL  highlighted))set_highlighted{
    __weak typeof(self) weakSelf = self;
    return ^(BOOL  highlighted){
        weakSelf.highlighted = highlighted;
        return weakSelf;
    };
}

-(UIControl  *(^)(long long  contentVerticalAlignment))set_contentVerticalAlignment{
    __weak typeof(self) weakSelf = self;
    return ^(long long  contentVerticalAlignment){
        weakSelf.contentVerticalAlignment = contentVerticalAlignment;
        return weakSelf;
    };
}

-(UIControl  *(^)(long long  contentHorizontalAlignment))set_contentHorizontalAlignment{
    __weak typeof(self) weakSelf = self;
    return ^(long long  contentHorizontalAlignment){
        weakSelf.contentHorizontalAlignment = contentHorizontalAlignment;
        return weakSelf;
    };
}

//superclass pros UIView
-(UIControl  *(^)(UIView *  maskView))set_maskView{
    __weak typeof(self) weakSelf = self;
    return ^(UIView *  maskView){
        weakSelf.maskView = maskView;
        return weakSelf;
    };
}

-(UIControl  *(^)(BOOL  userInteractionEnabled))set_userInteractionEnabled{
    __weak typeof(self) weakSelf = self;
    return ^(BOOL  userInteractionEnabled){
        weakSelf.userInteractionEnabled = userInteractionEnabled;
        return weakSelf;
    };
}

-(UIControl  *(^)(long long  tag))set_tag{
    __weak typeof(self) weakSelf = self;
    return ^(long long  tag){
        weakSelf.tag = tag;
        return weakSelf;
    };
}

-(UIControl  *(^)(long long  semanticContentAttribute))set_semanticContentAttribute{
    __weak typeof(self) weakSelf = self;
    return ^(long long  semanticContentAttribute){
        weakSelf.semanticContentAttribute = semanticContentAttribute;
        return weakSelf;
    };
}

-(UIControl  *(^)(CGPoint  center))set_center{
    __weak typeof(self) weakSelf = self;
    return ^(CGPoint  center){
        weakSelf.center = center;
        return weakSelf;
    };
}

-(UIControl  *(^)(CGRect  frame))set_frame{
    __weak typeof(self) weakSelf = self;
    return ^(CGRect  frame){
        weakSelf.frame = frame;
        return weakSelf;
    };
}

-(UIControl  *(^)(UIColor *  backgroundColor))set_backgroundColor{
    __weak typeof(self) weakSelf = self;
    return ^(UIColor *  backgroundColor){
        weakSelf.backgroundColor = backgroundColor;
        return weakSelf;
    };
}

//superclass pros UIResponder
-(UIControl  *(^)(NSUserActivity *  userActivity))set_userActivity{
    __weak typeof(self) weakSelf = self;
    return ^(NSUserActivity *  userActivity){
        weakSelf.userActivity = userActivity;
        return weakSelf;
    };
}

//superclass pros NSObject
-(UIControl  *(^)(NSArray *  accessibilityElements))set_accessibilityElements{
    __weak typeof(self) weakSelf = self;
    return ^(NSArray *  accessibilityElements){
        weakSelf.accessibilityElements = accessibilityElements;
        return weakSelf;
    };
}

-(UIControl  *(^)(NSArray *  accessibilityCustomActions))set_accessibilityCustomActions{
    __weak typeof(self) weakSelf = self;
    return ^(NSArray *  accessibilityCustomActions){
        weakSelf.accessibilityCustomActions = accessibilityCustomActions;
        return weakSelf;
    };
}

-(UIControl  *(^)(BOOL  isAccessibilityElement))set_isAccessibilityElement{
    __weak typeof(self) weakSelf = self;
    return ^(BOOL  isAccessibilityElement){
        weakSelf.isAccessibilityElement = isAccessibilityElement;
        return weakSelf;
    };
}

-(UIControl  *(^)(NSString *  accessibilityLabel))set_accessibilityLabel{
    __weak typeof(self) weakSelf = self;
    return ^(NSString *  accessibilityLabel){
        weakSelf.accessibilityLabel = accessibilityLabel;
        return weakSelf;
    };
}

-(UIControl  *(^)(NSString *  accessibilityHint))set_accessibilityHint{
    __weak typeof(self) weakSelf = self;
    return ^(NSString *  accessibilityHint){
        weakSelf.accessibilityHint = accessibilityHint;
        return weakSelf;
    };
}

-(UIControl  *(^)(NSString *  accessibilityValue))set_accessibilityValue{
    __weak typeof(self) weakSelf = self;
    return ^(NSString *  accessibilityValue){
        weakSelf.accessibilityValue = accessibilityValue;
        return weakSelf;
    };
}

-(UIControl  *(^)(unsigned long long  accessibilityTraits))set_accessibilityTraits{
    __weak typeof(self) weakSelf = self;
    return ^(unsigned long long  accessibilityTraits){
        weakSelf.accessibilityTraits = accessibilityTraits;
        return weakSelf;
    };
}

-(UIControl  *(^)(UIBezierPath *  accessibilityPath))set_accessibilityPath{
    __weak typeof(self) weakSelf = self;
    return ^(UIBezierPath *  accessibilityPath){
        weakSelf.accessibilityPath = accessibilityPath;
        return weakSelf;
    };
}

-(UIControl  *(^)(CGPoint  accessibilityActivationPoint))set_accessibilityActivationPoint{
    __weak typeof(self) weakSelf = self;
    return ^(CGPoint  accessibilityActivationPoint){
        weakSelf.accessibilityActivationPoint = accessibilityActivationPoint;
        return weakSelf;
    };
}

-(UIControl  *(^)(NSString *  accessibilityLanguage))set_accessibilityLanguage{
    __weak typeof(self) weakSelf = self;
    return ^(NSString *  accessibilityLanguage){
        weakSelf.accessibilityLanguage = accessibilityLanguage;
        return weakSelf;
    };
}

-(UIControl  *(^)(BOOL  accessibilityElementsHidden))set_accessibilityElementsHidden{
    __weak typeof(self) weakSelf = self;
    return ^(BOOL  accessibilityElementsHidden){
        weakSelf.accessibilityElementsHidden = accessibilityElementsHidden;
        return weakSelf;
    };
}

-(UIControl  *(^)(BOOL  accessibilityViewIsModal))set_accessibilityViewIsModal{
    __weak typeof(self) weakSelf = self;
    return ^(BOOL  accessibilityViewIsModal){
        weakSelf.accessibilityViewIsModal = accessibilityViewIsModal;
        return weakSelf;
    };
}

-(UIControl  *(^)(BOOL  shouldGroupAccessibilityChildren))set_shouldGroupAccessibilityChildren{
    __weak typeof(self) weakSelf = self;
    return ^(BOOL  shouldGroupAccessibilityChildren){
        weakSelf.shouldGroupAccessibilityChildren = shouldGroupAccessibilityChildren;
        return weakSelf;
    };
}

-(UIControl  *(^)(long long  accessibilityNavigationStyle))set_accessibilityNavigationStyle{
    __weak typeof(self) weakSelf = self;
    return ^(long long  accessibilityNavigationStyle){
        weakSelf.accessibilityNavigationStyle = accessibilityNavigationStyle;
        return weakSelf;
    };
}

-(UIControl *(^)(id value,NSString *key))set_ValueKey{
    __weak typeof(self) weakSelf = self;
    return ^(id value,NSString *key){
        [NSObject tf_setTargetValue:weakSelf withValue:value forKey:key];
        return weakSelf;
    };
}

@end


text:
@interface XXUser : NSObject <FICEntity>

@property (nonatomic, copy) NSString *name;

@end

@implementation XXUser

- (NSString *)fic_UUID{
    CFUUIDBytes UUIDBytes = FICUUIDBytesFromMD5HashOfString(_name);
    NSString *UUID = FICStringWithUUIDBytes(UUIDBytes);
    return UUID;
}

- (NSString *)fic_sourceImageUUID{
    CFUUIDBytes UUIDBytes = FICUUIDBytesFromMD5HashOfString(_name);
    NSString *UUID = FICStringWithUUIDBytes(UUIDBytes);
    return UUID;
}

- (NSURL *)fic_sourceImageURLWithFormatName:(NSString *)formatName{
    return [NSURL URLWithString:_name];
}

- (FICEntityImageDrawingBlock)fic_drawingBlockForImage:(UIImage *)image withFormatName:(NSString *)formatName{
    FICEntityImageDrawingBlock drawingBlock = ^(CGContextRef context, CGSize contextSize) {
        CGRect contextBounds = CGRectZero;
        contextBounds.size = contextSize;
        CGContextClearRect(context, contextBounds);

        UIGraphicsPushContext(context);
        [image drawInRect:contextBounds];
        UIGraphicsPopContext();
    };
    return drawingBlock;
}

@end

@interface AppDelegate ()<FICImageCacheDelegate>

@end

@implementation AppDelegate

- (NSArray<NSString*> *)getImages{
    NSArray *imageUrls = [[NSBundle mainBundle] URLsForResourcesWithExtension:@"jpg" subdirectory:@"DemoImages"];
    NSMutableArray<NSString*> *images = [[NSMutableArray alloc] initWithCapacity:imageUrls.count];
    for(NSURL *url in imageUrls){
        NSString *urlString = [url absoluteString];
        [images addObject:urlString];
    }
    return images;
}

- (NSArray<XXUser*>*)getUsers{
    NSMutableArray *users = [[NSMutableArray alloc]initWithCapacity:99];
    for(NSUInteger idx = 1; idx <= 99; ++idx){
        NSString *name = [NSString stringWithFormat:@"FICDDemoImage%0.3lu",idx];
        XXUser *user = [[XXUser alloc]init];
        user.name = name;
        [users addObject:user];
    }
    return users;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    CFTimeInterval begin = CACurrentMediaTime();
//    [self normalImageNamedLoad];
//    [self normalLoad];
    [self fastLoad];
    CFTimeInterval end = CACurrentMediaTime();
    NSLog(@"cost = %@ms",@(1000 * (end - begin)));

    return YES;
}

- (void)normalLoad{
    NSArray *images = [self getImages];
    NSMutableArray * ret = [[NSMutableArray alloc] initWithCapacity:images.count];
    for(NSString *urlString in images){
        NSString *fixedString = [urlString stringByReplacingOccurrencesOfString:@"file://" withString:@""];
        UIImage *img = [UIImage imageWithContentsOfFile:fixedString];
        [ret addObject:img];
    }
}

- (void)normalImageNamedLoad{
    NSMutableArray * ret = [[NSMutableArray alloc] initWithCapacity:100];
    for(NSUInteger idx = 1; idx <= 99; ++idx){
        NSString *name = [NSString stringWithFormat:@"FICDDemoImage%0.3lu",idx];
        UIImage *img = [UIImage imageNamed:name];
        [ret addObject:img];
    }

}

- (void)fastLoad{
    static NSString *formatName = @"com.mycompany.myapp.XXImageFormatNameUserThumbnailMedium";
    static NSString *familyName = @"com.mycompany.myapp.XXImageFormatFamilyUserThumbnails";

    FICImageFormat *mediumUserThumbnailImageFormat = [[FICImageFormat alloc] init];
    mediumUserThumbnailImageFormat.name = formatName;
    mediumUserThumbnailImageFormat.family = familyName;
    mediumUserThumbnailImageFormat.style = FICImageFormatStyle32BitBGRA;
    mediumUserThumbnailImageFormat.imageSize = CGSizeMake(100, 100);
    mediumUserThumbnailImageFormat.maximumCount = 250;
    mediumUserThumbnailImageFormat.devices = FICImageFormatDevicePhone;
    mediumUserThumbnailImageFormat.protectionMode = FICImageFormatProtectionModeNone;

    NSArray *imageFormats = @[mediumUserThumbnailImageFormat];
    FICImageCache * sharedImageCache = [FICImageCache sharedImageCache];
    sharedImageCache.delegate = self;
    [sharedImageCache setFormats:imageFormats];

    NSArray *users = [self getUsers];

    int cnt = 0;
    for(XXUser *user in users){
        BOOL imageExists = [sharedImageCache retrieveImageForEntity:user withFormatName:formatName completionBlock:^(id<FICEntity>  _Nullable entity, NSString * _Nonnull formatName, UIImage * _Nullable image) {
//            NSLog(@"%@ = %@",[entity fic_UUID],image);
        }];
        if(!imageExists){
            ++cnt;
//            NSLog(@"%@ not exists : %@",[user fic_UUID],@(cnt));
        }
    }

}

-(void)imageCache:(FICImageCache *)imageCache wantsSourceImageForEntity:(id<FICEntity>)entity withFormatName:(NSString *)formatName completionBlock:(FICImageRequestCompletionBlock)completionBlock{

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSURL *url = [entity fic_sourceImageURLWithFormatName:@""];
        UIImage *img = [UIImage imageNamed:[url absoluteString]];
        dispatch_async(dispatch_get_main_queue(), ^{
            completionBlock(img);
        });
    });
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end


text:
package dynaml

import (
	"fmt"
	"regexp"
)

// MaxLenError returns a string explanation of a "string too long" validation
// failure.
func MaxLenError(length int) string {
	return fmt.Sprintf("must be no more than %d characters", length)
}

// RegexError returns a string explanation of a regex validation failure.
func RegexError(msg string, fmt string, examples ...string) string {
	if len(examples) == 0 {
		return msg + " (regex used for validation is '" + fmt + "')"
	}
	msg += " (e.g. "
	for i := range examples {
		if i > 0 {
			msg += " or "
		}
		msg += "'" + examples[i] + "', "
	}
	msg += "regex used for validation is '" + fmt + "')"
	return msg
}

// EmptyError returns a string explanation of a "must not be empty" validation
// failure.
func EmptyError() string {
	return "must be non-empty"
}

const dns1123LabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
const dns1123LabelErrMsg string = "a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character"
const DNS1123LabelMaxLength int = 63

var dns1123LabelRegexp = regexp.MustCompile("^" + dns1123LabelFmt + "$")

// IsDNS1123Label tests for a string that conforms to the definition of a label in
// DNS (RFC 1123).
func IsDNS1123Label(value string) []string {
	var errs []string
	if len(value) > DNS1123LabelMaxLength {
		errs = append(errs, MaxLenError(DNS1123LabelMaxLength))
	}
	if !dns1123LabelRegexp.MatchString(value) {
		errs = append(errs, RegexError(dns1123LabelErrMsg, dns1123LabelFmt, "my-name", "123-abc"))
	}
	return errs
}

const dns1123SubdomainFmt string = dns1123LabelFmt + "(\\." + dns1123LabelFmt + ")*"
const dns1123SubdomainErrorMsg string = "a DNS-1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character"
const DNS1123SubdomainMaxLength int = 253

var dns1123SubdomainRegexp = regexp.MustCompile("^" + dns1123SubdomainFmt + "$")

// IsDNS1123Subdomain tests for a string that conforms to the definition of a
// subdomain in DNS (RFC 1123).
func IsDNS1123Subdomain(value string) []string {
	var errs []string
	if len(value) > DNS1123SubdomainMaxLength {
		errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength))
	}
	if !dns1123SubdomainRegexp.MatchString(value) {
		errs = append(errs, RegexError(dns1123SubdomainErrorMsg, dns1123SubdomainFmt, "example.com"))
	}
	return errs
}

const dns1035LabelFmt string = "[a-z]([-a-z0-9]*[a-z0-9])?"
const dns1035LabelErrMsg string = "a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character"
const DNS1035LabelMaxLength int = 63

var dns1035LabelRegexp = regexp.MustCompile("^" + dns1035LabelFmt + "$")

// IsDNS1035Label tests for a string that conforms to the definition of a label in
// DNS (RFC 1035).
func IsDNS1035Label(value string) []string {
	var errs []string
	if len(value) > DNS1035LabelMaxLength {
		errs = append(errs, MaxLenError(DNS1035LabelMaxLength))
	}
	if !dns1035LabelRegexp.MatchString(value) {
		errs = append(errs, RegexError(dns1035LabelErrMsg, dns1035LabelFmt, "my-name", "abc-123"))
	}
	return errs
}

// wildcard definition - RFC 1034 section 4.3.3.
// examples:
// - valid: *.bar.com, *.foo.bar.com
// - invalid: *.*.bar.com, *.foo.*.com, *bar.com, f*.bar.com, *
const wildcardDNS1123SubdomainFmt = "\\*\\." + dns1123SubdomainFmt
const wildcardDNS1123SubdomainErrMsg = "a wildcard DNS-1123 subdomain must start with '*.', followed by a valid DNS subdomain, which must consist of lower case alphanumeric characters, '-' or '.' and end with an alphanumeric character"

// IsWildcardDNS1123Subdomain tests for a string that conforms to the definition of a
// wildcard subdomain in DNS (RFC 1034 section 4.3.3).
func IsWildcardDNS1123Subdomain(value string) []string {
	wildcardDNS1123SubdomainRegexp := regexp.MustCompile("^" + wildcardDNS1123SubdomainFmt + "$")

	var errs []string
	if len(value) > DNS1123SubdomainMaxLength {
		errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength))
	}
	if !wildcardDNS1123SubdomainRegexp.MatchString(value) {
		errs = append(errs, RegexError(wildcardDNS1123SubdomainErrMsg, wildcardDNS1123SubdomainFmt, "*.example.com"))
	}
	return errs
}


text:
<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="api_platform.elasticsearch.client" class="Elasticsearch\Client" public="false" />

        <service id="api_platform.elasticsearch.cache.metadata.document" parent="cache.system" public="false">
            <tag name="cache.pool" />
        </service>

        <service id="api_platform.elasticsearch.metadata.document.metadata_factory" alias="api_platform.elasticsearch.metadata.document.metadata_factory.configured" />

        <service id="ApiPlatform\Elasticsearch\Metadata\Document\Factory\DocumentMetadataFactoryInterface" alias="api_platform.elasticsearch.metadata.document.metadata_factory" />

        <service id="api_platform.elasticsearch.metadata.document.metadata_factory.configured" class="ApiPlatform\Elasticsearch\Metadata\Document\Factory\ConfiguredDocumentMetadataFactory" public="false">
            <argument>%api_platform.elasticsearch.mapping%</argument>
        </service>

        <service id="api_platform.elasticsearch.metadata.document.metadata_factory.attribute" class="ApiPlatform\Elasticsearch\Metadata\Document\Factory\AttributeDocumentMetadataFactory" decorates="api_platform.elasticsearch.metadata.document.metadata_factory" decoration-priority="20" public="false">
            <argument type="service" id="api_platform.metadata.resource.metadata_collection_factory.retro_compatible" />
            <argument type="service" id="api_platform.elasticsearch.metadata.document.metadata_factory.attribute.inner" />
        </service>

        <service id="api_platform.elasticsearch.metadata.document.metadata_factory.cat" class="ApiPlatform\Elasticsearch\Metadata\Document\Factory\CatDocumentMetadataFactory" decorates="api_platform.elasticsearch.metadata.document.metadata_factory" decoration-priority="10" public="false">
            <argument type="service" id="api_platform.elasticsearch.client" />
            <argument type="service" id="api_platform.metadata.resource.metadata_collection_factory.retro_compatible" />
            <argument type="service" id="api_platform.elasticsearch.metadata.document.metadata_factory.cat.inner" />
        </service>

        <service id="api_platform.elasticsearch.metadata.document.metadata_factory.cached" class="ApiPlatform\Elasticsearch\Metadata\Document\Factory\CachedDocumentMetadataFactory" decorates="api_platform.elasticsearch.metadata.document.metadata_factory" decoration-priority="-10" public="false">
            <argument type="service" id="api_platform.elasticsearch.cache.metadata.document" />
            <argument type="service" id="api_platform.elasticsearch.metadata.document.metadata_factory.cached.inner" />
        </service>

        <service id="api_platform.elasticsearch.name_converter.inner_fields" class="ApiPlatform\Elasticsearch\Serializer\NameConverter\InnerFieldsNameConverter" public="false">
            <argument type="service" id="api_platform.name_converter" on-invalid="ignore" />
        </service>

        <service id="api_platform.elasticsearch.normalizer.item" class="ApiPlatform\Elasticsearch\Serializer\ItemNormalizer" decorates="api_platform.serializer.normalizer.item" public="false">
            <argument type="service" id="api_platform.elasticsearch.normalizer.item.inner" />
        </service>

        <service id="api_platform.elasticsearch.normalizer.document" class="ApiPlatform\Elasticsearch\Serializer\DocumentNormalizer" public="false">
            <argument type="service" id="api_platform.metadata.resource.metadata_collection_factory" />
            <argument type="service" id="serializer.mapping.class_metadata_factory" />
            <argument type="service" id="api_platform.elasticsearch.name_converter.inner_fields" />
            <argument type="service" id="serializer.property_accessor" />
            <argument type="service" id="property_info" on-invalid="ignore" />
            <argument type="service" id="serializer.mapping.class_discriminator_resolver" on-invalid="ignore" />

            <!-- Run after serializer.normalizer.data_uri but before serializer.normalizer.object -->
            <tag name="serializer.normalizer" priority="-922" />
        </service>

        <service id="api_platform.elasticsearch.request_body_search_extension.filter" public="false" abstract="true">
            <argument type="service" id="api_platform.filter_locator" />
        </service>

        <service id="api_platform.elasticsearch.request_body_search_extension.constant_score_filter" parent="api_platform.elasticsearch.request_body_search_extension.filter" class="ApiPlatform\Elasticsearch\Extension\ConstantScoreFilterExtension">
            <tag name="api_platform.elasticsearch.request_body_search_extension.collection" priority="30" />
        </service>

        <service id="api_platform.elasticsearch.request_body_search_extension.sort_filter" parent="api_platform.elasticsearch.request_body_search_extension.filter" class="ApiPlatform\Elasticsearch\Extension\SortFilterExtension">
            <tag name="api_platform.elasticsearch.request_body_search_extension.collection" priority="20" />
        </service>

        <service id="api_platform.elasticsearch.request_body_search_extension.sort" class="ApiPlatform\Elasticsearch\Extension\SortExtension" public="false">
            <argument type="service" id="api_platform.metadata.property.metadata_factory" />
            <argument type="service" id="api_platform.resource_class_resolver" />
            <argument type="service" id="api_platform.elasticsearch.name_converter.inner_fields" />
            <argument>%api_platform.collection.order%</argument>

            <tag name="api_platform.elasticsearch.request_body_search_extension.collection" priority="10" />
        </service>

        <service id="api_platform.elasticsearch.search_filter" public="false" abstract="true">
            <argument type="service" id="api_platform.metadata.property.name_collection_factory" />
            <argument type="service" id="api_platform.metadata.property.metadata_factory" />
            <argument type="service" id="api_platform.resource_class_resolver" />
            <argument type="service" id="api_platform.iri_converter" />
            <argument type="service" id="api_platform.property_accessor" />
            <argument type="service" id="api_platform.elasticsearch.name_converter.inner_fields" />
        </service>

        <service id="api_platform.elasticsearch.term_filter" class="ApiPlatform\Elasticsearch\Filter\TermFilter" parent="api_platform.elasticsearch.search_filter" public="false" abstract="true" />
        <service id="ApiPlatform\Elasticsearch\Filter\TermFilter" alias="api_platform.elasticsearch.term_filter" />

        <service id="api_platform.elasticsearch.match_filter" class="ApiPlatform\Elasticsearch\Filter\MatchFilter" parent="api_platform.elasticsearch.search_filter" public="false" abstract="true" />
        <service id="ApiPlatform\Elasticsearch\Filter\MatchFilter" alias="api_platform.elasticsearch.match_filter" />

        <service id="api_platform.elasticsearch.order_filter" class="ApiPlatform\Elasticsearch\Filter\OrderFilter" public="false" abstract="true">
            <argument type="service" id="api_platform.metadata.property.name_collection_factory" />
            <argument type="service" id="api_platform.metadata.property.metadata_factory" />
            <argument type="service" id="api_platform.resource_class_resolver" />
            <argument type="service" id="api_platform.elasticsearch.name_converter.inner_fields" />
            <argument>%api_platform.collection.order_parameter_name%</argument>
        </service>
        <service id="ApiPlatform\Elasticsearch\Filter\OrderFilter" alias="api_platform.elasticsearch.order_filter" />

        <service id="ApiPlatform\Elasticsearch\State\ItemProvider" class="ApiPlatform\Elasticsearch\State\ItemProvider" public="false">
            <argument type="service" id="api_platform.elasticsearch.client" />
            <argument type="service" id="api_platform.elasticsearch.metadata.document.metadata_factory" />
            <argument type="service" id="serializer" />

            <tag name="api_platform.state_provider" priority="-100" />
        </service>

        <service id="ApiPlatform\Elasticsearch\State\CollectionProvider" class="ApiPlatform\Elasticsearch\State\CollectionProvider" public="false">
            <argument type="service" id="api_platform.elasticsearch.client" />
            <argument type="service" id="api_platform.elasticsearch.metadata.document.metadata_factory" />
            <argument type="service" id="serializer" />
            <argument type="service" id="api_platform.pagination" />
            <argument type="tagged" tag="api_platform.elasticsearch.request_body_search_extension.collection" />

            <tag name="api_platform.state_provider" priority="-100" />
        </service>

        <service id="api_platform.elasticsearch.metadata.resource.metadata_collection_factory" class="ApiPlatform\Elasticsearch\Metadata\Resource\Factory\ElasticsearchProviderResourceMetadataCollectionFactory" decorates="api_platform.metadata.resource.metadata_collection_factory" decoration-priority="40">
            <argument type="service" id="api_platform.elasticsearch.client" />
            <argument type="service" id="api_platform.elasticsearch.metadata.resource.metadata_collection_factory.inner" />
        </service>

    </services>

</container>


text:
def whyrun_supported?
  false
end

action :switch do
  version = @new_resource.version
  base_dir = node[:phpversion][:versions_dir]
  path_regexp = /#{Regexp.escape(base_dir)}.*?:/
  target_dir = "#{base_dir}/#{version}"

  if version.nil?
    ENV.delete('PHP_VERSIONS')
    ENV.delete('PHPRC')
    ENV['PATH'] = ENV['PATH'].gsub(path_regexp, '')

    Chef::Log.info("php-version switched off")
  elsif ::File.exists?("#{target_dir}/bin")
    ENV['PHP_VERSIONS'] = base_dir
    ENV['PHPRC'] = "#{target_dir}/etc/php.ini" if ::File.exists?("#{target_dir}/etc/php.ini")

    path = ENV['PATH'].gsub(path_regexp, '')
    path = "#{target_dir}/bin:#{path}"
    path = "#{target_dir}/sbin:#{path}" if ::File.exists?("#{target_dir}/sbin")

    ENV['PATH'] = path

    Chef::Log.info("php-version: switched PHP to #{version}")
  else
    Chef::Log.warn("#{target_dir} directory was not found (action skipped).")
  end
end