diff --git a/src/THcTimeSyncEvtHandler.cxx b/src/THcTimeSyncEvtHandler.cxx
index 2ec522580abf3ffb9aea3ce05c27a13a6c49fe90..f94ba4972e77e20e91d03e9a3ec60c03efe3a86c 100644
--- a/src/THcTimeSyncEvtHandler.cxx
+++ b/src/THcTimeSyncEvtHandler.cxx
@@ -19,24 +19,42 @@
 
 \author Stephen Wood (saw@jlab.org)
 */
+/* This version will deal with bad run coin_all_03302.dat.
+
+That has an event with most of a noisy set of 1190 data in ROC 3.
+The next event has the remainder of the noisy data.  It's good 1190 data
+is in the next event.
+So the 1190 data for the first event with noisy data should be discarded.
+(Empty bank).  The next event should be cached, and then written out when
+the next event comes.
+*/
 
 #include "THcTimeSyncEvtHandler.h"
 #include "THaEvData.h"
 #include "THaGlobals.h"
 #include "THcGlobals.h"
 #include "THcParmList.h"
+#include "THaCodaFile.h"
+#include "THaRunBase.h"
 #include <cstring>
 #include <cstdio>
 #include <cstdlib>
 #include <iostream>
 #include <iomanip>
+//#include "evio.h"
 
 using namespace std;
+using namespace Decoder;
 
 THcTimeSyncEvtHandler::THcTimeSyncEvtHandler(const char *name, const char* description)
   : THaEvtTypeHandler(name,description)
 {
   ExpectedOffsetMap.clear();
+  fBadROC = -1;
+  fResync = kTRUE;
+  fBadSyncSizeTrigger = 450;
+  fCodaOut = 0;
+  fLastEventWasSync = kFALSE;
 }
 
 THcTimeSyncEvtHandler::~THcTimeSyncEvtHandler()
@@ -55,16 +73,29 @@ THcTimeSyncEvtHandler::~THcTimeSyncEvtHandler()
 Int_t THcTimeSyncEvtHandler::Analyze(THaEvData *evdata)
 {
 
-  if ( !IsMyEvent(evdata->GetEvType()) ) return -1;
+  //  cout << evdata->GetEvType() << " " << evdata->GetEvLength() << endl;
+
+  // If filtering data file, pass through all events we are not dealing with
+  if ( !IsMyEvent(evdata->GetEvType()) ) {
+    if(fCodaOut) {
+      fCodaOut->codaWrite(evdata->GetRawDataBuffer());
+    }
+    return -1;
+  }
+
 
   if (fDebug) cout << "------------------\n  Time Syncronization Checker"<<endl;
 
   Int_t evlen = evdata->GetEvLength();
+
   UInt_t *rdata = (UInt_t*) evdata->GetRawDataBuffer();
 
+  UInt_t *pslippedbank=0;
+
   UInt_t *p = (UInt_t*) rdata;
   UInt_t *plast = p+*p;		// Index to last word in the bank
   Int_t roc = -1;
+  Bool_t issyncevent=kFALSE;
 
   CrateTimeMap.clear();
 
@@ -87,6 +118,7 @@ Int_t THcTimeSyncEvtHandler::Analyze(THaEvData *evdata)
       // a bank within a ROC containing data from modules of a single type
       // Look for TI and FADC banks.
       UInt_t tag = (*p>>16) & 0xffff;
+      UInt_t num = *p & 0xff;
       UInt_t *pnext = p+banklen;	// Next bank
       p++;			// First data word
       if(tag==4) { // This is a TI blob banks
@@ -96,13 +128,18 @@ Int_t THcTimeSyncEvtHandler::Analyze(THaEvData *evdata)
         if(ifill) {
           p++; banklen--;  // Skip filler word
         }
+	CrateTimeMap[roc]->ti_evcount = p[3];
         if(banklen>=5) {   // Need bank header, at least 2 TI  headers, the  trailer and 2 data words
           UInt_t titime = p[4];
 	  if(fDebug) cout << roc << ": TItime " << titime << endl;
           CrateTimeMap[roc]->has_ti_ttime = kTRUE;
           CrateTimeMap[roc]->ti_ttime = titime;
         }
-      } else if (tag==250) { // This is an FADC banks
+      } else if (tag==3801) {
+	if(fResync && num==1) {
+	  issyncevent = kTRUE;
+	}
+      } else if (tag==250) { // This is an FADC bank
 	if(fDebug) cout << roc << ": FADC" << endl;
         // Walk through this bank looking for FADC headers.
         Int_t slot=-1;
@@ -117,7 +154,7 @@ Int_t THcTimeSyncEvtHandler::Analyze(THaEvData *evdata)
 	    {
 	      UInt_t fadctime = ((*p)&0xFFFFFF) + (((*(p+1))&0xFF)<<24);
 	      if(fDebug) cout << "    " << slot << ": " << fadctime << endl;
-        CrateTimeMap[roc]->fadcTimesMap[slot] = fadctime;
+	      CrateTimeMap[roc]->fadcTimesMap[slot] = fadctime;
 	      p += 2;
 	      break;
 	    }
@@ -126,6 +163,28 @@ Int_t THcTimeSyncEvtHandler::Analyze(THaEvData *evdata)
 	    break;
 	  }
 	}
+      } else if (tag==1190) {	// Bank with CAEN 1190 TDCs
+	if(roc==fBadROC) {		// Point to slipped bank
+	  if(fSlippage) {
+	    pslippedbank = p-2;
+	    //	    cout << banklen << " " << pslippedbank[0] << endl;
+	  } else {
+	    if(banklen > fBadSyncSizeTrigger) {
+	      cout << "Slippage enabled at event " << evdata->GetEvNum() << endl;
+	      fSlippage = 1;
+	    }
+	  }
+	}
+	if(fDebug) cout << roc << ": 1190" << endl;
+	// Walk through this bank looking for TDC headers
+	while(p<pnext) {
+	  if((*p & 0xf8000000) == 0x40000000) {
+	    Int_t slot= *p & 0x1f;
+	    Int_t evcount = (*p >> 5) & 0x3fffff;
+	    CrateTimeMap[roc]->ftdcEvCountMap[slot] = evcount;
+	  }
+	  p++;
+	}
       }
       p=pnext;    // Skip to next bank
     } else {
@@ -135,9 +194,140 @@ Int_t THcTimeSyncEvtHandler::Analyze(THaEvData *evdata)
 
   if(fFirstTime) {
     InitStats();
+    fLastEvent[0] = 0;
     fFirstTime = kFALSE;
+    fDumpNew=2;
+  }
+  if(issyncevent) cout << "SYNC event" << endl;
+  AccumulateStats(fLastEventWasSync);
+  fLastEventWasSync = issyncevent;
+
+  if(!fCodaOut) return(1);
+  
+  if(fSlippage > 0) {
+    if(fLastEvent[0]>0) { // Now slipping.  Output corrected event
+      fWriteDelayed=kTRUE;
+      //      cout << "Will write corrected event" << endl;
+    } else {
+      cout << "Skipping event " << evdata->GetEvNum() << endl;
+    }
+  } else {			// Not slipping yet, just copy event
+    if(fCodaOut) {
+      fCodaOut->codaWrite(evdata->GetRawDataBuffer());
+    }
+  }    
+
+  if(fWriteDelayed) {
+
+    // Dump event before fixing
+    //    if(fDumpNew > 0) {
+    //      cout << "Unmodified event" << endl;
+    //      for(UInt_t i=0;i<=fLastEvent[0];i++) {
+    //	if(i%5 == 0) cout<<endl<<dec<<i<<": ";
+    //	cout << hex << setw(10) << fLastEvent[i];
+    //      }
+    //    }
+    //    cout << dec << endl;
+
+    // Use fLastEvent with current pslipped bank to write out fixed event
+    // Find the 1190 bank.  Shift everything beyond that bank forward or
+    // or back to make room for the 1190 bank from the current event.
+    // Copy the current 1190 bank into fLastEvent.  Write the event.
+    p = fLastEvent;
+    plast = p+*p;
+    roc = -1;
+    UInt_t *poverwrite=0;
+    Int_t replacementlen;
+    Int_t banklen;
+    UInt_t *rocbanklenp=0;
+    UInt_t *roc3banklenp=0;
+
+    //    cout << "Old Size: " << fLastEvent[0] << " " << pslippedbank[0] << " ";
+    while(p<plast) {
+      banklen = *p;
+      p++;
+      if((*p & 0xff00) == 0x1000) {	// Bank Containing banks
+	if((fLastEvent[0]+1)-*(p-1) > 1) { // Don't use overall event header
+	  roc = (*p>>16) & 0xf;
+	  rocbanklenp = p-1;	// Pointer to rocbank length
+	}
+      p++;				// Now pointing to a bank in the bank
+      } else if (((*p & 0xff00) == 0x100) && (*p != 0xC0000100)) {
+	// Bank containing integers.
+	// This is either ROC bank containing integers or
+	// a bank within a ROC containing data from modules of a single type
+	// Look for TI and FADC banks.
+	UInt_t tag = (*p>>16) & 0xffff;
+	UInt_t *pnext = p+banklen;	// Next bank
+	p++;			// First data word
+	if(tag==1190 && roc==fBadROC) { // The TDC bank we want to replace
+	  replacementlen=pslippedbank[0];
+	  roc3banklenp=rocbanklenp; // Save pointer to ROC bank header
+	  poverwrite=p-2;	// Where to write the slipped bank
+	  break;
+	}
+	p=pnext;
+      } else {
+	p=p+*(p-1);
+      }
+    }
+    Int_t icopied=0;
+    if(poverwrite) {
+      //      cout << banklen << endl;
+      if(replacementlen < banklen) { // Shift data after bank down
+	p = poverwrite+banklen+1;    // Data to be shifted
+	//	cout << "Shifting " << (p-fLastEvent) << " to " << (p+replacementlen-banklen-fLastEvent) << endl;
+	while(p<=plast) {
+	  //	  cout << (p+replacementlen-banklen-fLastEvent) << ": " << hex << *p << dec << endl;
+	  *(p + replacementlen - banklen) = *p;
+	  p++;
+	  icopied++;
+	}
+      } else if (replacementlen > banklen) { // Shift data up
+	p = plast;
+	//	UInt_t *pfirst = poverwrite + replacementlen + 1;
+	UInt_t *pfirst = poverwrite + banklen + 1;
+	//	cout << "Shifting " << (plast-pfirst+1) << " words " << (pfirst-fLastEvent) << " to " << (pfirst+replacementlen-banklen-fLastEvent) << endl;
+	while(p>=pfirst) {
+	  //	  cout << (p+replacementlen-banklen-fLastEvent) << ": " << hex << *p << dec << endl;
+	  *(p+replacementlen-banklen) = *p;
+	  p--;
+	  icopied++;
+	}
+      }
+      fLastEvent[0] += replacementlen-banklen; // Correct overall event length
+      *roc3banklenp += replacementlen-banklen; // Also ROC3 bank length
+      //      cout << "Copying " << replacementlen+1 << " words of new bank to " << poverwrite-fLastEvent << endl;
+      for(Int_t i=0;i<=replacementlen;i++) { // Copy slipped bank into last event
+	poverwrite[i] = pslippedbank[i];
+      }
+    }
+    //    cout << "New Size: " << fLastEvent[0] << "   copied " << icopied << endl;
+    if(fCodaOut) {
+      //      if(fDumpNew > 0) {
+      //	for(UInt_t i=0;i<=fLastEvent[0];i++) {
+      //	  if(i%5 == 0) cout<<endl<<dec<<i<<": ";
+      //	  cout << hex << setw(10) << fLastEvent[i];
+      //	}
+      //	fDumpNew--;
+      //      }
+      //      cout << dec << endl;
+      fCodaOut->codaWrite(fLastEvent);
+      if(issyncevent) {		// If this was a sync event, write it out and stop rewriting
+	cout << "Run back in sync at event " << evdata->GetEvNum() << endl;
+	fCodaOut->codaWrite(evdata->GetRawDataBuffer());
+	fSlippage = 0;
+	fLastEvent[0] = 0;
+	fWriteDelayed = kFALSE;
+      }
+    }
+  }
+  if(fSlippage>0) {		// Just handle slippage of 1 now
+    for(UInt_t i=0;i<=rdata[0];i++) {
+      fLastEvent[i]=rdata[i];
+    }
+    //    cout << "Cached event " << evdata->GetEvNum() << " " << fLastEvent[0] << endl;
   }
-  AccumulateStats();
 
   return 1;
 }
@@ -186,10 +376,19 @@ void THcTimeSyncEvtHandler::InitStats() {
         CrateStatsMap[roc]->fadcLateSlipCountMap[slot] = 0;
       }
     }
+    if(roctimes->ftdcEvCountMap.size()>0) {
+      if(fDebug) cout << endl << " 1190";
+      std::map<Int_t, UInt_t>::iterator itt = roctimes->ftdcEvCountMap.begin();
+      while(itt != roctimes->ftdcEvCountMap.end()) {
+        Int_t slot = itt->first;
+	itt++;
+	CrateStatsMap[roc]->ftdcEvCountWrongMap[slot] = 0;
+      }
+    }
   }
 }
 
-void THcTimeSyncEvtHandler::AccumulateStats() {
+void THcTimeSyncEvtHandler::AccumulateStats(Bool_t sync) {
   fNEvents++;
   // Get trigger time from master CrateInfo
   UInt_t master_ttime = CrateTimeMap[fMasterRoc]->ti_ttime;
@@ -216,6 +415,28 @@ void THcTimeSyncEvtHandler::AccumulateStats() {
         }
       }
     }
+    if(rocstats->ftdcEvCountWrongMap.size()>0) {
+      std::map<Int_t, Int_t>::iterator itt = rocstats->ftdcEvCountWrongMap.begin();
+      while(itt != rocstats->ftdcEvCountWrongMap.end()) {
+	Int_t slot = itt->first;
+	itt++;
+	if(rocstats->ftdcEvCountOffsetMap.find(slot)==rocstats->ftdcEvCountOffsetMap.end()) {
+	  rocstats->ftdcEvCountOffsetMap[slot] = 1;
+	}
+	Int_t cdiff = (CrateTimeMap[roc]->ti_evcount & 0x3fffff) -
+	  ((CrateTimeMap[roc]->ftdcEvCountMap[slot]+rocstats->ftdcEvCountOffsetMap[slot])&0x3fffff);
+	if(sync) { // Need to do this check on the event after the sync event too
+	  if(cdiff>2) {
+	    cout << "ROC/Slot " << roc << "/" << slot << " count diff correction " << cdiff << endl;
+	    rocstats->ftdcEvCountOffsetMap[slot] += cdiff;
+	    cdiff = 0;
+	  }
+	}
+	if(cdiff != 0) {
+	  rocstats->ftdcEvCountWrongMap[slot]++;
+	}
+      }
+    }
   }
 }
 void THcTimeSyncEvtHandler::PrintStats()
@@ -244,6 +465,16 @@ void THcTimeSyncEvtHandler::PrintStats()
 	cout << "    " << slot << " " << rocstats->fadcOffsetMap[slot] << "    " << earlyslips << "    " << lateslips << endl;
       }
     }
+    std::map<Int_t, Int_t>::iterator itw = rocstats->ftdcEvCountWrongMap.begin();
+    while(itw != rocstats->ftdcEvCountWrongMap.end()) {
+      Int_t slot = itw->first;
+      Int_t wrongcount = itw->second;
+      itw++;
+      if(wrongcount > 0) {
+	cout << "    " << slot << " " << wrongcount << endl;
+      }
+    }
+	
   }
   cout << "-------------------------------------------------------------------" << endl;
 }
@@ -261,17 +492,58 @@ THaAnalysisObject::EStatus THcTimeSyncEvtHandler::Init(const TDatime& date)
   cout << "Howdy !  We are initializing THcTimeSyncEvtHandler !!   name =   "<<fName<<endl;
 
   if(eventtypes.size()==0) {
-    eventtypes.push_back(125);  // what events to look for
+    eventtypes.push_back(1);  // If no event types specified, 
+    eventtypes.push_back(2);  // check timestamp synchronization on these event types
+    eventtypes.push_back(3);
+    eventtypes.push_back(4);
+    eventtypes.push_back(5);
+    eventtypes.push_back(6);
+    eventtypes.push_back(7);
   }
 
   fFirstTime = kTRUE;
   fMasterRoc = -1;
   fNEvents = 0;
   CrateTimeMap.clear();
+  fSlippage=0;
+  fWriteDelayed=kFALSE;
+  fLastEvent[0]=0;
   //CrateStatsMap.clear();
+  if(fCodaOut && fBadROC < 0) {
+    Warning(Here("Init"), "Sync filtering requested, but bad ROC not specified");
+  }
 
   fStatus = kOK;
   return kOK;
 }
 
+Int_t THcTimeSyncEvtHandler::End( THaRunBase* r) {
+  if(!fCodaOut) {
+    return 0;
+  }
+  return fCodaOut->codaClose();
+}
+
+Int_t THcTimeSyncEvtHandler::SetRewriteFile(const char *filename) {
+  if(filename==0 || strlen(filename)==0) {
+    fCodaOut = 0;
+    cout << "THcTimeSyncEvtHandler sync filtering disabled" << endl;
+  } else {
+    TString ts=filename;
+    fCodaOut = new THaCodaFile;
+    if (!fCodaOut) {
+      Error(Here("SetRewriteFile"),"Cannot create CODA output file object. "
+	    "Something is very wrong." );
+      return -2;
+    }
+    if ( fCodaOut->codaOpen(ts, "w", 1) ) {
+      Error(Here("SetRewriteFile"),"Cannot open CODA file %s for writing.",ts.Data());
+      return -3;
+    }
+    cout << "THcTimeSYncEvtHandler writing sync filtered coda file to " << ts <<endl;
+  }
+  return(0);
+}
+
+
 ClassImp(THcTimeSyncEvtHandler)
diff --git a/src/THcTimeSyncEvtHandler.h b/src/THcTimeSyncEvtHandler.h
index ccb3b3c5840f5c17d8f45409619b8bda5081b268..53b388012e3b7868025d80d08df0124ef4c654a6 100644
--- a/src/THcTimeSyncEvtHandler.h
+++ b/src/THcTimeSyncEvtHandler.h
@@ -8,10 +8,14 @@
 /////////////////////////////////////////////////////////////////////
 
 #include "THaEvtTypeHandler.h"
+#include "Decoder.h"
 #include <string>
 #include <vector>
 #include <map>
 
+//class THaRunBase;
+//class THaEvData;
+
 class THcTimeSyncEvtHandler : public THaEvtTypeHandler {
 
 public:
@@ -24,23 +28,43 @@ public:
   virtual void PrintStats();
   virtual void SetExpectedOffset(Int_t roc, Int_t offset);
   virtual void AddExpectedOffset(Int_t roc, Int_t offset);
-
- //  Float_t GetData(const std::string& tag);
+  virtual Int_t End( THaRunBase* r=0 );
+  virtual Int_t SetRewriteFile(const char *filename);
+  virtual void SetBadROC(Int_t roc) {fBadROC = roc;}
+  virtual void SetResync(Bool_t b) {fResync = b;}
+  virtual void SetBadSyncSizeTrigger(Int_t sizetrigger) {fBadSyncSizeTrigger = sizetrigger;}
 
 private:
 
   virtual void InitStats();
-  virtual void AccumulateStats();
+  virtual void AccumulateStats(Bool_t sync);
 
   Bool_t fFirstTime;
   Int_t fMasterRoc; // ROC with the TI master
   Int_t fNEvents;   // Number of events analyzed
+  Int_t fSlippage;
+  UInt_t fLastEvent[32000];
+  UInt_t fSlippingBank[32000];
+  Bool_t fWriteDelayed;
+  Int_t fDumpNew;
+  Int_t fBadROC;		// ROC to check and filter sync problems
+  Bool_t fResync;		// If true, stop correcting events on sync
+  Int_t fBadSyncSizeTrigger;
+  Bool_t fLastEventWasSync;	// True when last event was sync event
+
+  Decoder::THaCodaFile* fCodaOut; // The CODA output file
+  Int_t handle;
 
   typedef struct RocTimes {
     Bool_t has_ti_ttime;
     UInt_t ti_ttime;
+    UInt_t ti_evcount;
     std::map<Int_t, UInt_t> fadcTimesMap;
-    RocTimes() : has_ti_ttime(kFALSE) {fadcTimesMap.clear();}
+    std::map<Int_t, UInt_t> ftdcEvCountMap;
+    RocTimes() : has_ti_ttime(kFALSE) {
+      fadcTimesMap.clear();
+      ftdcEvCountMap.clear();
+    }
   } RocTimes_t;
 
   typedef struct RocStats {
@@ -51,12 +75,16 @@ private:
     std::map<Int_t, Int_t> fadcOffsetMap;
     std::map<Int_t, Int_t> fadcEarlySlipCountMap;
     std::map<Int_t, Int_t> fadcLateSlipCountMap;
+    std::map<Int_t, Int_t> ftdcEvCountWrongMap;
+    std::map<Int_t, Int_t> ftdcEvCountOffsetMap;
     RocStats() : ti_ttime_offset(0), ti_earlyslipcount(0), ti_lateslipcount(0),
       fadc_expected_offset(0)
     {
       fadcOffsetMap.clear();
       fadcEarlySlipCountMap.clear();
       fadcLateSlipCountMap.clear();
+      ftdcEvCountWrongMap.clear();
+      ftdcEvCountOffsetMap.clear();
     }
   } RocStats_t;