diff --git a/sleepyhead/SleepLib/calcs.cpp b/sleepyhead/SleepLib/calcs.cpp
index 5d678190..2702a711 100644
--- a/sleepyhead/SleepLib/calcs.cpp
+++ b/sleepyhead/SleepLib/calcs.cpp
@@ -223,7 +223,7 @@ void FlowParser::openFlow(Session *session, EventList *flow)
     EventStoreType *eptr = inraw + m_samples;
 
     // Convert from store type to floats..
-    for (; inraw < eptr; inraw++) {
+    for (; inraw < eptr; ++inraw) {
         *buf++ = EventDataType(*inraw) * m_gain;
     }
 
@@ -437,10 +437,19 @@ void FlowParser::calc(bool calcResp, bool calcTv, bool calcTi, bool calcTe, bool
 
     qint32 timeval = 0; // Time relative to start
 
-    for (idx = 0; idx < nm; idx++) {
-        bs = breaths[idx].start;
-        bm = breaths[idx].middle;
-        be = breaths[idx].end;
+
+
+    BreathPeak * bpstr = breaths.data();
+    BreathPeak * bpend = bpstr + nm;
+    for (BreathPeak * bp = bpstr; bp != bpend; ++bp) {
+        bs = bp->start;
+        bm = bp->middle;
+        be = bp->end;
+
+//    for (idx = 0; idx < nm; idx++) {
+//        bs = breaths[idx].start;
+//        bm = breaths[idx].middle;
+//        be = breaths[idx].end;
 
         // Calculate start, middle and end time of this breath
         st = start + bs * m_rate;
@@ -524,9 +533,13 @@ void FlowParser::calc(bool calcResp, bool calcTv, bool calcTi, bool calcTe, bool
             //et2=et;
 
             // Step back through last minute and count breaths
-            for (int i = idx; i >= 0; i--) {
-                st2 = start + double(breaths[i].start) * m_rate;
-                et2 = start + double(breaths[i].end) * m_rate;
+            BreathPeak *bpstr1 = bpstr-1;
+            for (BreathPeak *p = bp; p != bpstr1; --p) {
+                st2 = start + double(p->start) * m_rate;
+                et2 = start + double(p->end) * m_rate;
+//            for (int i = idx; i >= 0; i--) {
+//                st2 = start + double(breaths[i].start) * m_rate;
+//                et2 = start + double(breaths[i].end) * m_rate;
 
                 if (et2 < stmin) {
                     break;
@@ -631,13 +644,21 @@ void FlowParser::flagEvents()
 
     bool allowDuplicates = PROFILE.cpap->userEventDuplicates();
 
-    for (int i = 0; i < numbreaths; i++) {
-        mx = breaths[i].max;
-        mn = breaths[i].min;
-        br.push_back(qAbs(mx));
-        br.push_back(qAbs(mn));
+    BreathPeak *bpstr = breaths.data();
+    BreathPeak *bpend = bpstr + numbreaths;
+
+    for (BreathPeak *p = bpstr; p != bpend; ++p) {
+        br.push_back(qAbs(p->max));
+        br.push_back(qAbs(p->min));
     }
 
+//    for (int i = 0; i < numbreaths; i++) {
+//        mx = breaths[i].max;
+//        mn = breaths[i].min;
+//        br.push_back(qAbs(mx));
+//        br.push_back(qAbs(mn));
+//    }
+
     //EventList * uf2=m_session->AddEventList(CPAP_UserFlag2,EVL_Event);
     //EventList * uf3=m_session->AddEventList(CPAP_UserFlag3,EVL_Event);
 
@@ -651,13 +672,19 @@ void FlowParser::flagEvents()
 
     int bs, bm, be, bs1, bm1, be1;
 
-    for (int i = 0; i < numbreaths; i++) {
-        bs = breaths[i].start;
-        bm = breaths[i].middle;
-        be = breaths[i].end;
+    for (BreathPeak *p = bpstr; p != bpend; ++p) {
+        bs = p->start;
+        bm = p->middle;
+        be = p->end;
+        mx = p->max;
+        mn = p->min;
+//    for (int i = 0; i < numbreaths; i++) {
+//        bs = breaths[i].start;
+//        bm = breaths[i].middle;
+//        be = breaths[i].end;
 
-        mx = breaths[i].max;
-        mn = breaths[i].min;
+//        mx = breaths[i].max;
+//        mn = breaths[i].min;
         val = mx - mn;
 
         //        if (qAbs(mx) > cutoffval) {
@@ -779,8 +806,8 @@ void calcRespRate(Session *session, FlowParser *flowparser)
         }
 
         QVector<EventList *> &list = session->eventlist[CPAP_RespRate];
-
-        for (int i = 0; i < list.size(); i++) {
+        int size = list.size();
+        for (int i = 0; i < size; ++i) {
             delete list[i];
         }
 
@@ -788,7 +815,8 @@ void calcRespRate(Session *session, FlowParser *flowparser)
 
         QVector<EventList *> &list2 = session->eventlist[CPAP_TidalVolume];
 
-        for (int i = 0; i < list2.size(); i++) {
+        size = list2.size();
+        for (int i = 0; i < size; ++i) {
             delete list2[i];
         }
 
@@ -796,7 +824,8 @@ void calcRespRate(Session *session, FlowParser *flowparser)
 
         QVector<EventList *> &list3 = session->eventlist[CPAP_MinuteVent];
 
-        for (int i = 0; i < list3.size(); i++) {
+        size = list3.size();
+        for (int i = 0; i < size; ++i) {
             delete list3[i];
         }
 
@@ -813,8 +842,11 @@ void calcRespRate(Session *session, FlowParser *flowparser)
     //flowparser->addFilter(FilterXPass,0.5);
     EventList *flow;
 
-    for (int ws = 0; ws < session->eventlist[CPAP_FlowRate].size(); ws++) {
-        flow = session->eventlist[CPAP_FlowRate][ws];
+    QVector<EventList *> &EVL = session->eventlist[CPAP_FlowRate];
+    int size = EVL.size();
+
+    for (int ws = 0; ws < size; ++ws) {
+        flow = EVL[ws];
 
         if (flow->count() > 20) {
             flowparser->openFlow(session, flow);
@@ -1157,23 +1189,26 @@ void zMaskProfile::scanPressure(Session *session)
         prescnt = session->count(CPAP_Pressure);
         Pressure.reserve(prescnt);
 
-        for (int j = 0; j < session->eventlist[CPAP_Pressure].size(); j++) {
-            QVector<EventList *> &el = session->eventlist[CPAP_Pressure];
+        // WTF IS THIS DOING??? WHY THE HECK DID I PUT AN INNER LOOP HERE??
+        QVector<EventList *> &EVL=session->eventlist[CPAP_Pressure];
+        int size = EVL.size();
+        for (int j = 0; j < size; ++j) {
+            scanPressureList(EVL[j]);
+//            QVector<EventList *> &el = session->eventlist[CPAP_Pressure];
 
-            for (int e = 0; e < el.size(); e++) {
-                scanPressureList(el[e]);
-            }
+//            for (int e = 0; e < el.size(); e++) {
+//                scanPressureList(el[e]);
+//            }
         }
     } else if (session->eventlist.contains(CPAP_IPAP)) {
         prescnt = session->count(CPAP_IPAP);
         Pressure.reserve(prescnt);
 
-        for (int j = 0; j < session->eventlist[CPAP_IPAP].size(); j++) {
-            QVector<EventList *> &el = session->eventlist[CPAP_IPAP];
+        QVector<EventList *> &EVL=session->eventlist[CPAP_IPAP];
+        int size = EVL.size();
 
-            for (int e = 0; e < el.size(); e++) {
-                scanPressureList(el[e]);
-            }
+        for (int j = 0; j < size; ++j) {
+            scanPressureList(EVL[j]);
         }
     }
 
@@ -1195,6 +1230,12 @@ void zMaskProfile::scanLeakList(EventList *el)
     qint64 ti;
     bool found;
 
+    int psize = Pressure.size();
+    if (psize == 0) return;
+    TimeValue *tvstr = Pressure.data();
+    TimeValue *tvend = tvstr + (psize - 1);
+    TimeValue *p1, *p2;
+
     for (; dptr < eptr; dptr++) {
         leak = *dptr;
         ti = start + *tptr++;
@@ -1202,20 +1243,34 @@ void zMaskProfile::scanLeakList(EventList *el)
         found = false;
         pressure = Pressure[0].value;
 
-        if (Pressure.size() > 1) {
-            for (int i = 0; i < Pressure.size() - 1; i++) {
-                const TimeValue &p1 = Pressure[i];
-                const TimeValue &p2 = Pressure[i + 1];
+        if (psize > 1) {
+            for (p1 = tvstr; p1 != tvend; ++p1) {
+                p2 = p1+1;
 
-                if ((p2.time > ti) && (p1.time <= ti)) {
-                    pressure = p1.value;
+                if ((p2->time > ti) && (p1->time <= ti)) {
+                    pressure = p1->value;
                     found = true;
                     break;
-                } else if (p2.time == ti) {
-                    pressure = p2.value;
+                } else if (p2->time == ti) {
+                    pressure = p2->value;
                     found = true;
                     break;
                 }
+
+
+//            for (int i = 0; i < Pressure.size() - 1; i++) {
+//                const TimeValue &p1 = Pressure[i];
+//                const TimeValue &p2 = Pressure[i + 1];
+
+//                if ((p2.time > ti) && (p1.time <= ti)) {
+//                    pressure = p1.value;
+//                    found = true;
+//                    break;
+//                } else if (p2.time == ti) {
+//                    pressure = p2.value;
+//                    found = true;
+//                    break;
+//                }
             }
         } else {
             found = true;
@@ -1245,8 +1300,14 @@ void zMaskProfile::scanLeaks(Session *session)
 {
     QVector<EventList *> &elv = session->eventlist[CPAP_LeakTotal];
 
-    for (int i = 0; i < elv.size(); i++) {
-        scanLeakList(elv[i]);
+    int size=elv.size();
+    if (!size)
+        return;
+
+    QVector<EventList *>::iterator end = elv.end();
+    QVector<EventList *>::iterator it;
+    for (it = elv.begin(); it != end; ++it) {
+        scanLeakList(*it);
     }
 }
 void zMaskProfile::updatePressureMin()
@@ -1266,14 +1327,19 @@ void zMaskProfile::updatePressureMin()
 
     int sum1, sum2, w1, w2, N, k;
 
-    for (it = pressureleaks.begin(); it != pressureleaks.end(); it++) {
+
+    QMap<EventStoreType, QMap<EventStoreType, quint32> >::iterator plend = pressureleaks.end();
+
+    QMap<EventStoreType, quint32>::iterator lmend;
+    for (it = pressureleaks.begin(); it != plend; it++) {
         pressure = it.key();
         QMap<EventStoreType, quint32> &leakmap = it.value();
         lks = leakmap.size();
         SN = 0;
 
         // First sum total counts of all leaks
-        for (QMap<EventStoreType, quint32>::iterator lit = leakmap.begin(); lit != leakmap.end(); lit++) {
+        lmend = leakmap.end();
+        for (QMap<EventStoreType, quint32>::iterator lit = leakmap.begin(); lit != lmend; ++lit) {
             SN += lit.value();
         }
 
@@ -1292,15 +1358,14 @@ void zMaskProfile::updatePressureMin()
         bool found = false;
         double total = 0;
 
-        for (QMap<EventStoreType, quint32>::iterator lit = leakmap.begin(); lit != leakmap.end();
-                lit++, k++) {
+        // why do this effectively twice? and k = size
+        for (QMap<EventStoreType, quint32>::iterator lit = leakmap.begin(); lit != lmend; ++lit, ++k) {
             total += lit.value();
         }
 
         pressuretotal[pressure] = total;
 
-        for (QMap<EventStoreType, quint32>::iterator lit = leakmap.begin(); lit != leakmap.end();
-                lit++, k++) {
+        for (QMap<EventStoreType, quint32>::iterator lit = leakmap.begin(); lit != lmend; ++lit, ++k) {
             //for (k=0;k < N;k++) {
             v1 = lit.key();
             w1 = lit.value();
@@ -1379,8 +1444,13 @@ void zMaskProfile::updateProfile(Session *session)
 
     EventDataType maxcnt, maxval, lastval, lastcnt;
 
-    for (QMap<EventStoreType, QMap<EventStoreType, quint32> >::iterator it = pressureleaks.begin();
-            it != pressureleaks.end(); it++)  {
+
+    QMap<EventStoreType, QMap<EventStoreType, quint32> >::iterator plend = pressureleaks.end();
+    QMap<EventStoreType, QMap<EventStoreType, quint32> >::iterator it = pressureleaks.begin();
+
+    QMap<EventStoreType, quint32>::iterator lit;
+    QMap<EventStoreType, quint32>::iterator lvend;
+    for (; it != plend; ++it) {
         p = it.key();
         l = pressuremin[p];
         QMap<EventStoreType, quint32> &leakval = it.value();
@@ -1391,7 +1461,8 @@ void zMaskProfile::updateProfile(Session *session)
 
         maxcnt = 0, maxval = 0, lastval = 0, lastcnt = 0;
 
-        for (QMap<EventStoreType, quint32>::iterator lit = leakval.begin(); lit != leakval.end(); lit++) {
+        lvend = leakval.end();
+        for (lit = leakval.begin(); lit != lvend; ++lit) {
             cnt += lit.value();
 
             if (lit.value() > maxcnt) {
@@ -1418,7 +1489,7 @@ void zMaskProfile::updateProfile(Session *session)
         pressuremax[p] = lastval;
         sum = 0;
 
-        for (QMap<EventStoreType, quint32>::iterator lit = leakval.begin(); lit != leakval.end(); lit++) {
+        for (lit = leakval.begin(); lit != lvend; lit++) {
             tmp = lit.key() - mean;
             sum += tmp * tmp;
         }
@@ -1435,16 +1506,16 @@ void zMaskProfile::updateProfile(Session *session)
     QMap<EventStoreType, EventDataType> pressureval2;
     EventDataType max = 0, tmp2, tmp3;
 
-    for (QMap<EventStoreType, EventDataType>::iterator it = pressuretotal.begin();
-            it != pressuretotal.end(); it++) {
-        if (max < it.value()) { max = it.value(); }
+    QMap<EventStoreType, EventDataType>::iterator ptit;
+    QMap<EventStoreType, EventDataType>::iterator ptend = pressuretotal.end();
+    for (ptit = pressuretotal.begin(); ptit != ptend; ++ptit) {
+        if (max < ptit.value()) { max = ptit.value(); }
     }
 
-    for (QMap<EventStoreType, EventDataType>::iterator it = pressuretotal.begin();
-            it != pressuretotal.end(); it++) {
-        p = it.key();
+    for (ptit = pressuretotal.begin(); ptit != pressuretotal.end(); ptit++) {
+        p = ptit.key();
         tmp = pressurecount[p];
-        tmp2 = it.value();
+        tmp2 = ptit.value();
 
         tmp3 = (tmp / tmp2) * (tmp2 / max);
 
@@ -1546,8 +1617,18 @@ int calcLeaks(Session *session)
 
     EventList *leak = session->AddEventList(CPAP_Leak, EVL_Event, 1);
 
-    for (int i = 0; i < session->eventlist[CPAP_LeakTotal].size(); i++) {
-        EventList &el = *session->eventlist[CPAP_LeakTotal][i];
+    QVector<EventList *> & EVL = session->eventlist[CPAP_LeakTotal];
+    int evlsize = EVL.size();
+
+    TimeValue *p2, *pstr, *pend;
+
+    // can this go out of the loop?
+    int mppressize = maskProfile->Pressure.size();
+    pstr = maskProfile->Pressure.data();
+    pend = maskProfile->Pressure.data()+(mppressize-1);
+
+    for (int i = 0; i < evlsize; ++i) {
+        EventList &el = *EVL[i];
         EventDataType gain = el.gain(), tmp, val;
         int count = el.count();
         EventStoreType *dptr = el.rawData();
@@ -1560,28 +1641,41 @@ int calcLeaks(Session *session)
 
         bool found;
 
-        for (; dptr < eptr; dptr++) {
+        for (; dptr < eptr; ++dptr) {
             tmp = EventDataType(*dptr) * gain;
             ti = start + *tptr++;
 
             found = false;
-            pressure = maskProfile->Pressure[0].value;
+            pressure = pstr->value;
 
-            for (int i = 0; i < maskProfile->Pressure.size() - 1; i++) {
-                const TimeValue &p1 = maskProfile->Pressure[i];
-                const TimeValue &p2 = maskProfile->Pressure[i + 1];
-
-                if ((p2.time > ti) && (p1.time <= ti)) {
-                    pressure = p1.value;
+            for (TimeValue *p1 = pstr; p1 != pend; ++p1) {
+                p2 = p1+1;
+                if ((p2->time > ti) && (p1->time <= ti)) {
+                    pressure = p1->value;
                     found = true;
                     break;
-                } else if (p2.time == ti) {
-                    pressure = p2.value;
+                } else if (p2->time == ti) {
+                    pressure = p2->value;
                     found = true;
                     break;
                 }
             }
 
+//            for (int i = 0; i < mppressize - 1; ++i) {
+//                const TimeValue &p1 = &maskProfile->Pressure[i];
+//                const TimeValue &p2 = maskProfile->Pressure[i + 1];
+
+//                if ((p2.time > ti) && (p1.time <= ti)) {
+//                    pressure = p1.value;
+//                    found = true;
+//                    break;
+//                } else if (p2.time == ti) {
+//                    pressure = p2.value;
+//                    found = true;
+//                    break;
+//                }
+//            }
+
             if (found) {
                 val = tmp - maskProfile->calcLeak(pressure);
 
@@ -1622,10 +1716,12 @@ int calcPulseChange(Session *session)
 
     int max;
 
-    for (int e = 0; e < it.value().size(); e++) {
+    int size = it.value().size();
+    for (int e = 0; e < size; ++e) {
         EventList &el = *(it.value()[e]);
 
-        for (unsigned i = 0; i < el.count(); i++) {
+        int elcount=el.count();
+        for (int i = 0; i < elcount; ++i) {
             val = el.data(i);
             time = el.time(i);
 
@@ -1634,7 +1730,7 @@ int calcPulseChange(Session *session)
             lv = change;
             max = 0;
 
-            for (unsigned j = i + 1; j < el.count(); j++) { // scan ahead in the window
+            for (int j = i + 1; j < elcount; ++j) { // scan ahead in the window
                 time2 = el.time(j);
 
                 if (time2 > time + window) { break; }
@@ -1709,10 +1805,12 @@ int calcSPO2Drop(Session *session)
     // Calculate median baseline
     QList<EventDataType> med;
 
-    for (int e = 0; e < it.value().size(); e++) {
+    int evsize = it.value().size();
+    for (int e = 0; e < evsize; ++e) {
         EventList &el = *(it.value()[e]);
 
-        for (unsigned i = 0; i < el.count(); i++) {
+        int elcount = el.count();
+        for (int i = 0; i < elcount; i++) {
             val = el.data(i);
             time = el.time(i);
 
@@ -1746,10 +1844,11 @@ int calcSPO2Drop(Session *session)
     EventDataType current;
     qDebug() << "Calculated baseline" << baseline;
 
-    for (int e = 0; e < it.value().size(); e++) {
+    for (int e = 0; e < evsize; ++e) {
         EventList &el = *(it.value()[e]);
 
-        for (unsigned i = 0; i < el.count(); i++) {
+        int elcount = el.count();
+        for (int i = 0; i < elcount; ++i) {
             current = el.data(i);
 
             if (!current) { continue; }
@@ -1785,7 +1884,7 @@ int calcSPO2Drop(Session *session)
 
             min = val;
 
-            for (unsigned j = i; j < el.count(); j++) { // scan ahead in the window
+            for (int j = i; j < elcount; ++j) { // scan ahead in the window
                 time2 = el.time(j);
                 //if (time2 > time+window) break;
                 val2 = el.data(j);
diff --git a/sleepyhead/SleepLib/loader_plugins/icon_loader.cpp b/sleepyhead/SleepLib/loader_plugins/icon_loader.cpp
index d35ad00d..b7ed544c 100644
--- a/sleepyhead/SleepLib/loader_plugins/icon_loader.cpp
+++ b/sleepyhead/SleepLib/loader_plugins/icon_loader.cpp
@@ -286,28 +286,97 @@ int FPIconLoader::OpenMachine(Machine *mach, QString &path, Profile *profile)
     return true;
 }
 
-QDateTime FPIconLoader::readFPDateTime(quint8 *data)
+// !\brief Convert F&P 32bit date format to 32bit UNIX Timestamp
+quint32 convertDate(quint32 timestamp)
 {
-    quint32 ts = (data[3] << 24) | (data[2] << 16) | ((data[1] << 8) | data[0]); // ^ 0xc00000;
-    // 0x20a41b18
+    quint8 day, month,hour, minute, second;
+    quint16 year;
 
-    quint8 day = ts & 0x1f; // 0X18      24
-    ts >>= 5;               // 10520D8
-    quint8 month = ts & 0x0f; // 0X08      8
-    ts >>= 4;               // 10520D
-    quint8 year = ts & 0x3f; // 0X0D      13
-    ts >>= 6;               // 4148
-    quint8 second = ts & 0x3f; // 0X08      8
-    ts >>= 6;               // 20A
-    quint8 minute = ts & 0x3f; // 0A        10
-    ts >>= 6;               // 10
-    quint8 hour = ts & 0x1f; // 10        16
-    QDate date = QDate(2000 + year, month, day);
-    QTime time = QTime(hour, minute, second);
-    QDateTime datetime = QDateTime(date, time, Qt::UTC);
-    return datetime;
+
+    day = timestamp & 0x1f;
+    month = (timestamp  >> 5) & 0x0f;
+    year = 2000 + ((timestamp  >> 9) & 0x3f);
+    timestamp >>= 15;
+    timestamp |= (timestamp >> 15) & 1;
+
+    // Okay, why did I swap the first and last bits of the time field?
+    // What am I forgetting?? This seems to work properly like this
+    // Was I looking at older data that worked like this?
+
+    second = timestamp  & 0x3f;
+    minute = (timestamp >> 6) & 0x3f;
+    hour = (timestamp >> 12) & 0x1f;
+
+    //        in >> a1;
+    //        in >> a2;
+    //        t1 = a2 << 8 | a1;
+
+    //        if (t1 == 0xfafe) {
+    //            break;
+    //        }
+
+    //        day = t1 & 0x1f;
+    //        month = (t1 >> 5) & 0x0f;
+    //        year = 2000 + ((t1 >> 9) & 0x3f);
+
+    //        in >> a1;
+    //        in >> a2;
+
+    //        ts = ((a2 << 8) | a1) << 1;
+    //        ts |= (t1 >> 15) & 1;
+
+    //        second = (ts & 0x3f);
+    //        minute = (ts >> 6) & 0x3f;
+    //        hour = (ts >> 12) & 0x1f;
+    QDateTime dt = QDateTime(QDate(year, month, day), QTime(hour, minute, second), Qt::UTC);
+
+    return dt.toTime_t();
 }
 
+quint32 convertFLWDate(quint32 timestamp)
+{
+    quint8 day, month, hour, minute, second;
+    quint16 year;
+
+    day = timestamp & 0x1f;
+    month = (timestamp  >> 5) & 0x0f;
+    year = 2000 + ((timestamp  >> 9) & 0x3f);
+    timestamp >>= 15;
+
+    // Okay, why did I swap the first and last bits of the time field?
+    // What am I forgetting?? This seems to work properly like this
+    // Was I looking at older data that worked like this?
+
+    second = timestamp  & 0x3f;
+    minute = (timestamp >> 6) & 0x3f;
+    hour = (timestamp >> 12) & 0x1f;
+    QDateTime dt = QDateTime(QDate(year, month, day), QTime(hour, minute, second), Qt::UTC);
+
+    return dt.toTime_t();
+}
+
+//QDateTime FPIconLoader::readFPDateTime(quint8 *data)
+//{
+//    quint32 ts = (data[3] << 24) | (data[2] << 16) | ((data[1] << 8) | data[0]); // ^ 0xc00000;
+//    // 0x20a41b18
+
+//    quint8 day = ts & 0x1f; // 0X18      24
+//    ts >>= 5;               // 10520D8
+//    quint8 month = ts & 0x0f; // 0X08      8
+//    ts >>= 4;               // 10520D
+//    quint8 year = ts & 0x3f; // 0X0D      13
+//    ts >>= 6;               // 4148
+//    quint8 second = ts & 0x3f; // 0X08      8
+//    ts >>= 6;               // 20A
+//    quint8 minute = ts & 0x3f; // 0A        10
+//    ts >>= 6;               // 10
+//    quint8 hour = ts & 0x1f; // 10        16
+//    QDate date = QDate(2000 + year, month, day);
+//    QTime time = QTime(hour, minute, second);
+//    QDateTime datetime = QDateTime(date, time, Qt::UTC);
+//    return datetime;
+//}
+
 /*
  *in >> a1;
 in >> a2;
@@ -348,19 +417,13 @@ bool FPIconLoader::OpenFLW(Machine *mach, QString filename, Profile *profile)
 {
     Q_UNUSED(mach);
     Q_UNUSED(profile);
-    QByteArray data;
-    quint16 t1;
+
     quint32 ts;
     double ti;
 
-    EventList *flow = nullptr, * pressure = nullptr, *leak = nullptr;
-    QDateTime datetime;
-
-    unsigned char *buf, *endbuf;
-
+    EventList *flow = nullptr, * pressure = nullptr;
 
     qDebug() << filename;
-    QByteArray header;
     QFile file(filename);
 
     if (!file.open(QFile::ReadOnly)) {
@@ -368,19 +431,14 @@ bool FPIconLoader::OpenFLW(Machine *mach, QString filename, Profile *profile)
         return false;
     }
 
-    header = file.read(0x200);
-
+    QByteArray header = file.read(0x200);
     if (header.size() != 0x200) {
         qDebug() << "Short file" << filename;
         return false;
     }
 
-    unsigned char hsum = 0xff;
-
-    for (int i = 0; i < 0x1ff; i++) {
-        hsum += header[i];
-    }
-
+    unsigned char hsum = 0x0;
+    for (int i = 0; i < 0x1ff; i++) { hsum ^= header[i]; }
     if (hsum != header[0x1ff]) {
         qDebug() << "Header checksum mismatch" << filename;
     }
@@ -399,41 +457,21 @@ bool FPIconLoader::OpenFLW(Machine *mach, QString filename, Profile *profile)
     }
 
     fname.chop(4);
-    QString num = fname.right(4);
-    int filenum = num.toInt();
+   // QString num = fname.right(4);
+ //   int filenum = num.toInt();
 
-    data = file.readAll();
 
-    buf = (unsigned char *)data.data();
-    endbuf = buf + data.size();
+    QByteArray buf = file.read(4);
+    unsigned char * data = (unsigned char *)buf.data();
 
-    t1 = buf[1] << 8 | buf[0];
+    ts = data[0] | data[1] << 8 | data[2] << 16 | data[3] << 24;
 
-    if (t1 == 0xfafe) { // End of file marker..
-        qDebug() << "FaFE observed in" << filename;
+    if (ts == 0xffffffff)
         return false;
-    }
-
-    datetime = readFPDateTime(buf);
-    buf += 4;
-
-
-    QDate date;
-    QTime time;
-
-    if (!datetime.isValid()) {
-        qDebug() << "DateTime invalid in OpenFLW:" << filename;
-        return false;
-    }  else {
-        date = datetime.date();
-        time = datetime.time();
-        ts = datetime.toTime_t();
-    }
 
+    ts = convertFLWDate(ts);
     ti = qint64(ts) * 1000L;
 
-    EventStoreType pbuf[256];
-
     QMap<SessionID, Session *>::iterator sit = Sessions.find(ts);
 
     Session *sess;
@@ -442,8 +480,9 @@ bool FPIconLoader::OpenFLW(Machine *mach, QString filename, Profile *profile)
 
     if (sit != Sessions.end()) {
         sess = sit.value();
-        qDebug() << filenum << ":" << date << sess->session() << ":" << sess->hours() * 60.0;
+//        qDebug() << filenum << ":" << date << sess->session() << ":" << sess->hours() * 60.0;
     } else {
+        // Create a session
         qint64 k = -1;
         Session *s1 = nullptr;
         sess = nullptr;
@@ -470,7 +509,7 @@ bool FPIconLoader::OpenFLW(Machine *mach, QString filename, Profile *profile)
             sess->setFirst(CPAP_FlowRate, ti);
             sess->setFirst(CPAP_MaskPressure, ti);
             newsess = true;
-            qDebug() << filenum << ":" << date << "couldn't find matching session for" << ts;
+//            qDebug() << filenum << ":" << date << "couldn't find matching session for" << ts;
         }
     }
 
@@ -479,72 +518,65 @@ bool FPIconLoader::OpenFLW(Machine *mach, QString filename, Profile *profile)
 
     // F&P Overwrites this file, not appends to it.
     flow = new EventList(EVL_Waveform, 1.0F, 0, 0, 0, rate);
-    //leak=new EventList(EVL_Event,1.0,0,0,0,rate*double(samples_per_block)); // 1 per second
-    pressure = new EventList(EVL_Event, 0.01F, 0, 0, 0,
-                             rate * double(samples_per_block)); // 1 per second
+    pressure = new EventList(EVL_Event, 0.01F, 0, 0, 0, rate * double(samples_per_block));
 
     flow->setFirst(ti);
-    //leak->setFirst(ti);
     pressure->setFirst(ti);
 
-    qint16 pr;
-    quint16 lkaj;
+    quint16 endMarker;
+    quint8 offset;         // offset from center for this block
+    quint16 pres;       // mask pressure
+
+    qint16 tmp;
+    QByteArray block;
+    qint16 samples[samples_per_block];
 
     EventDataType val;
-    qint16 tmp;
 
+    // Each block represents 1 second of data.. therefore Flow waveform is at 50hz, and Pressure is at 1hz
     do {
-        quint8 *p = buf;
-
-        // Scan ahead looking for end of block, marked by ff ff
-        do {
-            p++;
-
-            if (p >= endbuf) {
-                delete flow;
-                delete leak;
-                delete pressure;
-                return false;
-            }
-        } while (!((p[0] == 0xff) && (p[1] == 0xff)));
-
-        // The Pressure and lkaj codes are before the end of block marker
-        p -= 3;
-        pr = p[1] << 8 | p[0];
-        lkaj = p[2];
-        int i = 0;
-
-        pressure->AddEvent(ti, pr);
-        //leak->AddEvent(ti,lkaj);
-
-        do {
-            tmp = buf[1] << 8 | buf[0];
-            val = (EventDataType(tmp) / 100.0) - lkaj;
-
-            if (val < -128) { val = -128; }
-            else if (val > 128) { val = 128; }
-
-            buf += 2;
-
-            pbuf[i++] = val;
-        } while (buf < p);
-
-        flow->AddWaveform(ti, pbuf, i, rate);
-        ti += i * rate;
-
-        buf = p + 5;
-
-        if (buf >= endbuf) {
+        block = file.read(105);
+        if (block.size() != 105) {
             break;
         }
-    } while (!((buf[0] == 0xff) && (buf[1] == 0x7f)));
+        data = (unsigned char *)block.data();
+        endMarker = data[1] << 8 | data[0];
+        if (endMarker == 0x7fff) {
+            // Reached end of file
+            break;
+        }
+        pres = data[101] << 8 | data[100];
 
+        offset = data[102];
+
+        pressure->AddEvent(ti, pres);
+
+        for (int i=0; i < samples_per_block; i++) {
+            tmp = ((char *)data)[(i<<1) + 1] << 8 | data[(i << 1)];
+
+            // Assuming Litres per hour, converting to litres per minute and applying offset?
+            // As in should be 60.0?
+            val = (EventDataType(tmp) / 100.0) - offset;
+
+//            if (val < -128) { val = -128; }
+//            else if (val > 128) { val = 128; }
+
+            samples[i]=val;
+        }
+        flow->AddWaveform(ti, samples, samples_per_block, rate);
+
+        endMarker = data[103] << 8 | data[104];
+        ti += samples_per_block * rate;
+    } while (endMarker == 0xffff);
+
+    if (endMarker != 0x7fff) {
+        qDebug() << fname << "waveform does not end with the corrent marker";
+    }
 
     if (sess) {
         sess->setLast(CPAP_FlowRate, ti);
         sess->setLast(CPAP_MaskPressure, ti);
         sess->eventlist[CPAP_FlowRate].push_back(flow);
-        // sess->eventlist[CPAP_Leak].push_back(leak);
         sess->eventlist[CPAP_MaskPressure].push_back(pressure);
     }
 
@@ -555,6 +587,7 @@ bool FPIconLoader::OpenFLW(Machine *mach, QString filename, Profile *profile)
     return true;
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////////////////
 // Open Summary file
 ////////////////////////////////////////////////////////////////////////////////////////////
@@ -620,32 +653,11 @@ bool FPIconLoader::OpenSummary(Machine *mach, QString filename, Profile *profile
     QDate date;
 
     do {
-        in >> a1;
-        in >> a2;
-        t1 = a2 << 8 | a1;
+        in >> ts;
+        if (ts == 0xffffffff) break;
+        if ((ts & 0xfafe) == 0xfafe) break;
 
-        if (t1 == 0xfafe) {
-            break;
-        }
-
-        day = t1 & 0x1f;
-        month = (t1 >> 5) & 0x0f;
-        year = 2000 + ((t1 >> 9) & 0x3f);
-
-        in >> a1;
-        in >> a2;
-
-        ts = ((a2 << 8) | a1) << 1;
-        ts |= (t1 >> 15) & 1;
-
-        second = (ts & 0x3f);
-        minute = (ts >> 6) & 0x3f;
-        hour = (ts >> 12) & 0x1f;
-
-        datetime = QDateTime(QDate(year, month, day), QTime(hour, minute, second), Qt::UTC);
-
-        date = datetime.date();
-        ts = datetime.toTime_t();
+        ts = convertDate(ts);
 
         // the following two quite often match in value
         in >> a1;  // 0x04 Run Time
@@ -733,8 +745,8 @@ bool FPIconLoader::OpenDetail(Machine *mach, QString filename, Profile *profile)
         return false;
     }
 
+    // Calculate and test checksum
     unsigned char hsum = 0;
-
     for (int i = 0; i < 0x1ff; i++) {
         hsum += header[i];
     }
@@ -743,64 +755,29 @@ bool FPIconLoader::OpenDetail(Machine *mach, QString filename, Profile *profile)
         qDebug() << "Header checksum mismatch" << filename;
     }
 
-    QByteArray index;
-    index = file.read(0x800);
-    //long size=index.size(),pos=0;
+    QByteArray index = file.read(0x800);
     QDataStream in(index);
 
     in.setVersion(QDataStream::Qt_4_6);
     in.setByteOrder(QDataStream::LittleEndian);
     quint32 ts;
-    QDateTime datetime;
-    QDate date;
-    QTime time;
-    //FPDetIdx *idx=(FPDetIdx *)index.data();
-
 
     QVector<quint32> times;
     QVector<quint16> start;
     QVector<quint8> records;
 
-    quint16 t1;
     quint16 strt;
-    quint8 recs, z1, z2;
-
-    int day, month, year, hour, minute, second;
+    quint8 recs;
 
     int totalrecs = 0;
 
     do {
-        in >> z1;
-        in >> z2;
-        t1 = z2 << 8 | z1;
+        in >> ts;
+        if (ts == 0xffffffff) break;
+        if ((ts & 0xfafe) == 0xfafe) break;
 
-        if (t1 == 0xfafe) {
-            break;
-        }
+        ts = convertDate(ts);
 
-        day = t1 & 0x1f;
-        month = (t1 >> 5) & 0x0f;
-        year = 2000 + ((t1 >> 9) & 0x3f);
-
-        in >> z1;
-        in >> z2;
-        //
-
-        ts = ((z2 << 8) | z1) << 1;
-        ts |= (t1 >> 15) & 1;
-
-        //
-        second = (ts & 0x3f);
-        minute = (ts >> 6) & 0x3f;
-        hour = (ts >> 12) & 0x1f;
-
-        datetime = QDateTime(QDate(year, month, day), QTime(hour, minute, second), Qt::UTC);
-        //datetime=datetime.toTimeSpec(Qt::UTC);
-
-        ts = datetime.toTime_t();
-
-        date = datetime.date();
-        time = datetime.time();
         in >> strt;
         in >> recs;
         totalrecs += recs;
@@ -816,13 +793,14 @@ bool FPIconLoader::OpenDetail(Machine *mach, QString filename, Profile *profile)
 
     in.setVersion(QDataStream::Qt_4_6);
     in.setByteOrder(QDataStream::BigEndian);
+
     // 5 byte repeating patterns
 
     quint8 *data = (quint8 *)databytes.data();
 
     qint64 ti;
-    quint8 pressure, leak, a1, a2, a3;
-    quint8 sa1, sa2;  // The two sense awake bits per 2 minutes
+    quint8 pressure, leak, a1, a2, a3, a4;
+//    quint8 sa1, sa2;  // The two sense awake bits per 2 minutes
     SessionID sessid;
     Session *sess;
     int idx;
@@ -834,7 +812,6 @@ bool FPIconLoader::OpenDetail(Machine *mach, QString filename, Profile *profile)
         sess->really_set_first(ti);
         EventList *LK = sess->AddEventList(CPAP_LeakTotal, EVL_Event, 1);
         EventList *PR = sess->AddEventList(CPAP_Pressure, EVL_Event, 0.1F);
-//        EventList *FLG = sess->AddEventList(CPAP_FLG, EVL_Event);
         EventList *OA = sess->AddEventList(CPAP_Obstructive, EVL_Event);
         EventList *H = sess->AddEventList(CPAP_Hypopnea, EVL_Event);
         EventList *FL = sess->AddEventList(CPAP_FlowLimit, EVL_Event);
@@ -846,8 +823,8 @@ bool FPIconLoader::OpenDetail(Machine *mach, QString filename, Profile *profile)
         idx = stidx * 15;
 
         quint8 bitmask;
-        for (int i = 0; i < rec; i++) {
-            for (int j = 0; j < 3; j++) {
+        for (int i = 0; i < rec; ++i) {
+            for (int j = 0; j < 3; ++j) {
                 pressure = data[idx];
                 PR->AddEvent(ti, pressure);
 
@@ -858,17 +835,19 @@ bool FPIconLoader::OpenDetail(Machine *mach, QString filename, Profile *profile)
                 a2 = data[idx + 3];   // [0..5] Hypopnea,         [6..7] Unknown
                 a3 = data[idx + 4];   // [0..5] Flow Limitation,  [6..7] SensAwake bitflags, 1 per minute
 
-                sa1 = (a3 >> 6) & 1;  // Sense awake bit for first minutes
-                sa2 = (a3 >> 7) & 1;  // Sense awake bit for second minute
+                // Sure there isn't 6 SenseAwake bits?
+                a4 = (a1 >> 6) << 4 | ((a2 >> 6) << 2) | (a3 >> 6);
 
-                if (sa1) { SA->AddEvent(ti, 1); }
-                if (sa2) { SA->AddEvent(ti + 60000L, 1); }
+                // this does the same thing as behaviour
+                //a4 = (a3 >> 7) << 3 | ((a3 >> 6)&1);
 
                 bitmask = 1;
                 for (int k = 0; k < 6; k++) {  // There are 6 flag sets per 2 minutes
                     if (a1 & bitmask) { OA->AddEvent(ti, 1); }
                     if (a2 & bitmask) { H->AddEvent(ti, 1); }
                     if (a3 & bitmask) { FL->AddEvent(ti, 1); }
+                    if (a4 & bitmask) { SA->AddEvent(ti, 1); }
+
                     bitmask <<= 1;
                     ti += 20000L;  // Increment 20 seconds
                 }
diff --git a/sleepyhead/daily.cpp b/sleepyhead/daily.cpp
index 8983a268..9b5b3fae 100644
--- a/sleepyhead/daily.cpp
+++ b/sleepyhead/daily.cpp
@@ -309,6 +309,8 @@ Daily::Daily(QWidget *parent,gGraphView * shared)
     graphlist[schema::channel[CPAP_Snore].label()]->AddLayer(AddCPAP(new gLineChart(CPAP_Snore, COLOR_Snore, true)));
 
     graphlist[schema::channel[CPAP_PTB].label()]->AddLayer(AddCPAP(new gLineChart(CPAP_PTB, COLOR_PTB, square)));
+
+
     graphlist[schema::channel[CPAP_MaskPressure].label()]->AddLayer(AddCPAP(new gLineChart(CPAP_MaskPressure, COLOR_MaskPressure, false)));
     graphlist[schema::channel[CPAP_RespRate].label()]->AddLayer(AddCPAP(lc=new gLineChart(CPAP_RespRate, COLOR_RespRate, square)));