diff --git a/app/build.gradle b/app/build.gradle
index b48e315c651f14dea31f0c579dac6a2ec348761c..6087f89f0703604736d3fdec83f036ad0c5d6d7b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -161,4 +161,7 @@ dependencies {
     compile 'com.squareup.retrofit2:retrofit:2.1.0'
     compile 'com.squareup.retrofit2:converter-gson:2.1.0'
     compile 'com.google.android.gms:play-services-appindexing:8.4.0'
+
+    // https://mvnrepository.com/artifact/org.anarres.lzo/lzo-core
+    compile group: 'org.anarres.lzo', name: 'lzo-core', version: '1.0.5'
 }
\ No newline at end of file
diff --git a/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java b/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java
index 6a493ac5550eed62fcc97909a2c124a9228643d5..a4bc1796fb01ef6c6f22425b658eddfa3b7707d6 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java
@@ -59,6 +59,8 @@ import java.text.DateFormat;
 import java.text.DecimalFormat;
 import java.text.NumberFormat;
 import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Locale;
 import java.util.Queue;
 import java.util.concurrent.ArrayBlockingQueue;
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/pump/PumpTimeResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/pump/PumpTimeResponseMessage.java
index 914e539ca2108f5c2576c22d1b6ff7c8020787ce..3a45dfd8d6ba615eee10f55bcc007843ce2f53e5 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/pump/PumpTimeResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/pump/PumpTimeResponseMessage.java
@@ -24,6 +24,60 @@ public class PumpTimeResponseMessage extends MedtronicSendMessageResponseMessage
     protected PumpTimeResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
         super(pumpSession, payload);
 
+        /**
+         2017-03-11 11:50:29 +0000 UTC I ContourNextLinkMessage  :0    READ:
+         2017-03-11 11:50:29 +0000 UTC I ContourNextLinkMessage  :0               ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
+         2017-03-11 11:50:29 +0000 UTC I ContourNextLinkMessage  :0    0x00000000 51 03 30 30 30 30 30 30 00 00 00 00 00 00 00 00 Q.000000........
+         2017-03-11 11:50:29 +0000 UTC I ContourNextLinkMessage  :0    0x00000010 00 00 81 05 00 00 00 00 00 00 00 00 0F 00 00 00 ................
+         2017-03-11 11:50:29 +0000 UTC I ContourNextLinkMessage  :0    0x00000020 D2 55 0D 00 04 00 00 00 00 03 00 01 02 02 58 03 .U............X.
+
+         2017-03-11 11:50:31 +0000 UTC I ContourNextLinkMessage  :0    READ:
+         2017-03-11 11:50:31 +0000 UTC I ContourNextLinkMessage  :0               ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
+         2017-03-11 11:50:31 +0000 UTC I ContourNextLinkMessage  :0    0x00000000 51 03 30 30 30 30 30 30 00 00 00 00 00 00 00 00 Q.000000........
+         2017-03-11 11:50:31 +0000 UTC I ContourNextLinkMessage  :0    0x00000010 00 00 80 D0 8E 00 80 00 00 00 00 00 28 00 00 00 ............(...
+         2017-03-11 11:50:31 +0000 UTC I ContourNextLinkMessage  :0    0x00000020 D8 55 26 00 06 EB 2F 11 EE 45 F7 23 00 01 0B 10 .U&.../..E.#....
+         2017-03-11 11:50:31 +0000 UTC I ContourNextLinkMessage  :0    0x00000030 82 06 F7 23 00 02 0C 04 0E A9 BF 51 60 15 80 A7 ...#.......Q`...
+         2017-03-11 11:50:31 +0000 UTC I ContourNextLinkMessage  :0    0x00000040 20 65 39 1A EC 5A 4E 1D 29                      .e9..ZN.)
+
+         2017-03-11 11:50:31 +0000 UTC I MedtronicResponseMessage  :0    DECRYPTED:
+         2017-03-11 11:50:31 +0000 UTC I MedtronicResponseMessage  :0               ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
+         2017-03-11 11:50:31 +0000 UTC I MedtronicResponseMessage  :0    0x00000000 51 03 30 30 30 30 30 30 00 00 00 00 00 00 00 00 Q.000000........
+         2017-03-11 11:50:31 +0000 UTC I MedtronicResponseMessage  :0    0x00000010 00 00 80 D0 8E 00 80 00 00 00 00 00 28 00 00 00 ............(...
+         2017-03-11 11:50:31 +0000 UTC I MedtronicResponseMessage  :0    0x00000020 D8 55 26 00 06 EB 2F 11 EE 45 F7 23 00 01 0B 10 .U&.../..E.#....
+         2017-03-11 11:50:31 +0000 UTC I MedtronicResponseMessage  :0    0x00000030 82 06 F7 23 00 02 0C 04 0E 01 04 07 01 80 8D DF ...#............
+         2017-03-11 11:50:31 +0000 UTC I MedtronicResponseMessage  :0    0x00000040 24 9F C8 D0 7F 7A 1D 1D 29                      $....z..)
+         2017-03-11 11:50:31 +0000 UTC I PumpTimeResponseMessage  :0    PAYLOAD:
+         2017-03-11 11:50:31 +0000 UTC I PumpTimeResponseMessage  :0               ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7
+         2017-03-11 11:50:31 +0000 UTC I PumpTimeResponseMessage  :0    0x00000000 80 8D DF 24 9F C8 D0 7F                         ...$....
+
+         Steam with wrong (old) key
+         2017-03-11 11:48:04 +0000 UTC I ContourNextLinkMessage  :0    READ:
+         2017-03-11 11:48:04 +0000 UTC I ContourNextLinkMessage  :0               ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
+         2017-03-11 11:48:04 +0000 UTC I ContourNextLinkMessage  :0    0x00000000 51 03 30 30 30 30 30 30 00 00 00 00 00 00 00 00 Q.000000........
+         2017-03-11 11:48:04 +0000 UTC I ContourNextLinkMessage  :0    0x00000010 00 00 81 04 00 00 00 00 00 00 00 00 0F 00 00 00 ................
+         2017-03-11 11:48:04 +0000 UTC I ContourNextLinkMessage  :0    0x00000020 D1 55 0D 00 04 00 00 00 00 03 00 01 02 02 58 03 .U............X.
+         2017-03-11 11:48:07 +0000 UTC I ContourNextLinkMessage  :0    READ:
+         2017-03-11 11:48:07 +0000 UTC I ContourNextLinkMessage  :0               ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
+         2017-03-11 11:48:07 +0000 UTC I ContourNextLinkMessage  :0    0x00000000 51 03 30 30 30 30 30 30 00 00 00 00 00 00 00 00 Q.000000........
+         2017-03-11 11:48:07 +0000 UTC I ContourNextLinkMessage  :0    0x00000010 00 00 80 CE 8E 00 80 00 00 00 00 00 0D 00 00 00 ................
+         2017-03-11 11:48:07 +0000 UTC I ContourNextLinkMessage  :0    0x00000020 24 55 0B 00 00 00 02 00 00 03 00 00 7D 65       $U..........}e
+         2017-03-11 11:48:07 +0000 UTC W PumpTimeResponseMessage  :0    Invalid message received for getPumpTime
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    Unexpected Message
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    info.nightscout.android.medtronic.exception.UnexpectedMessageException: Invalid message received for getPumpTime
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    	at info.nightscout.android.medtronic.message.PumpTimeResponseMessage.<init>(PumpTimeResponseMessage.java:31)
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    	at info.nightscout.android.medtronic.message.PumpTimeRequestMessage.getResponse(PumpTimeRequestMessage.java:49)
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    	at info.nightscout.android.medtronic.message.PumpTimeRequestMessage.send(PumpTimeRequestMessage.java:39)
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    	at info.nightscout.android.medtronic.message.PumpTimeRequestMessage.send(PumpTimeRequestMessage.java:15)
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    	at info.nightscout.android.medtronic.message.ContourNextLinkRequestMessage.send(ContourNextLinkRequestMessage.java:26)
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    	at info.nightscout.android.medtronic.MedtronicCnlReader.getPumpTime(MedtronicCnlReader.java:177)
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    	at info.nightscout.android.medtronic.service.MedtronicCnlIntentService.onHandleIntent(MedtronicCnlIntentService.java:236)
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    	at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66)
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    	at android.os.Handler.dispatchMessage(Handler.java:102)
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    	at android.os.Looper.loop(Looper.java:148)
+         2017-03-11 11:48:07 +0000 UTC W MedtronicCnlReader  :0    	at android.os.HandlerThread.run(HandlerThread.java:61)
+         2017-03-11 11:48:07 +0000 UTC I UsbHidDriver  :0    Wrote amt=64 attempted=64
+
+         */
         if (this.encode().length < (61 + 8)) {
             // Invalid message. Return an invalid date.
             // TODO - deal with this more elegantly
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/pump/ReadHistoryBaseRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/pump/ReadHistoryBaseRequestMessage.java
index 39e3168116d00493128dc5d6be681199ab39071b..70a3150b142e7c640c260318d92e28ecf0a4037a 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/pump/ReadHistoryBaseRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/pump/ReadHistoryBaseRequestMessage.java
@@ -2,6 +2,12 @@ package info.nightscout.android.medtronic.message.pump;
 
 import android.util.Log;
 
+import org.anarres.lzo.LzoAlgorithm;
+import org.anarres.lzo.LzoDecompressor;
+import org.anarres.lzo.LzoInputStream;
+import org.anarres.lzo.LzoLibrary;
+
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
@@ -23,18 +29,21 @@ import info.nightscout.android.medtronic.message.pump.command.multipacket.Repeat
 import info.nightscout.android.utils.HexDump;
 
 import static android.R.attr.value;
+import static android.R.id.message;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
 public abstract class ReadHistoryBaseRequestMessage<T extends AbstractResponseMessage> extends MedtronicSendMessageRequestMessage<T> {
     private static final String TAG = ReadHistoryBaseRequestMessage.class.getSimpleName();
+    private final LzoDecompressor lzoODecompressor;
 
     private long segmentSize;
     private short packetSize;
     private short lastPacketSize;
     private short packetsToFetch;
     private byte[][] segments;
+    private byte historyDataType;
 
     protected enum HistoryDataType {
         PUMP_DATA(0x2),
@@ -58,6 +67,8 @@ public abstract class ReadHistoryBaseRequestMessage<T extends AbstractResponseMe
         this.expectedSize = expectedSize;
         this.bytesFetched = 0;
         this.receviedEndHistoryCommand = false;
+
+        lzoODecompressor = LzoLibrary.getInstance().newDecompressor(LzoAlgorithm.LZO1X, null);
     }
 
     @Override
@@ -128,15 +139,18 @@ public abstract class ReadHistoryBaseRequestMessage<T extends AbstractResponseMe
     }
 
     protected int[] missingSegmentKeys() {
-        ArrayList<Integer> keys = new ArrayList<>(this.segments.length);
+        int[] keys = new int[this.segments.length];
         int count = 0;
-        for ( byte[] segment: this.segments){
+        for ( int i = 0; i < this.segments.length; i++) {
+            byte[] segment = this.segments[i];
             if (segment==null) {
-                keys.add(count);
+                keys[count++] = i;
             };
-            count ++;
         }
-        return keys.toArray();
+
+        int[] result = new int[count];
+        System.arraycopy(keys, 0, result, 0, count);
+        return result;
     }
     /*
     get missingSegmentKeys() {
@@ -190,28 +204,36 @@ public abstract class ReadHistoryBaseRequestMessage<T extends AbstractResponseMe
             // TODO - all of this should go into different classes...
             // Decompress the message
             if ((buffer.getInt(0x00) & 0xffffffffl) == 0x030E) {
-                const HEADER_SIZE = 12; // TODO should be a static get.
+                final byte HEADER_SIZE = 12; // TODO should be a static get.
                 // It's an UnmergedHistoryUpdateCompressed response. We need to decompress it
-                const dataType = segmentPayload[0x02]; // Returns a HISTORY_DATA_TYPE
-                const historySizeCompressed = segmentPayload.readUInt32BE(0x03);
-                const historySizeUncompressed = segmentPayload.readUInt32BE(0x07);
-                const historyCompressed = segmentPayload[0x0B];
+                final byte dataType = buffer.get(0x02); // Returns a HISTORY_DATA_TYPE
+                final long  historySizeCompressed = (buffer.getInt(0x03) & 0xffffffffl); //segmentPayload.readUInt32BE(0x03);
+                final long historySizeUncompressed = (buffer.getInt(0x03) & 0xffffffffl); //segmentPayload.readUInt32BE(0x07);
+                final boolean historyCompressed = (buffer.get(0x0B) != 0);
 
-                if (dataType !== this.historyDataType) {
-                    reject(new InvalidMessageError('Unexpected history type in response'));
+                if (dataType != this.historyDataType) {
+                    throw new InvalidMessageException("Unexpected history type in response");
                 }
 
                 // Check that we have the correct number of bytes in this message
-                if (segmentPayload.length - HEADER_SIZE !== historySizeCompressed) {
-                    reject(new InvalidMessageError('Unexpected message size'));
+                if (segmentPayload.length - HEADER_SIZE != historySizeCompressed) {
+                    throw new InvalidMessageException("Unexpected message size");
                 }
 
-                let blockPayload = null;
+                byte[] blockPayload;
                 if (historyCompressed) {
-                    blockPayload = lzo.decompress(segmentPayload.slice(HEADER_SIZE));
-                    if (blockPayload.length !== historySizeUncompressed) {
-                        debug(`Unexpected uncompressed message size. Expected ${historySizeUncompressed}, got ${blockPayload.length}. Original size ${historySizeCompressed}, compressed: ${historyCompressed}.`);
-                        reject(new InvalidMessageError('Unexpected uncompressed message size.'));
+                    byte[] lzoSegemnt;
+                    System.arraycopy(segmentPayload, HEADER_SIZE, lzoSegemnt, 0, segmentPayload.length -HEADER_SIZE);
+                    LzoInputStream stream = new LzoInputStream(
+                            new ByteArrayInputStream(lzoSegemnt), lzoODecompressor);
+
+                    blockPayload = new byte[stream.available()];
+
+                    int size = stream.read(blockPayload);
+
+                    if (size != historySizeUncompressed) {
+                        Log.d(TAG, "Unexpected uncompressed message size. Expected ${historySizeUncompressed}, got ${blockPayload.length}. Original size ${historySizeCompressed}, compressed: ${historyCompressed}.");
+                        throw (new InvalidMessageException("Unexpected uncompressed message size."));
                     }
                 } else {
                     blockPayload = segmentPayload.slice(HEADER_SIZE);