diff --git a/patches/gromacs-4.6.0.config b/patches/gromacs-4.6.0.config
new file mode 100644
index 0000000000000000000000000000000000000000..a5d00fcea22295d52544fcd345e60947ff7553ef
--- /dev/null
+++ b/patches/gromacs-4.6.0.config
@@ -0,0 +1,6 @@
+
+
+function plumed_preliminary_test(){
+# check if the README contains the word GROMACS and if gromacs has been already configured
+  grep -q GROMACS README 1>/dev/null 2>/dev/null
+}
diff --git a/patches/gromacs-4.6.0.diff b/patches/gromacs-4.6.0.diff
new file mode 100644
index 0000000000000000000000000000000000000000..8ce2a443311966a44532a2f004bdfa567441dc46
--- /dev/null
+++ b/patches/gromacs-4.6.0.diff
@@ -0,0 +1,396 @@
+patch -u -l -b -F 5 --suffix=.preplumed "./src/kernel/CMakeLists.txt" << \EOF_EOF
+--- ./src/kernel/CMakeLists.txt.preplumed
++++ ./src/kernel/CMakeLists.txt
+@@ -31,10 +31,12 @@
+ #
+ # To help us fund GROMACS development, we humbly ask that you cite
+ # the research papers on the package. Check out http://www.gromacs.org.
+ #
+ 
++include(${CMAKE_SOURCE_DIR}/Plumed.cmake)
++
+ set(GMXPREPROCESS_SOURCES 
+     add_par.c       
+     calc_verletbuf.c
+     compute_io.c    
+     convparm.c      
+@@ -126,11 +128,11 @@
+     set_target_properties(${PROGRAM} PROPERTIES OUTPUT_NAME "${PROGRAM}${GMX_BINARY_SUFFIX}")
+ endforeach()
+ 
+ add_executable(mdrun ${MDRUN_SOURCES} main.c)
+ gmx_add_man_page(mdrun)
+-target_link_libraries(mdrun ${GMX_EXTRA_LIBRARIES} ${GMX_OPENMM_LIBRARIES})
++target_link_libraries(mdrun ${GMX_EXTRA_LIBRARIES} ${GMX_OPENMM_LIBRARIES} ${PLUMED_LOAD})
+ set_target_properties(mdrun PROPERTIES OUTPUT_NAME "mdrun${GMX_BINARY_SUFFIX}" COMPILE_FLAGS "${OpenMP_C_FLAGS}")
+ 
+ # this is to circumvent the following MSVC error: 
+ # warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs
+ # fatal error LNK1169: one or more multiply defined symbols found
+EOF_EOF
+patch -u -l -b -F 5 --suffix=.preplumed "./src/kernel/md.c" << \EOF_EOF
+--- ./src/kernel/md.c.preplumed
++++ ./src/kernel/md.c
+@@ -91,10 +91,16 @@
+ #include "membed.h"
+ #include "types/nlistheuristics.h"
+ #include "types/iteratedconstraints.h"
+ #include "nbnxn_cuda_data_mgmt.h"
+ 
++/* PLUMED */
++#include "../../Plumed.h"
++extern int    plumedswitch;
++extern plumed plumedmain;
++/* END PLUMED */
++
+ #ifdef GMX_LIB_MPI
+ #include <mpi.h>
+ #endif
+ #ifdef GMX_THREAD_MPI
+ #include "tmpi.h"
+@@ -688,10 +694,50 @@
+             }
+         }
+         fprintf(fplog,"\n");
+     }
+ 
++    /* PLUMED */
++    if(plumedswitch){
++      if(cr->ms && cr->ms->nsim>1) {
++        if(MASTER(cr)) plumed_cmd(plumedmain,"GREX setMPIIntercomm",&cr->ms->mpi_comm_masters);
++        if(PAR(cr)){
++          if(DOMAINDECOMP(cr)) {
++            plumed_cmd(plumedmain,"GREX setMPIIntracomm",&cr->dd->mpi_comm_all);
++          }else{
++            plumed_cmd(plumedmain,"GREX setMPIIntracomm",&cr->mpi_comm_mysim);
++          }
++        }
++        plumed_cmd(plumedmain,"GREX init",NULL);
++      }
++      if(PAR(cr)){
++        if(DOMAINDECOMP(cr)) {
++          plumed_cmd(plumedmain,"setMPIComm",&cr->dd->mpi_comm_all);
++        }else{
++          plumed_cmd(plumedmain,"setMPIComm",&cr->mpi_comm_mysim);
++        }
++      }
++      plumed_cmd(plumedmain,"setNatoms",&top_global->natoms);
++      plumed_cmd(plumedmain,"setMDEngine","gromacs");
++      plumed_cmd(plumedmain,"setLog",fplog);
++      real real_delta_t;
++      real_delta_t=ir->delta_t;
++      plumed_cmd(plumedmain,"setTimestep",&real_delta_t);
++      plumed_cmd(plumedmain,"init",NULL);
++
++      if(PAR(cr)){
++        if(DOMAINDECOMP(cr)) {
++          plumed_cmd(plumedmain,"setAtomsNlocal",&cr->dd->nat_home);
++          plumed_cmd(plumedmain,"setAtomsGatindex",cr->dd->gatindex);
++        }else{
++          plumed_cmd(plumedmain,"setAtomsNlocal",&mdatoms->homenr);
++          plumed_cmd(plumedmain,"setAtomsContiguous",&mdatoms->start);
++        }
++      }
++    }
++    /* END PLUMED */
++
+     /* Set and write start time */
+     runtime_start(runtime);
+     print_date_and_time(fplog,cr->nodeid,"Started mdrun",runtime);
+     wallcycle_start(wcycle,ewcRUN);
+     if (fplog)
+@@ -998,10 +1044,17 @@
+                                     vsite,shellfc,constr,
+                                     nrnb,wcycle,
+                                     do_verbose && !bPMETuneRunning);
+                 wallcycle_stop(wcycle,ewcDOMDEC);
+                 /* If using an iterative integrator, reallocate space to match the decomposition */
++
++                /* PLUMED */
++                if(plumedswitch){
++                  plumed_cmd(plumedmain,"setAtomsNlocal",&cr->dd->nat_home);
++                  plumed_cmd(plumedmain,"setAtomsGatindex",cr->dd->gatindex);
++                }
++                /* END PLUMED */
+             }
+         }
+ 
+         if (MASTER(cr) && do_log && !bFFscan)
+         {
+@@ -1137,16 +1190,39 @@
+             /* The coordinates (x) are shifted (to get whole molecules)
+              * in do_force.
+              * This is parallellized as well, and does communication too. 
+              * Check comments in sim_util.c
+              */
++
++             /* PLUMED */
++             if(plumedswitch){
++               plumed_cmd(plumedmain,"setStep",&step);
++               plumed_cmd(plumedmain,"setPositions",&state->x[mdatoms->start][0]);
++               plumed_cmd(plumedmain,"setMasses",&mdatoms->massT[mdatoms->start]);
++               plumed_cmd(plumedmain,"setCharges",&mdatoms->chargeA[mdatoms->start]);
++               plumed_cmd(plumedmain,"setBox",&state->box[0][0]);
++               plumed_cmd(plumedmain,"prepareCalc",NULL);
++             }
++             /* END PLUMED */
+              do_force(fplog,cr,ir,step,nrnb,wcycle,top,top_global,groups,
+                      state->box,state->x,&state->hist,
+                      f,force_vir,mdatoms,enerd,fcd,
+                      state->lambda,graph,
+                      fr,vsite,mu_tot,t,outf->fp_field,ed,bBornRadii,
+                      (bNS ? GMX_FORCE_NS : 0) | force_flags);
++
++             /* PLUMED */
++             if(plumedswitch){
++               plumed_cmd(plumedmain,"setEnergy",&enerd->term[F_EPOT]);
++               plumed_cmd(plumedmain,"setForces",&f[mdatoms->start][0]);
++               plumed_cmd(plumedmain,"setVirial",&force_vir[0][0]);
++               plumed_cmd(plumedmain,"performCalc",NULL);
++               if ((repl_ex_nst > 0) && (step > 0) && !bLastStep &&
++                  do_per_step(step,repl_ex_nst)) plumed_cmd(plumedmain,"GREX savePositions",NULL);
++             }
++             /* END PLUMED */
++
+         }
+     
+         GMX_BARRIER(cr->mpi_comm_mygroup);
+         
+         if (bTCR)
+EOF_EOF
+patch -u -l -b -F 5 --suffix=.preplumed "./src/kernel/mdrun.c" << \EOF_EOF
+--- ./src/kernel/mdrun.c.preplumed
++++ ./src/kernel/mdrun.c
+@@ -56,10 +56,16 @@
+ #endif
+ 
+ /* afm stuf */
+ #include "pull.h"
+ 
++/* PLUMED */
++#include "../../Plumed.h"
++int    plumedswitch;
++plumed plumedmain;
++/* END PLUMED */
++
+ int cmain(int argc,char *argv[])
+ {
+   const char *desc[] = {
+  #ifdef GMX_OPENMM
+     "This is an experimental release of GROMACS for accelerated",
+@@ -463,10 +469,11 @@
+     { efLOG, "-ra",     "rotangles",ffOPTWR },
+     { efLOG, "-rs",     "rotslabs", ffOPTWR },
+     { efLOG, "-rt",     "rottorque",ffOPTWR },
+     { efMTX, "-mtx",    "nm",       ffOPTWR },
+     { efNDX, "-dn",     "dipole",   ffOPTWR },
++    { efDAT, "-plumed", "plumed",   ffOPTRD },   /* PLUMED */
+     { efRND, "-multidir",NULL,      ffOPTRDMULT},
+     { efDAT, "-membed", "membed",   ffOPTRD },
+     { efTOP, "-mp",     "membed",   ffOPTRD },
+     { efNDX, "-mn",     "membed",   ffOPTRD }
+   };
+@@ -782,18 +789,50 @@
+ 
+   ddxyz[XX] = (int)(realddxyz[XX] + 0.5);
+   ddxyz[YY] = (int)(realddxyz[YY] + 0.5);
+   ddxyz[ZZ] = (int)(realddxyz[ZZ] + 0.5);
+ 
++/* PLUMED */
++  plumedswitch=0;
++  if (opt2bSet("-plumed",NFILE,fnm)) plumedswitch=1;
++  if(plumedswitch){
++    int plumed_is_there=0;
++    int real_precision=sizeof(real);
++    real energyUnits=1.0;
++    real lengthUnits=1.0;
++    real timeUnits=1.0;
++
++
++    if(!plumed_installed()){
++      gmx_fatal(FARGS,"Plumed is not available. Check your PLUMED_KERNEL variable.");
++    }
++    plumedmain=plumed_create();
++    plumed_cmd(plumedmain,"setRealPrecision",&real_precision);
++// this is not necessary for gromacs units:
++    plumed_cmd(plumedmain,"setMDEnergyUnits",&energyUnits);
++    plumed_cmd(plumedmain,"setMDLengthUnits",&lengthUnits);
++    plumed_cmd(plumedmain,"setMDTimeUnits",&timeUnits);
++//
++    plumed_cmd(plumedmain,"setPlumedDat",ftp2fn(efDAT,NFILE,fnm));
++    plumedswitch=1;
++  }
++/* END PLUMED */
++
+   rc = mdrunner(&hw_opt, fplog,cr,NFILE,fnm,oenv,bVerbose,bCompact,
+                 nstglobalcomm, ddxyz,dd_node_order,rdd,rconstr,
+                 dddlb_opt[0],dlb_scale,ddcsx,ddcsy,ddcsz,
+                 nbpu_opt[0],
+                 nsteps,nstepout,resetstep,
+                 nmultisim,repl_ex_nst,repl_ex_nex,repl_ex_seed,
+                 pforce, cpt_period,max_hours,deviceOptions,Flags);
+ 
++/* PLUMED */
++  if(plumedswitch){
++    plumed_finalize(plumedmain);
++  }
++/* END PLUMED */
++
+   gmx_finalize_par();
+ 
+   if (MULTIMASTER(cr)) {
+       thanx(stderr);
+   }
+EOF_EOF
+patch -u -l -b -F 5 --suffix=.preplumed "./src/kernel/repl_ex.c" << \EOF_EOF
+--- ./src/kernel/repl_ex.c.preplumed
++++ ./src/kernel/repl_ex.c
+@@ -51,10 +51,16 @@
+ #include "names.h"
+ #include "mvdata.h"
+ #include "domdec.h"
+ #include "partdec.h"
+ 
++/* PLUMED */
++#include "../../Plumed.h"
++extern int    plumedswitch;
++extern plumed plumedmain;
++/* END PLUMED */
++
+ #define PROBABILITYCUTOFF 100
+ /* we don't bother evaluating if events are more rare than exp(-100) = 3.7x10^-44 */
+ 
+ enum { ereTEMP, ereLAMBDA, ereENDSINGLE ,ereTL, ereNR };
+ const char *erename[ereNR] = { "temperature", "lambda", "end_single_marker", "temperature and lambda"};
+@@ -109,18 +115,20 @@
+ 
+     snew(qall,ms->nsim);
+     qall[re->repl] = q;
+     gmx_sum_sim(ms->nsim,qall,ms);
+ 
+-    bDiff = FALSE;
+-    for (s=1; s<ms->nsim; s++)
+-    {
+-        if (qall[s] != qall[0])
+-        {
++    /* PLUMED */
++    //bDiff = FALSE;
++    //for (s=1; s<ms->nsim; s++)
++    //{
++    //    if (qall[s] != qall[0])
++    //    {
+             bDiff = TRUE;   
+-        }
+-    }
++    //    }
++    //}
++    /* END PLUMED */
+ 
+     if (bDiff)
+     {
+         /* Set the replica exchange type and quantities */
+         re->type = ere;
+@@ -251,10 +259,14 @@
+     for(i=0; i<re->nrepl; i++)
+     {
+         re->ind[i] = i;
+     }
+ 
++    /* PLUMED */
++    // plumed2: check if we want alternative patterns (i.e. for bias-exchange metaD)
++    // in those cases replicas can share the same temperature.
++    /*
+     if (re->type<ereENDSINGLE) {
+ 
+         for(i=0; i<re->nrepl; i++)
+         {
+             for(j=i+1; j<re->nrepl; j++)
+@@ -270,10 +282,12 @@
+                     gmx_fatal(FARGS,"Two replicas have identical %ss",erename[re->type]);
+                 }
+             }
+         }
+     }
++    */
++    /* END PLUMED */
+ 
+     /* keep track of all the swaps, starting with the initial placement. */
+     snew(re->allswaps,re->nrepl);
+     for(i=0; i<re->nrepl; i++)
+     {
+@@ -1008,19 +1022,59 @@
+     }
+     else
+     {
+         /* standard nearest neighbor replica exchange */
+         m = (step / re->nst) % 2;
++
++        /* PLUMED */
++        if(plumedswitch){
++          int partner=re->repl;
++          int test=0;
++          plumed_cmd(plumedmain,"getExchangesFlag",&test);
++          if(test>0){
++            int *list;
++            snew(list,re->nrepl);
++            plumed_cmd(plumedmain,"setNumberOfReplicas",&(re->nrepl));
++            plumed_cmd(plumedmain,"getExchangesList",list);
++            for(i=0; i<re->nrepl; i++) re->ind[i]=list[i];
++            sfree(list);
++          }
++
++          for(i=1; i<re->nrepl; i++) {
++            if (i % 2 != m) continue;
++            a = re->ind[i-1];
++            b = re->ind[i];
++            if(re->repl==a) partner=b;
++            if(re->repl==b) partner=a;
++          }
++          plumed_cmd(plumedmain,"GREX setPartner",&partner);
++          plumed_cmd(plumedmain,"GREX calculate",NULL);
++          plumed_cmd(plumedmain,"GREX shareAllDeltaBias",NULL);
++        }
++        /* END PLUMED */
++
+         for(i=1; i<re->nrepl; i++)
+         {
+             a = re->ind[i-1];
+             b = re->ind[i];
+             
+             bPrint = (re->repl==a || re->repl==b);
+             if (i % 2 == m)
+             {
+                 delta = calc_delta(fplog,bPrint,re,a,b,a,b);
++                /* PLUMED */
++                if(plumedswitch){
++                  real adb,bdb,dplumed;
++                  char buf[300];
++                  sprintf(buf,"GREX getDeltaBias %d",a); plumed_cmd(plumedmain,buf,&adb);
++                  sprintf(buf,"GREX getDeltaBias %d",b); plumed_cmd(plumedmain,buf,&bdb);
++                  dplumed=adb*re->beta[a]+bdb*re->beta[b];
++                  delta+=dplumed;
++                  if (bPrint)
++                    fprintf(fplog,"  dplumed = %10.3e  d = %10.3e",dplumed,delta);
++                }
++                /* END PLUMED */
+                 if (delta <= 0) {
+                     /* accepted */
+                     prob[i] = 1;
+                     bEx[i] = TRUE;
+                 }
+@@ -1263,10 +1317,14 @@
+      * exchanges. */
+     /* Where each replica ends up after the exchange attempt(s). */
+     /* The order in which multiple exchanges will occur. */
+     gmx_bool bThisReplicaExchanged = FALSE;
+ 
++    /* PLUMED */
++    if(plumedswitch)plumed_cmd(plumedmain,"GREX prepare",NULL);
++    /* END PLUMED */
++
+     if (MASTER(cr))
+     {
+         replica_id  = re->repl;
+         test_for_replica_exchange(fplog,cr->ms,re,enerd,det(state_local->box),step,time);
+         prepare_to_do_exchange(fplog,re->destinations,replica_id,re->nrepl,&maxswap,
+EOF_EOF
diff --git a/patches/patch.sh b/patches/patch.sh
index 23872ca0938f4d19ff88d9a703f0e2b67d7ba716..31d685abc64c71c47b928b549592149f46fdb31c 100755
--- a/patches/patch.sh
+++ b/patches/patch.sh
@@ -210,6 +210,7 @@ case "$action" in
     echo "Linking Plumed.h and Plumed.inc ($mode mode)"
     ln -s "$PLUMED_ROOT/src/wrapper/Plumed.h"
     ln -s "$PLUMED_ROOT/src/lib/Plumed.inc.$mode" Plumed.inc
+    ln -s "$PLUMED_ROOT/src/lib/Plumed.cmake.$mode" Plumed.cmake
     bash "$diff"
     if type -t plumed_after_patch 1>/dev/null ; then
       echo "Executing plumed_after_patch function"
@@ -273,7 +274,7 @@ EOF
       echo "WARNING: I cannot find Plumed.h and Plumed.inc files. You have likely not patched yet."
     else
     echo "Removing Plumed.h and Plumed.inc"
-      rm Plumed.h Plumed.inc
+      rm Plumed.h Plumed.inc Plumed.cmake
     fi
     PREPLUMED=$(find . -name "*.preplumed")
     if ! test "$PREPLUMED" ; then
diff --git a/src/lib/Makefile b/src/lib/Makefile
index 9b2f6dd3226b4cc35560a97165153e04bb2389c0..d0529d448ce7ca896304702f69b841d325309d68 100644
--- a/src/lib/Makefile
+++ b/src/lib/Makefile
@@ -61,6 +61,7 @@ $(DIRS):
 lib: $(PLUMED_KERNEL) $(PLUMED_SHARED_OBJ) $(OBJ_WRAPPER) \
      $(PLUMED_MAIN_STATIC) $(PLUMED_MAIN_SHARED) $(PLUMED_MAIN_RUNTIME) \
      Plumed.inc Plumed.inc.runtime Plumed.inc.shared Plumed.inc.static \
+     Plumed.cmake Plumed.cmake.runtime Plumed.cmake.shared Plumed.cmake.static \
      plumed-patch
 
 plumed-patch:
@@ -116,6 +117,38 @@ Plumed.inc.shared: Plumed.inc
 	@echo PLUMED_LOAD= '$$(PLUMED_SHARED_LOAD)' >> $@
 	@echo PLUMED_DEPENDENCIES= '$$(PLUMED_SHARED_DEPENDENCIES)' >> $@
 
+Plumed.cmake: $(OBJ_KERNEL) $(OBJ_WRAPPER) $(PLUMED_SHARED_OBJ) $(OBJ_DYNAMIC_WRAPPER)
+	@echo Building Plumed.cmake
+	@echo "set(PLUMED_INCLUDE "-I$(realpath ../../include)")" > $@
+	@echo "set(PLUMED_RUNTIME_LOAD " $(realpath $(OBJ_DYNAMIC_WRAPPER)) $(LIBS) $(LDFLAGS)")" >> $@
+	@echo "set(PLUMED_STATIC_LOAD " $(realpath $(OBJ_KERNEL)) $(realpath $(OBJ_WRAPPER)) $(LIBS) $(DYNAMIC_LIBS) $(LDFLAGS)")" >> $@
+	@echo "set(PLUMED_SHARED_LOAD " $(realpath $(PLUMED_SHARED_OBJ)) $(LIBS) $(LDFLAGS)")" >> $@
+	@echo "set(PLUMED_RUNTIME_DEPENDENCIES) "   >> $@
+	@echo "set(PLUMED_STATIC_DEPENDENCIES " $(realpath $(OBJ_KERNEL)) $(realpath $(OBJ_WRAPPER))")"  >> $@
+	@echo "set(PLUMED_SHARED_DEPENDENCIES " $(realpath $(PLUMED_SHARED_OBJ))")"  >> $@
+
+Plumed.cmake.runtime: Plumed.cmake
+	@echo Building Plumed.cmake, runtime-linking version
+	@echo "# PLUMED: runtime installation" > $@
+	@cat $< >> $@
+	@echo "set("PLUMED_LOAD '$${PLUMED_RUNTIME_LOAD}'")" >> $@
+	@echo "set("PLUMED_DEPENDENCIES '$${PLUMED_RUNTIME_DEPENDENCIES}'")" >> $@
+
+Plumed.cmake.static: Plumed.cmake
+	@echo Building Plumed.cmake, static version
+	@echo "# PLUMED: static installation" > $@
+	@cat $< >> $@
+	@echo "set("PLUMED_LOAD '$${PLUMED_STATIC_LOAD}'")" >> $@
+	@echo "set("PLUMED_DEPENDENCIES '$${PLUMED_STATIC_DEPENDENCIES}'")" >> $@
+
+Plumed.cmake.shared: Plumed.cmake
+	@echo Building Plumed.cmake, shared version
+	@echo "# PLUMED: shared installation" > $@
+	@cat $< >> $@
+	@echo "set("PLUMED_LOAD '$${PLUMED_SHARED_LOAD}'")" >> $@
+	@echo "set("PLUMED_DEPENDENCIES '$${PLUMED_SHARED_DEPENDENCIES}'")" >> $@
+
+
 # Individual dependencies
 
 -include $(ALL_DEP)