diff --git a/dumpSTR.pro b/dumpSTR.pro
index 2e3aaa39..2ed676ce 100644
--- a/dumpSTR.pro
+++ b/dumpSTR.pro
@@ -12,6 +12,8 @@ CONFIG -= debug_and_release
 
 QT += core widgets
 
+DEFINES+=DUMPSTR
+
 TARGET = dumpSTR
 
 TEMPLATE = app
@@ -24,9 +26,9 @@ VERSION = 0.5.0
 
 SOURCES += \
 	dumpSTR/main.cpp \
-	dumpSTR/edfparser.cpp \
+	dumpSTR/edfparser.cpp 
 
 HEADERS  += \
-    dumpSTR/common.h \
-    dumpSTR/edfparser.h \
+    dumpSTR/SleepLib/common.h \
+    dumpSTR/edfparser.h 
 
diff --git a/dumpSTR/common.h b/dumpSTR/SleepLib/common.h
similarity index 100%
rename from dumpSTR/common.h
rename to dumpSTR/SleepLib/common.h
diff --git a/dumpSTR/edfparser.cpp b/dumpSTR/edfparser.cpp
deleted file mode 100644
index ad62946f..00000000
--- a/dumpSTR/edfparser.cpp
+++ /dev/null
@@ -1,353 +0,0 @@
-/* EDF Parser Implementation
- *
- * Copyright (c) 2019 The OSCAR Team
- * Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of the source code
- * for more details. */
-
-#include <QDateTime>
-#include <QDebug>
-#include <QFile>
-#include <QMutexLocker>
-#ifdef _MSC_VER
-#include <QtZlib/zlib.h>
-#else
-#include <zlib.h>
-#endif
-
-#include "edfparser.h"
-
-EDFInfo::EDFInfo()
-{
-    filesize = 0;
-    datasize = 0;
-    signalPtr = nullptr;
-    hdrPtr = nullptr;
-    fileData = nullptr;
-}
-
-EDFInfo::~EDFInfo()
-{
-    for (auto & s : edfsignals) {
-        if (s.dataArray)  
-            delete [] s.dataArray;
-    }
-//    for (auto & a : annotations)
-//    	delete  a;
-}
-
-QByteArray * EDFInfo::Open(const QString & name)
-{
-    if (hdrPtr != nullptr) {
-        qWarning() << "EDFInfo::Open() called with file already open " << name;
-        sleep(1);
-        return nullptr;
-    }
-    QFile fi(name);
-    if (!fi.open(QFile::ReadOnly)) {
-        qDebug() << "EDFInfo::Open() Couldn't open file " << name;
-        sleep(1);
-        return nullptr;
-    }
-    fileData = new QByteArray();
-//    if (name.endsWith(STR_ext_gz)) {
-//        *fileData = gUncompress(fi.readAll()); // Open and decompress file
-//    } else {
-        *fileData = fi.readAll(); // Open and read uncompressed file
-//    }
-    fi.close();
-    if (fileData->size() <= EDFHeaderSize) {
-    	fileData->clear();
-        qDebug() << "EDFInfo::Open() File too short " << name;
-        sleep(1);
-        return nullptr;
-    }
-    filename = name;
-    return fileData;
-}
-
-bool EDFInfo::Parse(QByteArray * fileData ) 
-{
-    bool ok;
-
-    if (fileData == nullptr) {
-        qWarning() << "EDFInfo::Parse() called without valid EDF data " << filename;
-        sleep(1);
-        return false;
-    }
-    
-    hdrPtr = (EDFHeaderRaw *)(*fileData).constData();
-    signalPtr = (char *)(*fileData).constData() + EDFHeaderSize;
-    filesize = (*fileData).size();
-    pos = 0;
-
-    eof = false;
-    edfHdr.version = QString::fromLatin1(hdrPtr->version, 8).toLong(&ok);
-    if (!ok) {
-        qWarning() << "EDFInfo::Parse() Bad Version " << filename;
-        sleep(1);
-        return false;
-    }
-
-    edfHdr.patientident=QString::fromLatin1(hdrPtr->patientident,80).trimmed();
-    edfHdr.recordingident = QString::fromLatin1(hdrPtr->recordingident, 80).trimmed(); // Serial number is in here..
-    edfHdr.startdate_orig = QDateTime::fromString(QString::fromLatin1(hdrPtr->datetime, 16), "dd.MM.yyHH.mm.ss");
-    QDate d2 = edfHdr.startdate_orig.date();
-    if (d2.year() < 2000) {
-        d2.setDate(d2.year() + 100, d2.month(), d2.day());
-        edfHdr.startdate_orig.setDate(d2);
-    }
-
-    edfHdr.num_header_bytes = QString::fromLatin1(hdrPtr->num_header_bytes, 8).toLong(&ok);
-    if (!ok) {
-        qWarning() << "EDFInfo::Parse() Bad header byte count " << filename;
-        sleep(1);
-        return false;
-    }
-    edfHdr.reserved44=QString::fromLatin1(hdrPtr->reserved, 44).trimmed();
-    edfHdr.num_data_records = QString::fromLatin1(hdrPtr->num_data_records, 8).toLong(&ok);
-    if (!ok) {
-        qWarning() << "EDFInfo::Parse() Bad data record count " << filename;
-        sleep(1);
-        return false;
-    }
-    edfHdr.duration_Seconds = QString::fromLatin1(hdrPtr->dur_data_records, 8).toDouble(&ok);
-    if (!ok) {
-        qWarning() << "EDFInfo::Parse() Bad duration " << filename;
-        sleep(1);
-        return false;
-    }
-    edfHdr.num_signals = QString::fromLatin1(hdrPtr->num_signals, 4).toLong(&ok);
-    if (!ok) {
-        qWarning() << "EDFInfo::Parse() Bad number of signals " << filename;
-        sleep(1);
-        return false;
-    }
-    datasize = filesize - EDFHeaderSize;
-
-    // Initialize fixed-size signal list.
-    edfsignals.resize(edfHdr.num_signals);
-
-    // Now copy all the Signal descriptives into edfsignals
-    for (auto & sig : edfsignals) {
-        sig.dataArray = nullptr;
-        sig.label = ReadBytes(16);
-
-        signal_labels.push_back(sig.label);
-        signalList[sig.label].push_back(&sig);
-        if (eof) {
-            qWarning() << "EDFInfo::Parse() Early end of file " << filename;
-            sleep(1);
-            return false;
-        }
-    }
-    for (auto & sig : edfsignals) { 
-        sig.transducer_type = ReadBytes(80).trimmed(); 
-    }
-    for (auto & sig : edfsignals) { 
-        sig.physical_dimension = ReadBytes(8); 
-    }
-    for (auto & sig : edfsignals) { 
-        sig.physical_minimum = ReadBytes(8).toDouble(&ok); 
-    }
-    for (auto & sig : edfsignals) { 
-        sig.physical_maximum = ReadBytes(8).toDouble(&ok); 
-    }
-    for (auto & sig : edfsignals) { 
-        sig.digital_minimum = ReadBytes(8).toDouble(&ok); 
-    }
-    for (auto & sig : edfsignals) { 
-        sig.digital_maximum = ReadBytes(8).toDouble(&ok);
-        sig.gain = (sig.physical_maximum - sig.physical_minimum) / (sig.digital_maximum - sig.digital_minimum);
-        sig.offset = 0;
-    }
-    for (auto & sig : edfsignals) { 
-        sig.prefiltering = ReadBytes(80).trimmed(); 
-    }
-    for (auto & sig : edfsignals) { 
-        sig.sampleCnt = ReadBytes(8).toLong(&ok); 
-    }
-    for (auto & sig : edfsignals) { 
-        sig.reserved = ReadBytes(32).trimmed(); 
-    }
-
-    // could do it earlier, but it won't crash from > EOF Reads
-    if (eof) {
-        qWarning() << "EDFInfo::Parse() Early end of file " << filename;
-        sleep(1);
-        return false;
-    }
-
-    // Now check the file isn't truncated before allocating space for the values
-    long totalsize = 0;
-    for (auto & sig : edfsignals) {
-        if (edfHdr.num_data_records > 0) {
-            totalsize += sig.sampleCnt * edfHdr.num_data_records * 2;
-        }
-    }
-    if (totalsize > datasize) {
-        // Space required more than the remainder left to read,
-        // so abort and let the user clean up the corrupted file themselves
-        qWarning() << "EDFInfo::Parse(): " << filename << " is too short!";
-        sleep(1);
-        return false;
-    }
-
-    // allocate the arrays for the signal values
-    for (auto & sig : edfsignals) {
-        long samples = sig.sampleCnt * edfHdr.num_data_records;
-        if (edfHdr.num_data_records <= 0)
-            sig.dataArray = nullptr;
-        else 
-            sig.dataArray = new qint16 [samples];
-//      qDebug() << "Allocated " << samples  << " at " << sig.dataArray;    
-    }
-    for (int recNo = 0; recNo < edfHdr.num_data_records; recNo++) {
-        for (auto & sig : edfsignals) {
-        	if ( sig.label.contains("Annotation") ) {
-        	//	qDebug() << "Rec " << recNo << " Anno @ " << pos << " starts with " << signalPtr[pos];
-        		annotations.push_back(ReadAnnotations( (char *)&signalPtr[pos], sig.sampleCnt*2));
-        		pos += sig.sampleCnt * 2;
-        	} else {      //  it's got genuine 16-bit values
-                for (int j=0;j<sig.sampleCnt;j++) { // Big endian safe
-                    qint16 t=Read16();
-                    sig.dataArray[recNo*sig.sampleCnt + j]=t;
-    	        }
-			}
-        }
-    }
-	return true;
-}
-
-// Parse the EDF file to get the annotations out of it.
-QVector<Annotation>  EDFInfo::ReadAnnotations(const char * data, int charLen)
-{
-	QVector<Annotation>  annoVec =  QVector<Annotation>();
-	
-    // Process event annotation record
-
-    long pos = 0;
-    double offset;
-    double duration;
-
-    while (pos < charLen) {
-	    QString text;
-        bool sign, ok;
-        char c = data[pos];
-
-        if ((c != '+') && (c != '-'))       // Annotaion must start with a +/- sign
-            break;
-        sign = (data[pos++] == '+');
-
-        text = "";
-        c = data[pos];
-
-        do {            // collect the offset 
-            text += c;
-            pos++;
-            c = data[pos];
-        } while ((c != AnnoSep) && (c != AnnoDurMark)); // a duration is optional
-
-        offset = text.toDouble(&ok);
-        if (!ok) {
-            qDebug() << "Faulty offset in  annotation record ";
-        //  sleep(1);
-            break;
-        }
-
-        if (!sign)
-            offset = -offset;
-
-        duration = -1.0;	// This indicates no duration supplied
-        // First entry
-        if (data[pos] == AnnoDurMark) { // get duration.(preceded by decimal 21 byte)
-            pos++;
-            text = "";
-
-            do {        // collect the duration
-                text += data[pos];
-                pos++;
-            } while ((data[pos] != AnnoSep) && (pos < charLen)); // separator code
-
-            duration = text.toDouble(&ok);
-            if (!ok) {
-                qDebug() << "Faulty duration in  annotation record ";
-        //      sleep(1);
-                break;
-            }
-        }
-
-        while ((data[pos] == AnnoSep) && (pos < charLen)) {
-        	text = "";
-            int textLen = 0;
-            pos++;
-            const char * textStart = &data[pos];
-            if (data[pos] == AnnoEnd)
-                break;
-            if (data[pos] == AnnoSep) {
-                pos++;
-                break;
-            }
-            do {            // collect the annotation text
-                pos++;      // officially UTF-8 is allowed here, so don't mangle it
-                textLen++;
-            } while ((data[pos] != AnnoSep) && (pos < charLen)); // separator code
-            text = QString::fromUtf8(textStart, textLen);
-            annoVec.push_back( Annotation( offset, duration, text) );
-            if (pos >= charLen) {
-                qDebug() << "Short EDF Annotations record";
-        //      sleep(1);
-                break;
-            }
-        }
-
-        while ((pos < charLen) && (data[pos] == AnnoEnd))
-            pos++;
-
-        if (pos >= charLen)
-            break;
-    }
-    return annoVec;
-}
-
-// Read a 16 bits integer
-qint16 EDFInfo::Read16()
-{
-    if ((pos + 2) > datasize) {
-        eof = true;
-        return 0;
-    }
-#ifdef Q_LITTLE_ENDIAN // Intel, etc...
-    qint16 res = *(qint16 *)&signalPtr[pos];
-#else // ARM, PPC, etc..
-    qint16 res = quint8(signalPtr[pos]) | (qint8(signalPtr[pos+1]) << 8);
-#endif
-    pos += 2;
-    return res;
-}
-
-QString EDFInfo::ReadBytes(unsigned n)
-{
-    if ((pos + long(n)) > datasize) {
-        eof = true;
-        return QString();
-    }
-    QByteArray buf(&signalPtr[pos], n);
-    pos+=n;
-    return buf.trimmed();
-}
-
-EDFSignal *EDFInfo::lookupLabel(const QString & name, int index)
-{
-    auto it = signalList.find(name);
-    if (it == signalList.end()) 
-        return nullptr;
-
-    if (index >= it.value().size()) 
-        return nullptr;
-
-    return it.value()[index];
-}
-
diff --git a/dumpSTR/edfparser.cpp b/dumpSTR/edfparser.cpp
new file mode 120000
index 00000000..0cf82530
--- /dev/null
+++ b/dumpSTR/edfparser.cpp
@@ -0,0 +1 @@
+../oscar/SleepLib/loader_plugins/edfparser.cpp
\ No newline at end of file
diff --git a/dumpSTR/edfparser.h b/dumpSTR/edfparser.h
deleted file mode 100644
index 69eab21a..00000000
--- a/dumpSTR/edfparser.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/* EDF Parser Header
- *
- * Copyright (c) 2019 The OSCAR Team
- * Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of the source code
- * for more details. */
-
-#ifndef EDFPARSER_H
-#define EDFPARSER_H
-
-#include <QString>
-#include <QVector>
-#include <QHash>
-#include <QList>
-#include <QDateTime>
-
-// #include "SleepLib/common.h"
-
-typedef float EventDataType;
-
-const QString STR_ext_EDF = "edf";
-const QString STR_ext_gz = ".gz";
-
-const char AnnoSep = 20;
-const char AnnoDurMark = 21;
-const char AnnoEnd = 0;
-
-/*! \struct EDFHeader
-    \brief  Represents the EDF+ header structure, used as a place holder while processing the text data.
-    \note More information on the EDF+ file format can be obtained from http://edfplus.info
-*/
-struct EDFHeaderRaw {
-    char version[8];
-    char patientident[80];
-    char recordingident[80];
-    char datetime[16];
-    char num_header_bytes[8];
-    char reserved[44];
-    char num_data_records[8];
-    char dur_data_records[8];
-    char num_signals[4];
-}
-#ifndef _MSC_VER
-__attribute__((packed))
-#endif
-;
-const int EDFHeaderSize = sizeof(EDFHeaderRaw);
-
-/*! \struct EDFHeaderQT
-    \brief Contains the QT version of the EDF header information
-    */
-struct EDFHeaderQT {
-  public:
-    long version;
-    QString patientident;
-    QString recordingident;
-    QDateTime startdate_orig;
-    long num_header_bytes;
-    QString reserved44;
-    long num_data_records;
-    double duration_Seconds;
-    int num_signals;
-};
-
-/*! \struct EDFSignal
-    \brief Contains information about a single EDF+ Signal
-    \note More information on the EDF+ file format can be obtained from http://edfplus.info
-    */
-struct EDFSignal {
-  public:
-    QString label;                      //! \brief Name of this Signal
-    QString transducer_type;            //! \brief Tranducer Type (source of the data, usually blank)
-    QString physical_dimension;         //! \brief The units of measurements represented by this signal
-    EventDataType physical_minimum;     //! \brief The minimum limits of the ungained data
-    EventDataType physical_maximum;     //! \brief The maximum limits of the ungained data
-    EventDataType digital_minimum;      //! \brief The minimum limits of the data with gain and offset applied
-    EventDataType digital_maximum;      //! \brief The maximum limits of the data with gain and offset applied
-    EventDataType gain;                 //! \brief Raw integer data is multiplied by this value
-    EventDataType offset;               //! \brief This value is added to the raw data
-    QString prefiltering;               //! \brief Any prefiltering methods used (usually blank)
-    long sampleCnt;                     //! \brief Number of samples per record
-    QString reserved;                   //! \brief Reserved (usually blank)
-
-    qint16 * dataArray;                   //! \brief Offset in record to the signals sample data
-};
-
-/*! \class Annotation
-    \author Phil Olynyk
-    \brief Hold the annotation text from an EDF file
-    */
-class Annotation
-{
-  public:
-    Annotation() { duration = -1.0; };
-    Annotation( double off, double dur, QString tx ) {
-        offset = off;
-        duration = dur;
-        text = tx;
-    };
-    virtual ~Annotation() {};
-
-    double  offset;
-    double  duration;
-    QString text;
-};
-
-/*! \class EDFInfo
-    \author Phil Olynyk
-    \author Mark Watkins <mark@jedimark.net>
-    \brief Parse an EDF+ data file into a list of EDFSignal's
-    \note More information on the EDF+ file format can be obtained from http://edfplus.info
-    */
-class EDFInfo
-{
-  public:
-    //! \brief Constructs an EDFParser object, opening the filename if one supplied
-    EDFInfo();
-
-    virtual ~EDFInfo();
-
-    virtual QByteArray * Open(const QString & name);                    //! \brief Open the EDF+ file, and read it's header
-
-    virtual bool Parse(QByteArray * fileData);                          //! \brief Parse the EDF+ file into the EDFheaderQT. Must call Open(..) first.
-
-    virtual EDFSignal *lookupLabel(const QString & name, int index=0);  //! \brief Return a ptr to the i'th signal with that name
-
-    virtual long GetNumSignals() { return edfHdr.num_signals; }         //! \brief Returns the number of signals contained in this EDF file
-
-    virtual long GetNumDataRecords() { return edfHdr.num_data_records; } //! \brief Returns the number of data records contained per signal.
-
-    virtual double GetDuration() { return edfHdr.duration_Seconds; }    //! \brief Returns the duration represented by this EDF file
-
-    virtual QString GetPatient() { return edfHdr.patientident; }        //! \brief Returns the patientid field from the EDF header
-
-//  The data members follow
-
-    QString filename;								//!	\brief For debug and error messages
-
-    EDFHeaderQT edfHdr;                             //! \brief The header in a QT friendly form
-
-    QVector<EDFSignal> edfsignals;                  //! \brief Holds the EDFSignals contained in this edf file
-    
-//  QVector< QVector<qint16> > dataRecords;			//! \brief Holds the datarecords
-
-    QVector< QVector<Annotation> > annotations;   //! \brief Holds the Annotaions for this EDF file
-
-    QStringList signal_labels;                      //! \brief An by-name indexed into the EDFSignal data
-
-    QHash<QString, QList<EDFSignal *> > signalList; //! \brief ResMed sometimes re-uses the SAME signal name
-
-//  the following could be private
-  private:
-    QVector<Annotation>  ReadAnnotations( const char * data, int charLen );	//! \brief Create an Annotaion vector from the signal values
-
-    QString ReadBytes(unsigned n);                                   //! \brief Read n bytes of 8 bit data from the EDF+ data stream
-
-    qint16 Read16();                                            //! \brief Read 16 bit word of data from the EDF+ data stream
-
-    //! \brief This is the array holding the EDF file data
-    QByteArray  * fileData;
-    //! \brief  The EDF+ files header structure, used as a place holder while processing the text data.
-    EDFHeaderRaw *hdrPtr;
-    //! \brief This is the array of signal descriptors and values
-    char *signalPtr;
-
-    long filesize;
-    long datasize;
-    long pos;
-    bool eof;
-};
-
-
-#endif // EDFPARSER_H
diff --git a/dumpSTR/edfparser.h b/dumpSTR/edfparser.h
new file mode 120000
index 00000000..9296f3c2
--- /dev/null
+++ b/dumpSTR/edfparser.h
@@ -0,0 +1 @@
+../oscar/SleepLib/loader_plugins/edfparser.h
\ No newline at end of file
diff --git a/dumpSTR/main.cpp b/dumpSTR/main.cpp
index c8024de6..4f3e54db 100644
--- a/dumpSTR/main.cpp
+++ b/dumpSTR/main.cpp
@@ -45,6 +45,18 @@ void dumpSignals( const QVector<EDFSignal>  sigs ) {
     }
 }
 
+void usage() {
+    qDebug() << "dumpSTR [ options ] filename";
+    qDebug() << "Options";
+    qDebug() << "\t-a Show all";
+    qDebug() << "\t-f ### First day";
+    qDebug() << "\t-l ### Last day";
+    qDebug() << "\t-g ### First signal";
+    qDebug() << "\t-m ### Last signal";
+    qDebug() << "\t-s Signal list only";
+    qDebug() << "\t-h or -? This help message";
+}
+
 int main(int argc, char *argv[]) {
 
 //    QString homeDocs = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)+"/";
@@ -77,14 +89,23 @@ int main(int argc, char *argv[]) {
             lastSig = args[++i].toInt();
         else if (args[i] == "-a")
             showall = true;
-        else if (args[i] == "-b")
+        else if (args[i] == "-s")
             brief = true;
+        else if ((args[i] == "-?") || (args[i] == "-h")) {
+            usage();
+            exit(0);
+        }
     }
 
     EDFInfo str;
-    QByteArray * buffer = str.Open(filename);
-    if ( ! str.Parse(buffer) )
+    if ( ! str.Open(filename) ) {
+        qDebug() << "Failed to open" << filename;
         exit(-1);
+    }
+    if ( ! str.Parse() ) {
+        qDebug() << "Parsing failed on" << filename;
+        exit(-1);
+    }
 
     QDate d2 = str.edfHdr.startdate_orig.date();
     if (d2.year() < 2000) {
diff --git a/oscar/SleepLib/loader_plugins/edfparser.cpp b/oscar/SleepLib/loader_plugins/edfparser.cpp
index 62ed45e7..6d21fb9a 100644
--- a/oscar/SleepLib/loader_plugins/edfparser.cpp
+++ b/oscar/SleepLib/loader_plugins/edfparser.cpp
@@ -68,11 +68,15 @@ bool EDFInfo::Open(const QString & name)
         return false;
     }
 //    fileData = new QByteArray();
+#ifndef DUMPSTR
     if (name.endsWith(STR_ext_gz)) {
         fileData = gUncompress(fi.readAll()); // Open and decompress file
     } else {
         fileData = fi.readAll(); // Open and read uncompressed file
     }
+#else
+    fileData = fi.readAll(); // Open and read uncompressed file
+#endif    
     fi.close();
     if (fileData.size() <= EDFHeaderSize) {
     	fileData.clear();;
@@ -280,11 +284,15 @@ EDFHeaderQT * EDFInfo::GetHeader( const QString & name)
         return nullptr;
     }
 //    fileData = new QByteArray();
+#ifndef DUMPSTR
     if (name.endsWith(STR_ext_gz)) {
         fileData = gUncompress(fi.read(sizeof(EDFHeaderRaw))); // Open and decompress file
     } else {
         fileData = fi.read(sizeof(EDFHeaderRaw)); // Open and read uncompressed file
     }
+#else
+    fileData = fi.read(sizeof(EDFHeaderRaw)); // Open and read uncompressed file
+#endif    
     fi.close();
     filename = name;
     hdrPtr = (EDFHeaderRaw *)fileData.constData();