diff --git a/app/src/main/java/com/google/zxing/integration/android/IntentIntegrator.java b/app/src/main/java/com/google/zxing/integration/android/IntentIntegrator.java
new file mode 100644
index 0000000000000000000000000000000000000000..4eb5681d2449ec69ab85260d634ab986e4d3cabe
--- /dev/null
+++ b/app/src/main/java/com/google/zxing/integration/android/IntentIntegrator.java
@@ -0,0 +1,506 @@
+/*
+ * Copyright 2009 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.integration.android;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.content.ActivityNotFoundException;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * <p>A utility class which helps ease integration with Barcode Scanner via {@link Intent}s. This is a simple
+ * way to invoke barcode scanning and receive the result, without any need to integrate, modify, or learn the
+ * project's source code.</p>
+ *
+ * <h2>Initiating a barcode scan</h2>
+ *
+ * <p>To integrate, create an instance of {@code IntentIntegrator} and call {@link #initiateScan()} and wait
+ * for the result in your app.</p>
+ *
+ * <p>It does require that the Barcode Scanner (or work-alike) application is installed. The
+ * {@link #initiateScan()} method will prompt the user to download the application, if needed.</p>
+ *
+ * <p>There are a few steps to using this integration. First, your {@link Activity} must implement
+ * the method {@link Activity#onActivityResult(int, int, Intent)} and include a line of code like this:</p>
+ *
+ * <pre>{@code
+ * public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ *   IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
+ *   if (scanResult != null) {
+ *     // handle scan result
+ *   }
+ *   // else continue with any other code you need in the method
+ *   ...
+ * }
+ * }</pre>
+ *
+ * <p>This is where you will handle a scan result.</p>
+ *
+ * <p>Second, just call this in response to a user action somewhere to begin the scan process:</p>
+ *
+ * <pre>{@code
+ * IntentIntegrator integrator = new IntentIntegrator(yourActivity);
+ * integrator.initiateScan();
+ * }</pre>
+ *
+ * <p>Note that {@link #initiateScan()} returns an {@link AlertDialog} which is non-null if the
+ * user was prompted to download the application. This lets the calling app potentially manage the dialog.
+ * In particular, ideally, the app dismisses the dialog if it's still active in its {@link Activity#onPause()}
+ * method.</p>
+ * 
+ * <p>You can use {@link #setTitle(String)} to customize the title of this download prompt dialog (or, use
+ * {@link #setTitleByID(int)} to set the title by string resource ID.) Likewise, the prompt message, and
+ * yes/no button labels can be changed.</p>
+ *
+ * <p>Finally, you can use {@link #addExtra(String, Object)} to add more parameters to the Intent used
+ * to invoke the scanner. This can be used to set additional options not directly exposed by this
+ * simplified API.</p>
+ * 
+ * <p>By default, this will only allow applications that are known to respond to this intent correctly
+ * do so. The apps that are allowed to response can be set with {@link #setTargetApplications(List)}.
+ * For example, set to {@link #TARGET_BARCODE_SCANNER_ONLY} to only target the Barcode Scanner app itself.</p>
+ *
+ * <h2>Sharing text via barcode</h2>
+ *
+ * <p>To share text, encoded as a QR Code on-screen, similarly, see {@link #shareText(CharSequence)}.</p>
+ *
+ * <p>Some code, particularly download integration, was contributed from the Anobiit application.</p>
+ *
+ * <h2>Enabling experimental barcode formats</h2>
+ *
+ * <p>Some formats are not enabled by default even when scanning with {@link #ALL_CODE_TYPES}, such as
+ * PDF417. Use {@link #initiateScan(Collection)} with
+ * a collection containing the names of formats to scan for explicitly, like "PDF_417", to use such
+ * formats.</p>
+ *
+ * @author Sean Owen
+ * @author Fred Lin
+ * @author Isaac Potoczny-Jones
+ * @author Brad Drehmer
+ * @author gcstang
+ */
+public class IntentIntegrator {
+
+  public static final int REQUEST_CODE = 0x0000c0de; // Only use bottom 16 bits
+  private static final String TAG = IntentIntegrator.class.getSimpleName();
+
+  public static final String DEFAULT_TITLE = "Install Barcode Scanner?";
+  public static final String DEFAULT_MESSAGE =
+      "This application requires Barcode Scanner. Would you like to install it?";
+  public static final String DEFAULT_YES = "Yes";
+  public static final String DEFAULT_NO = "No";
+
+  private static final String BS_PACKAGE = "com.google.zxing.client.android";
+  private static final String BSPLUS_PACKAGE = "com.srowen.bs.android";
+
+  // supported barcode formats
+  public static final Collection<String> PRODUCT_CODE_TYPES = list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "RSS_14");
+  public static final Collection<String> ONE_D_CODE_TYPES =
+      list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "CODE_39", "CODE_93", "CODE_128",
+           "ITF", "RSS_14", "RSS_EXPANDED");
+  public static final Collection<String> QR_CODE_TYPES = Collections.singleton("QR_CODE");
+  public static final Collection<String> DATA_MATRIX_TYPES = Collections.singleton("DATA_MATRIX");
+
+  public static final Collection<String> ALL_CODE_TYPES = null;
+  
+  public static final List<String> TARGET_BARCODE_SCANNER_ONLY = Collections.singletonList(BS_PACKAGE);
+  public static final List<String> TARGET_ALL_KNOWN = list(
+          BSPLUS_PACKAGE,             // Barcode Scanner+
+          BSPLUS_PACKAGE + ".simple", // Barcode Scanner+ Simple
+          BS_PACKAGE                  // Barcode Scanner          
+          // What else supports this intent?
+      );
+  
+  private final Activity activity;
+  private final Fragment fragment;
+
+  private String title;
+  private String message;
+  private String buttonYes;
+  private String buttonNo;
+  private List<String> targetApplications;
+  private final Map<String,Object> moreExtras = new HashMap<String,Object>(3);
+
+  /**
+   * @param activity {@link Activity} invoking the integration
+   */
+  public IntentIntegrator(Activity activity) {
+    this.activity = activity;
+    this.fragment = null;
+    initializeConfiguration();
+  }
+
+  /**
+   * @param fragment {@link Fragment} invoking the integration.
+   *  {@link #startActivityForResult(Intent, int)} will be called on the {@link Fragment} instead
+   *  of an {@link Activity}
+   */
+  public IntentIntegrator(Fragment fragment) {
+    this.activity = fragment.getActivity();
+    this.fragment = fragment;
+    initializeConfiguration();
+  }
+
+  private void initializeConfiguration() {
+    title = DEFAULT_TITLE;
+    message = DEFAULT_MESSAGE;
+    buttonYes = DEFAULT_YES;
+    buttonNo = DEFAULT_NO;
+    targetApplications = TARGET_ALL_KNOWN;
+  }
+  
+  public String getTitle() {
+    return title;
+  }
+  
+  public void setTitle(String title) {
+    this.title = title;
+  }
+
+  public void setTitleByID(int titleID) {
+    title = activity.getString(titleID);
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  public void setMessage(String message) {
+    this.message = message;
+  }
+
+  public void setMessageByID(int messageID) {
+    message = activity.getString(messageID);
+  }
+
+  public String getButtonYes() {
+    return buttonYes;
+  }
+
+  public void setButtonYes(String buttonYes) {
+    this.buttonYes = buttonYes;
+  }
+
+  public void setButtonYesByID(int buttonYesID) {
+    buttonYes = activity.getString(buttonYesID);
+  }
+
+  public String getButtonNo() {
+    return buttonNo;
+  }
+
+  public void setButtonNo(String buttonNo) {
+    this.buttonNo = buttonNo;
+  }
+
+  public void setButtonNoByID(int buttonNoID) {
+    buttonNo = activity.getString(buttonNoID);
+  }
+  
+  public Collection<String> getTargetApplications() {
+    return targetApplications;
+  }
+  
+  public final void setTargetApplications(List<String> targetApplications) {
+    if (targetApplications.isEmpty()) {
+      throw new IllegalArgumentException("No target applications");
+    }
+    this.targetApplications = targetApplications;
+  }
+  
+  public void setSingleTargetApplication(String targetApplication) {
+    this.targetApplications = Collections.singletonList(targetApplication);
+  }
+
+  public Map<String,?> getMoreExtras() {
+    return moreExtras;
+  }
+
+  public final void addExtra(String key, Object value) {
+    moreExtras.put(key, value);
+  }
+
+  /**
+   * Initiates a scan for all known barcode types with the default camera.
+   *
+   * @return the {@link AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise.
+   */
+  public final AlertDialog initiateScan() {
+    return initiateScan(ALL_CODE_TYPES, -1);
+  }
+  
+  /**
+   * Initiates a scan for all known barcode types with the specified camera.
+   *
+   * @param cameraId camera ID of the camera to use. A negative value means "no preference".
+   * @return the {@link AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise.
+   */
+  public final AlertDialog initiateScan(int cameraId) {
+    return initiateScan(ALL_CODE_TYPES, cameraId);
+  }
+
+  /**
+   * Initiates a scan, using the default camera, only for a certain set of barcode types, given as strings corresponding
+   * to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
+   * like {@link #PRODUCT_CODE_TYPES} for example.
+   *
+   * @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
+   * @return the {@link AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise.
+   */
+  public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats) {
+    return initiateScan(desiredBarcodeFormats, -1);
+  }
+  
+  /**
+   * Initiates a scan, using the specified camera, only for a certain set of barcode types, given as strings corresponding
+   * to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
+   * like {@link #PRODUCT_CODE_TYPES} for example.
+   *
+   * @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
+   * @param cameraId camera ID of the camera to use. A negative value means "no preference".
+   * @return the {@link AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise
+   */
+  public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats, int cameraId) {
+    Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
+    intentScan.addCategory(Intent.CATEGORY_DEFAULT);
+
+    // check which types of codes to scan for
+    if (desiredBarcodeFormats != null) {
+      // set the desired barcode types
+      StringBuilder joinedByComma = new StringBuilder();
+      for (String format : desiredBarcodeFormats) {
+        if (joinedByComma.length() > 0) {
+          joinedByComma.append(',');
+        }
+        joinedByComma.append(format);
+      }
+      intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
+    }
+
+    // check requested camera ID
+    if (cameraId >= 0) {
+      intentScan.putExtra("SCAN_CAMERA_ID", cameraId);
+    }
+
+    String targetAppPackage = findTargetAppPackage(intentScan);
+    if (targetAppPackage == null) {
+      return showDownloadDialog();
+    }
+    intentScan.setPackage(targetAppPackage);
+    intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+    intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+    attachMoreExtras(intentScan);
+    startActivityForResult(intentScan, REQUEST_CODE);
+    return null;
+  }
+
+  /**
+   * Start an activity. This method is defined to allow different methods of activity starting for
+   * newer versions of Android and for compatibility library.
+   *
+   * @param intent Intent to start.
+   * @param code Request code for the activity
+   * @see Activity#startActivityForResult(Intent, int)
+   * @see Fragment#startActivityForResult(Intent, int)
+   */
+  protected void startActivityForResult(Intent intent, int code) {
+    if (fragment == null) {
+      activity.startActivityForResult(intent, code);
+    } else {
+      fragment.startActivityForResult(intent, code);
+    }
+  }
+  
+  private String findTargetAppPackage(Intent intent) {
+    PackageManager pm = activity.getPackageManager();
+    List<ResolveInfo> availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+    if (availableApps != null) {
+      for (String targetApp : targetApplications) {
+        if (contains(availableApps, targetApp)) {
+          return targetApp;
+        }
+      }
+    }
+    return null;
+  }
+  
+  private static boolean contains(Iterable<ResolveInfo> availableApps, String targetApp) {
+    for (ResolveInfo availableApp : availableApps) {
+      String packageName = availableApp.activityInfo.packageName;
+      if (targetApp.equals(packageName)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private AlertDialog showDownloadDialog() {
+    AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
+    downloadDialog.setTitle(title);
+    downloadDialog.setMessage(message);
+    downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
+      @Override
+      public void onClick(DialogInterface dialogInterface, int i) {
+        String packageName;
+        if (targetApplications.contains(BS_PACKAGE)) {
+          // Prefer to suggest download of BS if it's anywhere in the list
+          packageName = BS_PACKAGE;
+        } else {
+          // Otherwise, first option:
+          packageName = targetApplications.get(0);
+        }
+        Uri uri = Uri.parse("market://details?id=" + packageName);
+        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+        try {
+          if (fragment == null) {
+            activity.startActivity(intent);
+          } else {
+            fragment.startActivity(intent);
+          }
+        } catch (ActivityNotFoundException anfe) {
+          // Hmm, market is not installed
+          Log.w(TAG, "Google Play is not installed; cannot install " + packageName);
+        }
+      }
+    });
+    downloadDialog.setNegativeButton(buttonNo, null);
+    downloadDialog.setCancelable(true);
+    return downloadDialog.show();
+  }
+
+
+  /**
+   * <p>Call this from your {@link Activity}'s
+   * {@link Activity#onActivityResult(int, int, Intent)} method.</p>
+   *
+   * @param requestCode request code from {@code onActivityResult()}
+   * @param resultCode result code from {@code onActivityResult()}
+   * @param intent {@link Intent} from {@code onActivityResult()}
+   * @return null if the event handled here was not related to this class, or
+   *  else an {@link IntentResult} containing the result of the scan. If the user cancelled scanning,
+   *  the fields will be null.
+   */
+  public static IntentResult parseActivityResult(int requestCode, int resultCode, Intent intent) {
+    if (requestCode == REQUEST_CODE) {
+      if (resultCode == Activity.RESULT_OK) {
+        String contents = intent.getStringExtra("SCAN_RESULT");
+        String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
+        byte[] rawBytes = intent.getByteArrayExtra("SCAN_RESULT_BYTES");
+        int intentOrientation = intent.getIntExtra("SCAN_RESULT_ORIENTATION", Integer.MIN_VALUE);
+        Integer orientation = intentOrientation == Integer.MIN_VALUE ? null : intentOrientation;
+        String errorCorrectionLevel = intent.getStringExtra("SCAN_RESULT_ERROR_CORRECTION_LEVEL");
+        return new IntentResult(contents,
+                                formatName,
+                                rawBytes,
+                                orientation,
+                                errorCorrectionLevel);
+      }
+      return new IntentResult();
+    }
+    return null;
+  }
+
+
+  /**
+   * Defaults to type "TEXT_TYPE".
+   *
+   * @param text the text string to encode as a barcode
+   * @return the {@link AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise
+   * @see #shareText(CharSequence, CharSequence)
+   */
+  public final AlertDialog shareText(CharSequence text) {
+    return shareText(text, "TEXT_TYPE");
+  }
+
+  /**
+   * Shares the given text by encoding it as a barcode, such that another user can
+   * scan the text off the screen of the device.
+   *
+   * @param text the text string to encode as a barcode
+   * @param type type of data to encode. See {@code com.google.zxing.client.android.Contents.Type} constants.
+   * @return the {@link AlertDialog} that was shown to the user prompting them to download the app
+   *   if a prompt was needed, or null otherwise
+   */
+  public final AlertDialog shareText(CharSequence text, CharSequence type) {
+    Intent intent = new Intent();
+    intent.addCategory(Intent.CATEGORY_DEFAULT);
+    intent.setAction(BS_PACKAGE + ".ENCODE");
+    intent.putExtra("ENCODE_TYPE", type);
+    intent.putExtra("ENCODE_DATA", text);
+    String targetAppPackage = findTargetAppPackage(intent);
+    if (targetAppPackage == null) {
+      return showDownloadDialog();
+    }
+    intent.setPackage(targetAppPackage);
+    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+    attachMoreExtras(intent);
+    if (fragment == null) {
+      activity.startActivity(intent);
+    } else {
+      fragment.startActivity(intent);
+    }
+    return null;
+  }
+  
+  private static List<String> list(String... values) {
+    return Collections.unmodifiableList(Arrays.asList(values));
+  }
+
+  private void attachMoreExtras(Intent intent) {
+    for (Map.Entry<String,Object> entry : moreExtras.entrySet()) {
+      String key = entry.getKey();
+      Object value = entry.getValue();
+      // Kind of hacky
+      if (value instanceof Integer) {
+        intent.putExtra(key, (Integer) value);
+      } else if (value instanceof Long) {
+        intent.putExtra(key, (Long) value);
+      } else if (value instanceof Boolean) {
+        intent.putExtra(key, (Boolean) value);
+      } else if (value instanceof Double) {
+        intent.putExtra(key, (Double) value);
+      } else if (value instanceof Float) {
+        intent.putExtra(key, (Float) value);
+      } else if (value instanceof Bundle) {
+        intent.putExtra(key, (Bundle) value);
+      } else {
+        intent.putExtra(key, value.toString());
+      }
+    }
+  }
+
+}
diff --git a/app/src/main/java/com/google/zxing/integration/android/IntentResult.java b/app/src/main/java/com/google/zxing/integration/android/IntentResult.java
new file mode 100644
index 0000000000000000000000000000000000000000..15b2e961cdfbb848218261f985dd1edbe76e8ddb
--- /dev/null
+++ b/app/src/main/java/com/google/zxing/integration/android/IntentResult.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2009 ZXing authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.integration.android;
+
+/**
+ * <p>Encapsulates the result of a barcode scan invoked through {@link IntentIntegrator}.</p>
+ *
+ * @author Sean Owen
+ */
+public final class IntentResult {
+
+  private final String contents;
+  private final String formatName;
+  private final byte[] rawBytes;
+  private final Integer orientation;
+  private final String errorCorrectionLevel;
+
+  IntentResult() {
+    this(null, null, null, null, null);
+  }
+
+  IntentResult(String contents,
+               String formatName,
+               byte[] rawBytes,
+               Integer orientation,
+               String errorCorrectionLevel) {
+    this.contents = contents;
+    this.formatName = formatName;
+    this.rawBytes = rawBytes;
+    this.orientation = orientation;
+    this.errorCorrectionLevel = errorCorrectionLevel;
+  }
+
+  /**
+   * @return raw content of barcode
+   */
+  public String getContents() {
+    return contents;
+  }
+
+  /**
+   * @return name of format, like "QR_CODE", "UPC_A". See {@code BarcodeFormat} for more format names.
+   */
+  public String getFormatName() {
+    return formatName;
+  }
+
+  /**
+   * @return raw bytes of the barcode content, if applicable, or null otherwise
+   */
+  public byte[] getRawBytes() {
+    return rawBytes;
+  }
+
+  /**
+   * @return rotation of the image, in degrees, which resulted in a successful scan. May be null.
+   */
+  public Integer getOrientation() {
+    return orientation;
+  }
+
+  /**
+   * @return name of the error correction level used in the barcode, if applicable
+   */
+  public String getErrorCorrectionLevel() {
+    return errorCorrectionLevel;
+  }
+  
+  @Override
+  public String toString() {
+    int rawBytesLength = rawBytes == null ? 0 : rawBytes.length;
+    return "Format: " + formatName + '\n' +
+        "Contents: " + contents + '\n' +
+        "Raw bytes: (" + rawBytesLength + " bytes)\n" +
+        "Orientation: " + orientation + '\n' +
+        "EC level: " + errorCorrectionLevel + '\n';
+  }
+
+}
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 b7bab7f77977a1aa26fafa512d3fc32ab56f05fc..7634801cb6e7fb36ae9b45d9a5c01e6a76271aae 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java
@@ -75,6 +75,8 @@ import info.nightscout.android.model.medtronicNg.PumpInfo;
 import info.nightscout.android.model.medtronicNg.PumpStatusEvent;
 import info.nightscout.android.settings.SettingsActivity;
 import info.nightscout.android.upload.nightscout.NightscoutUploadIntentService;
+import info.nightscout.android.utils.ConfigurationStore;
+import info.nightscout.android.utils.DataStore;
 import io.realm.Realm;
 import io.realm.RealmChangeListener;
 import io.realm.RealmResults;
@@ -85,25 +87,15 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
     private static final String TAG = MainActivity.class.getSimpleName();
     public static final float MMOLXLFACTOR = 18.016f;
 
-    public static int batLevel = 0;
-    public static boolean reducePollOnPumpAway = false;
-    public static long pollInterval = MedtronicCnlIntentService.POLL_PERIOD_MS;
-    public static long lowBatteryPollInterval = MedtronicCnlIntentService.LOW_BATTERY_POLL_PERIOD_MS;
+    private DataStore dataStore = DataStore.getInstance();
+    private ConfigurationStore configurationStore = ConfigurationStore.getInstance();
 
-    private static long activePumpMac;
     private int chartZoom = 3;
     private boolean hasZoomedChart = false;
-
     private NumberFormat sgvFormatter;
-    private static boolean mmolxl;
-    private static boolean mmolxlDecimals;
-
-    public static long timeLastGoodSGV = 0;
-    public static short pumpBattery = 0;
-    public static int countUnavailableSGV = 0;
 
-    boolean mEnableCgmService = true;
-    SharedPreferences prefs = null;
+    private boolean mEnableCgmService = true;
+    private SharedPreferences prefs = null;
     private PumpInfo mActivePump;
     private TextView mTextViewLog; // This will eventually move to a status page.
     private GraphView mChart;
@@ -122,22 +114,23 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
      */
     public static long getNextPoll(PumpStatusEvent pumpStatusData) {
         long nextPoll = pumpStatusData.getEventDate().getTime() + pumpStatusData.getPumpTimeOffset(),
-            now = System.currentTimeMillis();
+            now = System.currentTimeMillis(),
+            pollInterval = ConfigurationStore.getInstance().getPollInterval();
 
         // align to next poll slot
         if (nextPoll + 2 * 60 * 60 * 1000 < now) { // last event more than 2h old -> could be a calibration
             nextPoll = System.currentTimeMillis() + 1000;
         } else {
             // align to poll interval
-            nextPoll += (((now - nextPoll) / MainActivity.pollInterval)) * MainActivity.pollInterval
+            nextPoll += (((now - nextPoll) / pollInterval)) * pollInterval
                     + MedtronicCnlIntentService.POLL_GRACE_PERIOD_MS;
             if (pumpStatusData.getBatteryPercentage() > 25) {
                 // poll every 5 min
-                nextPoll += MainActivity.pollInterval;
+                nextPoll += pollInterval;
             } else {
                 // if pump battery seems to be empty reduce polling to save battery (every 15 min)
                 //TODO add message & document it
-                nextPoll += MainActivity.lowBatteryPollInterval;
+                nextPoll += ConfigurationStore.getInstance().getLowBatteryPollInterval();
             }
         }
 
@@ -145,9 +138,10 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
     }
 
     public static String strFormatSGV(float sgvValue) {
-        if (mmolxl) {
+        ConfigurationStore configurationStore = ConfigurationStore.getInstance();
+        if (configurationStore.isMmolxl()) {
             NumberFormat sgvFormatter;
-            if (mmolxlDecimals) {
+            if (configurationStore.isMmolxlDecimals()) {
                 sgvFormatter = new DecimalFormat("0.00");
             } else {
                 sgvFormatter = new DecimalFormat("0.0");
@@ -164,6 +158,12 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
         super.onCreate(savedInstanceState);
 
         mRealm = Realm.getDefaultInstance();
+
+        RealmResults<PumpStatusEvent> data = mRealm.where(PumpStatusEvent.class)
+                .findAllSorted("eventDate", Sort.DESCENDING);
+        if (data.size() > 0)
+            dataStore.setLastPumpStatus(data.first());
+
         mNightscoutUploadService = new Intent(this, NightscoutUploadIntentService.class);
 
         setContentView(R.layout.activity_main);
@@ -176,15 +176,16 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
         }
 
         // setup preferences
-        MainActivity.pollInterval = Long.parseLong(prefs.getString("pollInterval", Long.toString(MedtronicCnlIntentService.POLL_PERIOD_MS)));
-        MainActivity.lowBatteryPollInterval = Long.parseLong(prefs.getString("lowBatPollInterval", Long.toString(MedtronicCnlIntentService.LOW_BATTERY_POLL_PERIOD_MS)));
-        MainActivity.reducePollOnPumpAway = prefs.getBoolean("doublePollOnPumpAway", false);
+        configurationStore.setPollInterval(Long.parseLong(prefs.getString("pollInterval", Long.toString(MedtronicCnlIntentService.POLL_PERIOD_MS))));
+        configurationStore.setLowBatteryPollInterval(Long.parseLong(prefs.getString("lowBatPollInterval", Long.toString(MedtronicCnlIntentService.LOW_BATTERY_POLL_PERIOD_MS))));
+        configurationStore.setReducePollOnPumpAway(prefs.getBoolean("doublePollOnPumpAway", false));
+
         chartZoom = Integer.parseInt(prefs.getString("chartZoom", "3"));
-        mmolxl = prefs.getBoolean("mmolxl", false);
-        mmolxlDecimals = prefs.getBoolean("mmolDecimals", false);
+        configurationStore.setMmolxl(prefs.getBoolean("mmolxl", false));
+        configurationStore.setMmolxlDecimals(prefs.getBoolean("mmolDecimals", false));
 
-        if (mmolxl) {
-            if (mmolxlDecimals)
+        if (configurationStore.isMmolxl()) {
+            if (configurationStore.isMmolxlDecimals())
                 sgvFormatter = new DecimalFormat("0.00");
             else
                 sgvFormatter = new DecimalFormat("0.0");
@@ -534,10 +535,10 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
                 startCgmService();
             }
         } else if (key.equals("mmolxl") || key.equals("mmolDecimals")) {
-            mmolxl = sharedPreferences.getBoolean("mmolxl", false);
-            mmolxlDecimals = sharedPreferences.getBoolean("mmolDecimals", false);
-            if (mmolxl) {
-                if (mmolxlDecimals)
+            configurationStore.setMmolxl(sharedPreferences.getBoolean("mmolxl", false));
+            configurationStore.setMmolxlDecimals(sharedPreferences.getBoolean("mmolDecimals", false));
+            if (configurationStore.isMmolxl()) {
+                if (configurationStore.isMmolxlDecimals())
                     sgvFormatter = new DecimalFormat("0.00");
                 else
                     sgvFormatter = new DecimalFormat("0.0");
@@ -546,13 +547,13 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
             }
             refreshDisplay();
         } else if (key.equals("pollInterval")) {
-            MainActivity.pollInterval = Long.parseLong(sharedPreferences.getString("pollInterval",
-                    Long.toString(MedtronicCnlIntentService.POLL_PERIOD_MS)));
+            configurationStore.setPollInterval(Long.parseLong(sharedPreferences.getString("pollInterval",
+                    Long.toString(MedtronicCnlIntentService.POLL_PERIOD_MS))));
         } else if (key.equals("lowBatPollInterval")) {
-            MainActivity.lowBatteryPollInterval = Long.parseLong(sharedPreferences.getString("lowBatPollInterval",
-                    Long.toString(MedtronicCnlIntentService.LOW_BATTERY_POLL_PERIOD_MS)));
+            configurationStore.setLowBatteryPollInterval(Long.parseLong(sharedPreferences.getString("lowBatPollInterval",
+                    Long.toString(MedtronicCnlIntentService.LOW_BATTERY_POLL_PERIOD_MS))));
         } else if (key.equals("doublePollOnPumpAway")) {
-            MainActivity.reducePollOnPumpAway = sharedPreferences.getBoolean("doublePollOnPumpAway", false);
+            configurationStore.setReducePollOnPumpAway(sharedPreferences.getBoolean("doublePollOnPumpAway", false));
         } else if (key.equals("chartZoom")) {
             chartZoom = Integer.parseInt(sharedPreferences.getString("chartZoom", "3"));
             hasZoomedChart = false;
@@ -601,11 +602,8 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
         }
     }
 
-    public static void setActivePumpMac(long pumpMac) {
-        activePumpMac = pumpMac;
-    }
-
     private PumpInfo getActivePump() {
+        long activePumpMac = dataStore.getActivePumpMac();
         if (activePumpMac != 0L && (mActivePump == null || !mActivePump.isValid() || mActivePump.getPumpMac() != activePumpMac)) {
             if (mActivePump != null) {
                 // remove listener on old pump
@@ -615,7 +613,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
 
             PumpInfo pump = mRealm
                     .where(PumpInfo.class)
-                    .equalTo("pumpMac", MainActivity.activePumpMac)
+                    .equalTo("pumpMac", activePumpMac)
                     .findFirst();
 
             if (pump != null && pump.isValid()) {
@@ -736,7 +734,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
             TextView textViewBg = (TextView) findViewById(R.id.textview_bg);
             TextView textViewBgTime = (TextView) findViewById(R.id.textview_bg_time);
             TextView textViewUnits = (TextView) findViewById(R.id.textview_units);
-            if (mmolxl) {
+            if (configurationStore.isMmolxl()) {
                 textViewUnits.setText(R.string.text_unit_mmolxl);
             } else {
                 textViewUnits.setText(R.string.text_unit_mgxdl);
@@ -747,23 +745,20 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
             // Get the most recently written CGM record for the active pump.
             PumpStatusEvent pumpStatusData = null;
 
-            PumpInfo pump = getActivePump();
+            // ignoring activePump atm
+            //PumpInfo pump = getActivePump();
 
-            if (pump != null && pump.isValid() && pump.getPumpHistory().size() > 0) {
-                Log.d(TAG, "history display refresh size: " + pump.getPumpHistory().size());
-                Log.d(TAG, "history display refresh date: " + pump.getPumpHistory().last().getEventDate());
-                pumpStatusData = pump.getPumpHistory().last();
+            if (dataStore.getLastPumpStatus().getEventDate().getTime() > 0) {
+                pumpStatusData = dataStore.getLastPumpStatus();
             }
 
-            // FIXME - grab the last item from the activePump's getPumpHistory
             updateChart(mRealm.where(PumpStatusEvent.class)
                     .greaterThan("eventDate", new Date(System.currentTimeMillis() - 1000*60*60*24))
                     .findAllSorted("eventDate", Sort.ASCENDING));
 
             if (pumpStatusData != null) {
-
                 String sgvString;
-                if (mmolxl) {
+                if (configurationStore.isMmolxl()) {
                     float fBgValue = (float) pumpStatusData.getSgv();
                     sgvString = sgvFormatter.format(fBgValue / MMOLXLFACTOR);
                     Log.d(TAG, sgvString + " mmol/L");
@@ -826,7 +821,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
                 mChart.getViewport().setMinX(left);
 
                 mChart.getViewport().setYAxisBoundsManual(true);
-                if (mmolxl) {
+                if (configurationStore.isMmolxl()) {
                     mChart.getViewport().setMinY(80 / MMOLXLFACTOR);
                     mChart.getViewport().setMaxY(120 / MMOLXLFACTOR);
                 } else {
@@ -845,7 +840,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
                 // turn your data into Entry objects
                 int sgv = pumpStatus.getSgv();
 
-                if (mmolxl) {
+                if (configurationStore.isMmolxl()) {
                     entries[pos++] = new DataPoint(pumpStatus.getEventDate(), (float) pumpStatus.getSgv() / MMOLXLFACTOR);
                 } else {
                     entries[pos++] = new DataPoint(pumpStatus.getEventDate(), (float) pumpStatus.getSgv());
@@ -883,6 +878,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
                     @Override
                     public void draw(Canvas canvas, Paint paint, float x, float y, DataPointInterface dataPoint) {
                         double sgv = dataPoint.getY();
+                        boolean mmolxl = configurationStore.isMmolxl();
                         if (sgv < (mmolxl?4.5:80))
                             paint.setColor(Color.RED);
                         else if (sgv <= (mmolxl?10:180))
@@ -972,7 +968,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
             if (arg1.getAction().equalsIgnoreCase(Intent.ACTION_BATTERY_LOW)
                     || arg1.getAction().equalsIgnoreCase(Intent.ACTION_BATTERY_CHANGED)
                     || arg1.getAction().equalsIgnoreCase(Intent.ACTION_BATTERY_OKAY)) {
-                batLevel = arg1.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+                dataStore.setUplooaderBatteryLevel(arg1.getIntExtra(BatteryManager.EXTRA_LEVEL, 0));
             }
         }
     }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/MedtronicCnlReader.java b/app/src/main/java/info/nightscout/android/medtronic/MedtronicCnlReader.java
index 6763c82d683bcd7daf32ba61f95294216a4a2a70..539e28d298f8aaf801e4bc997ee180c0508719b9 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/MedtronicCnlReader.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/MedtronicCnlReader.java
@@ -175,7 +175,8 @@ public class MedtronicCnlReader {
         // CNL<-->PUMP comms can have occasional short lived noise causing errors, retrying once catches this
         try {
             PumpTimeResponseMessage response = new PumpTimeRequestMessage(mPumpSession).send(mDevice);
-            Log.d(TAG, "Finished getPumpTime with date " + response.getPumpTime());
+            // ignore the first error. Just log retry
+            // Log.d(TAG, "Finished getPumpTime with date " + response.getPumpTime());
             return response.getPumpTime();
         } catch (UnexpectedMessageException e) {
             Log.e(TAG, "Unexpected Message", e);
@@ -196,7 +197,7 @@ public class MedtronicCnlReader {
         try {
             PumpStatusResponseMessage response = new PumpStatusRequestMessage(mPumpSession).send(mDevice);
             response.updatePumpRecord(pumpRecord);
-            Log.d(TAG, "Finished updatePumpStatus");
+            Log.d(TAG, "Finished updatePumpStatus: " + pumpRecord.toString());
             return pumpRecord;
         } catch (UnexpectedMessageException e) {
             Log.e(TAG, "Unexpected Message", e);
@@ -207,7 +208,7 @@ public class MedtronicCnlReader {
         PumpStatusResponseMessage response = new PumpStatusRequestMessage(mPumpSession).send(mDevice);
         response.updatePumpRecord(pumpRecord);
 
-        Log.d(TAG, "Finished updatePumpStatus");
+        Log.d(TAG, "Finished updatePumpStatus: " + pumpRecord.toString());
 
         return pumpRecord;
     }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusResponseMessage.java
index f97a73934acf42bcb5ffffb6f778a440af158563..31b6667cca40f641f1e5c8521e5bd828a478e53b 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusResponseMessage.java
@@ -14,6 +14,7 @@ import info.nightscout.android.medtronic.exception.ChecksumException;
 import info.nightscout.android.medtronic.exception.EncryptionException;
 import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
 import info.nightscout.android.model.medtronicNg.PumpStatusEvent;
+import info.nightscout.android.utils.DataStore;
 import info.nightscout.android.utils.HexDump;
 
 /**
@@ -197,6 +198,10 @@ public class PumpStatusResponseMessage extends MedtronicSendMessageResponseMessa
 
         // Recent Bolus Wizard BGL
         pumpRecord.setRecentBolusWizard(recentBolusWizard);
-        pumpRecord.setBolusWizardBGL(bolusWizardBGL); // In mg/DL
+        if (/*recentBolusWizard && */activeInsulin > DataStore.getInstance().getLastPumpStatus().getActiveInsulin()) {  // there is a BolusWizard usage & the IOB increaseed
+            pumpRecord.setBolusWizardBGL(bolusWizardBGL); // In mg/DL
+        } else {
+            pumpRecord.setBolusWizardBGL(0); // In mg/DL
+        }
     }
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmManager.java b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmManager.java
index 08737107d34864e8164ba6e04f25f4b327ed4c5a..b4f2e153000ada1bbf5932ecbf321dcaa6e5bd57 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmManager.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmManager.java
@@ -11,6 +11,7 @@ import android.util.Log;
 import java.util.Date;
 
 import info.nightscout.android.medtronic.MainActivity;
+import info.nightscout.android.utils.ConfigurationStore;
 
 /**
  * Created by lgoedhart on 14/07/2016.
@@ -81,7 +82,7 @@ public class MedtronicCnlAlarmManager {
     // restarting the alarm after MedtronicCnlIntentService.POLL_PERIOD_MS from now
     public static void restartAlarm() {
         //setAlarmAfterMillis(MainActivity.pollInterval + MedtronicCnlIntentService.POLL_GRACE_PERIOD_MS);
-        setAlarmAfterMillis(MainActivity.pollInterval); // grace already accounted for when using current intent time to set default restart
+        setAlarmAfterMillis(ConfigurationStore.getInstance().getPollInterval()); // grace already accounted for when using current intent time to set default restart
     }
 
     // Cancel the alarm.
diff --git a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
index 3d9e0eb7cea5e6e3fbdf9b866e6a1ad59b32ad8e..bf08008fe59b2fcc4864688476b55dbeceb25e28 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
@@ -35,6 +35,8 @@ import info.nightscout.android.model.medtronicNg.ContourNextLinkInfo;
 import info.nightscout.android.model.medtronicNg.PumpInfo;
 import info.nightscout.android.model.medtronicNg.PumpStatusEvent;
 import info.nightscout.android.upload.nightscout.NightscoutUploadReceiver;
+import info.nightscout.android.utils.ConfigurationStore;
+import info.nightscout.android.utils.DataStore;
 import info.nightscout.android.xdrip_plus.XDripPlusUploadReceiver;
 import io.realm.Realm;
 import io.realm.RealmResults;
@@ -48,10 +50,13 @@ public class MedtronicCnlIntentService extends IntentService {
     // Number of additional seconds to wait after the next expected CGM poll, so that we don't interfere with CGM radio comms.
     public final static long POLL_GRACE_PERIOD_MS = 30000L;
     private static final String TAG = MedtronicCnlIntentService.class.getSimpleName();
+
     private UsbHidDriver mHidDevice;
     private Context mContext;
     private NotificationManagerCompat nm;
     private UsbManager mUsbManager;
+    private DataStore dataStore = DataStore.getInstance();
+    private ConfigurationStore configurationStore = ConfigurationStore.getInstance();
 
     public MedtronicCnlIntentService() {
         super(MedtronicCnlIntentService.class.getName());
@@ -100,10 +105,14 @@ public class MedtronicCnlIntentService extends IntentService {
     protected void onHandleIntent(Intent intent) {
         Log.d(TAG, "onHandleIntent called");
 
-        long timePollStarted = System.currentTimeMillis();
-        long timePollExpected = timePollStarted;
-        if (MainActivity.timeLastGoodSGV != 0) {
-            timePollExpected = MainActivity.timeLastGoodSGV + POLL_PERIOD_MS + POLL_GRACE_PERIOD_MS + (POLL_PERIOD_MS * ((timePollStarted - 1000L - (MainActivity.timeLastGoodSGV + POLL_GRACE_PERIOD_MS)) / POLL_PERIOD_MS));
+        long timePollStarted = System.currentTimeMillis(),
+                timePollExpected = timePollStarted,
+                timeLastGoodSGV = dataStore.getLastPumpStatus().getEventDate().getTime();
+
+        short pumpBatteryLevel = dataStore.getLastPumpStatus().getBatteryPercentage();
+
+        if (timeLastGoodSGV != 0) {
+            timePollExpected = timeLastGoodSGV + POLL_PERIOD_MS + POLL_GRACE_PERIOD_MS + (POLL_PERIOD_MS * ((timePollStarted - 1000L - (timeLastGoodSGV + POLL_GRACE_PERIOD_MS)) / POLL_PERIOD_MS));
         }
 
         // avoid polling when too close to sensor-pump comms
@@ -114,9 +123,9 @@ public class MedtronicCnlIntentService extends IntentService {
             return;
         }
 
-        long pollInterval = MainActivity.pollInterval;
-        if ((MainActivity.pumpBattery > 0) && (MainActivity.pumpBattery <= 25)) {
-            pollInterval = MainActivity.lowBatteryPollInterval;
+        long pollInterval = configurationStore.getPollInterval();
+        if ((pumpBatteryLevel > 0) && (pumpBatteryLevel <= 25)) {
+            pollInterval = configurationStore.getLowBatteryPollInterval();
         }
 
         if (!hasUsbHostFeature()) {
@@ -216,9 +225,10 @@ public class MedtronicCnlIntentService extends IntentService {
                 if (radioChannel == 0) {
                     sendStatus("Could not communicate with the 640g. Are you near the pump?");
                     Log.i(TAG, "Could not communicate with the 640g. Are you near the pump?");
-                    pollInterval = MainActivity.pollInterval / (MainActivity.reducePollOnPumpAway?2L:1L); // reduce polling interval to half until pump is available
+                    pollInterval = configurationStore.getPollInterval() / (configurationStore.isReducePollOnPumpAway()?2L:1L); // reduce polling interval to half until pump is available
                 } else {
-                    setActivePumpMac(pumpMAC);
+                    dataStore.setActivePumpMac(pumpMAC);
+
                     activePump.setLastRadioChannel(radioChannel);
                     sendStatus(String.format(Locale.getDefault(), "Connected on channel %d  RSSI: %d%%", (int) radioChannel, cnlReader.getPumpSession().getRadioRSSIpercentage()));
                     Log.d(TAG, String.format("Connected to Contour Next Link on channel %d.", (int) radioChannel));
@@ -242,7 +252,6 @@ public class MedtronicCnlIntentService extends IntentService {
                     cnlReader.updatePumpStatus(pumpRecord);
 
                     if (pumpRecord.getSgv() != 0) {
-
                         String offsetSign = "";
                         if (pumpOffset > 0) {
                             offsetSign = "+";
@@ -250,14 +259,14 @@ public class MedtronicCnlIntentService extends IntentService {
                         sendStatus("SGV: " + MainActivity.strFormatSGV(pumpRecord.getSgv()) + "  At: " + df.format(pumpRecord.getEventDate().getTime()) + "  Pump: " + offsetSign + (pumpOffset / 1000L) + "sec");  //note: event time is currently stored with offset
 
                         // Check if pump sent old event when new expected and schedule a re-poll
-                        if (((pumpRecord.getEventDate().getTime() - MainActivity.timeLastGoodSGV) < 5000L) && ((timePollExpected - timePollStarted) < 5000L)) {
+                        if (((pumpRecord.getEventDate().getTime() - dataStore.getLastPumpStatus().getEventDate().getTime()) < 5000L) && ((timePollExpected - timePollStarted) < 5000L)) {
                             pollInterval = 90000L; // polling interval set to 90 seconds
                             sendStatus("Pump sent old SGV event, re-polling...");
                         }
 
-                        MainActivity.timeLastGoodSGV =  pumpRecord.getEventDate().getTime(); // track last good sgv event time
-                        MainActivity.pumpBattery =  pumpRecord.getBatteryPercentage(); // track pump battery
-                        MainActivity.countUnavailableSGV = 0; // reset unavailable sgv count
+                        //MainActivity.timeLastGoodSGV =  pumpRecord.getEventDate().getTime(); // track last good sgv event time
+                        //MainActivity.pumpBattery =  pumpRecord.getBatteryPercentage(); // track pump battery
+                        dataStore.clearUnavailableSGVCount(); // reset unavailable sgv count
 
                         // Check that the record doesn't already exist before committing
                         RealmResults<PumpStatusEvent> checkExistingRecords = activePump.getPumpHistory()
@@ -269,13 +278,12 @@ public class MedtronicCnlIntentService extends IntentService {
                         // There should be the 1 record we've already added in this transaction.
                         if (checkExistingRecords.size() == 0) {
                             activePump.getPumpHistory().add(pumpRecord);
+                            dataStore.setLastPumpStatus(pumpRecord);
                         }
 
-                        Log.d(TAG, "history reading size: " + activePump.getPumpHistory().size());
-                        Log.d(TAG, "history reading date: " + activePump.getPumpHistory().last().getEventDate());
                     } else {
                         sendStatus("SGV: unavailable from pump");
-                        MainActivity.countUnavailableSGV ++; // poll clash detection
+                        dataStore.incUnavailableSGVCount(); // poll clash detection
                     }
 
                     realm.commitTransaction();
@@ -286,11 +294,11 @@ public class MedtronicCnlIntentService extends IntentService {
             } catch (UnexpectedMessageException e) {
                 Log.e(TAG, "Unexpected Message", e);
                 sendStatus("Communication Error: " + e.getMessage());
-                pollInterval = MainActivity.pollInterval / (MainActivity.reducePollOnPumpAway?2L:1L);
+                pollInterval = configurationStore.getPollInterval() / (configurationStore.isReducePollOnPumpAway()?2L:1L);
             } catch (TimeoutException e) {
                 Log.e(TAG, "Timeout communicating with the Contour Next Link.", e);
                 sendStatus("Timeout communicating with the Contour Next Link.");
-                pollInterval = MainActivity.pollInterval / (MainActivity.reducePollOnPumpAway?2L:1L);
+                pollInterval = configurationStore.getPollInterval() / (configurationStore.isReducePollOnPumpAway()?2L:1L);
             } catch (NoSuchAlgorithmException e) {
                 Log.e(TAG, "Could not determine CNL HMAC", e);
                 sendStatus("Error connecting to Contour Next Link: Hashing error.");
@@ -331,8 +339,8 @@ public class MedtronicCnlIntentService extends IntentService {
 
             // smart polling and pump-sensor poll clash detection
             long lastActualPollTime = timePollStarted;
-            if (MainActivity.timeLastGoodSGV > 0) {
-                lastActualPollTime = MainActivity.timeLastGoodSGV + POLL_GRACE_PERIOD_MS + (POLL_PERIOD_MS * ((System.currentTimeMillis() - (MainActivity.timeLastGoodSGV + POLL_GRACE_PERIOD_MS)) / POLL_PERIOD_MS));
+            if (timeLastGoodSGV > 0) {
+                lastActualPollTime = timeLastGoodSGV + POLL_GRACE_PERIOD_MS + (POLL_PERIOD_MS * ((System.currentTimeMillis() - (timeLastGoodSGV + POLL_GRACE_PERIOD_MS)) / POLL_PERIOD_MS));
             }
             long nextActualPollTime = lastActualPollTime + POLL_PERIOD_MS;
             long nextRequestedPollTime = lastActualPollTime + pollInterval;
@@ -341,13 +349,13 @@ public class MedtronicCnlIntentService extends IntentService {
             }
             // extended unavailable SGV may be due to clash with the current polling time
             // while we wait for a good SGV event, polling is auto adjusted by offsetting the next poll based on miss count
-            if (MainActivity.countUnavailableSGV > 0) {
-                if (MainActivity.timeLastGoodSGV == 0) {
+            if (dataStore.getUnavailableSGVCount() > 0) {
+                if (timeLastGoodSGV == 0) {
                     nextRequestedPollTime += POLL_PERIOD_MS / 5L; // if there is a uploader/sensor poll clash on startup then this will push the next attempt out by 60 seconds
                 }
-                else if (MainActivity.countUnavailableSGV > 2) {
-                    sendStatus("Warning: No SGV available from pump for " + MainActivity.countUnavailableSGV + " attempts");
-                    nextRequestedPollTime += ((long) ((MainActivity.countUnavailableSGV - 2) % 5)) * (POLL_PERIOD_MS / 10L); // adjust poll time in 1/10 steps to avoid potential poll clash (max adjustment at 5/10)
+                else if (dataStore.getUnavailableSGVCount() > 2) {
+                    sendStatus("Warning: No SGV available from pump for " +dataStore.getUnavailableSGVCount() + " attempts");
+                    nextRequestedPollTime += ((long) ((dataStore.getUnavailableSGVCount() - 2) % 5)) * (POLL_PERIOD_MS / 10L); // adjust poll time in 1/10 steps to avoid potential poll clash (max adjustment at 5/10)
                 }
             }
             MedtronicCnlAlarmManager.setAlarm(nextRequestedPollTime);
@@ -357,10 +365,6 @@ public class MedtronicCnlIntentService extends IntentService {
         }
     }
 
-    private void setActivePumpMac(long pumpMAC) {
-        MainActivity.setActivePumpMac(pumpMAC);
-    }
-
     // reliable wake alarm manager wake up for all android versions
     public static void wakeUpIntent(Context context, long wakeTime, PendingIntent pendingIntent) {
         final AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
diff --git a/app/src/main/java/info/nightscout/android/model/medtronicNg/PumpStatusEvent.java b/app/src/main/java/info/nightscout/android/model/medtronicNg/PumpStatusEvent.java
index 87adfa0667c404458262d91ce4f503e29dc9e0a1..052733e641df4ca7b18d9484167936ce4499fb79 100644
--- a/app/src/main/java/info/nightscout/android/model/medtronicNg/PumpStatusEvent.java
+++ b/app/src/main/java/info/nightscout/android/model/medtronicNg/PumpStatusEvent.java
@@ -302,4 +302,37 @@ public class PumpStatusEvent extends RealmObject  {
             }
         }
     }
+    
+    @Override
+    public String toString() {
+        return "PumpStatusEvent{" +
+                "eventDate=" + eventDate +
+                ", pumpDate=" + pumpDate +
+                ", deviceName='" + deviceName + '\'' +
+                ", suspended=" + suspended +
+                ", bolusing=" + bolusing +
+                ", deliveringInsulin=" + deliveringInsulin +
+                ", tempBasalActive=" + tempBasalActive +
+                ", cgmActive=" + cgmActive +
+                ", activeBasalPattern=" + activeBasalPattern +
+                ", basalRate=" + basalRate +
+                ", tempBasalRate=" + tempBasalRate +
+                ", tempBasalPercentage=" + tempBasalPercentage +
+                ", tempBasalMinutesRemaining=" + tempBasalMinutesRemaining +
+                ", basalUnitsDeliveredToday=" + basalUnitsDeliveredToday +
+                ", batteryPercentage=" + batteryPercentage +
+                ", reservoirAmount=" + reservoirAmount +
+                ", minutesOfInsulinRemaining=" + minutesOfInsulinRemaining +
+                ", activeInsulin=" + activeInsulin +
+                ", sgv=" + sgv +
+                ", sgvDate=" + sgvDate +
+                ", lowSuspendActive=" + lowSuspendActive +
+                ", cgmTrend='" + cgmTrend + '\'' +
+                ", recentBolusWizard=" + recentBolusWizard +
+                ", bolusWizardBGL=" + bolusWizardBGL +
+                ", pumpTimeOffset=" + pumpTimeOffset +
+                ", uploaded=" + uploaded +
+                '}';
+    }
+
 }
diff --git a/app/src/main/java/info/nightscout/android/settings/SettingsFragment.java b/app/src/main/java/info/nightscout/android/settings/SettingsFragment.java
index cbabb6a4ec7e9a497f487642f0fd8f1f06ccf3da..a6156e59c558fa3290ea0c2ee81e026bec29d9ce 100644
--- a/app/src/main/java/info/nightscout/android/settings/SettingsFragment.java
+++ b/app/src/main/java/info/nightscout/android/settings/SettingsFragment.java
@@ -1,5 +1,6 @@
 package info.nightscout.android.settings;
 
+import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.os.Bundle;
@@ -9,14 +10,32 @@ import android.preference.MultiSelectListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceCategory;
 import android.preference.PreferenceFragment;
+import android.support.annotation.Nullable;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.zxing.integration.android.IntentIntegrator;
+import com.google.zxing.integration.android.IntentResult;
+
+import java.net.MalformedURLException;
+import java.net.URL;
 
 import info.nightscout.android.R;
+import info.nightscout.android.medtronic.message.PumpTimeResponseMessage;
 
 public class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
+    private static final String TAG = SettingsFragment.class.getSimpleName();
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        final SettingsFragment that = this;
 
         /* set preferences */
         addPreferencesFromResource(R.xml.preferences);
@@ -27,13 +46,23 @@ public class SettingsFragment extends PreferenceFragment implements OnSharedPref
         }
 
         setMinBatPollIntervall((ListPreference) findPreference("pollInterval"), (ListPreference) findPreference("lowBatPollInterval"));
+
+        Preference button = findPreference("scanButton");
+        button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+            @Override
+            public boolean onPreferenceClick(Preference preference) {
+                IntentIntegrator integrator = new IntentIntegrator(that);
+                integrator.initiateScan();
+
+                return true;
+            }
+        });
     }
 
     @Override
     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
         Preference pref = findPreference(key);
 
-
         if ("pollInterval".equals(key)) {
             setMinBatPollIntervall((ListPreference) pref, (ListPreference) findPreference("lowBatPollInterval"));
         }
@@ -110,4 +139,54 @@ public class SettingsFragment extends PreferenceFragment implements OnSharedPref
             p.setSummary(editTextPref.getText());
         }
     }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+
+        if (requestCode==IntentIntegrator.REQUEST_CODE)
+        {
+            IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
+            if (scanResult != null)
+            {
+                Log.d(TAG, "scanResult returns: " + scanResult.toString());
+
+                JsonParser json = new JsonParser();
+                JsonElement jsonElement = json.parse(scanResult.getContents());
+                if (jsonElement != null && jsonElement.isJsonObject()) {
+                    jsonElement = (jsonElement.getAsJsonObject()).get("rest");
+                    if (jsonElement != null && jsonElement.isJsonObject()) {
+                        jsonElement = (jsonElement.getAsJsonObject()).get("endpoint");
+                        if (jsonElement != null && jsonElement.isJsonArray() && jsonElement.getAsJsonArray().size() > 0) {
+                            String endpoint = jsonElement.getAsJsonArray().get(0).getAsString();
+                            Log.d(TAG, "endpoint: " + endpoint);
+
+                            try {
+                                URL uri = new URL(endpoint);
+
+                                StringBuffer url = new StringBuffer(uri.getProtocol())
+                                        .append("://").append(uri.getHost());
+                                if (uri.getPort() > -1)
+                                    url.append(":").append(uri.getPort());
+
+                                EditTextPreference editPref = (EditTextPreference) findPreference(getString(R.string.preference_nightscout_url));
+                                editPref.setText(url.toString());
+                                updatePrefSummary(editPref);
+
+                                editPref = (EditTextPreference) findPreference(getString(R.string.preference_api_secret));
+                                editPref.setText(uri.getUserInfo());
+                                updatePrefSummary(editPref);
+                            } catch (MalformedURLException e) {
+                                Log.w (TAG, e.getMessage());
+                            }
+
+                        }
+                    }
+                }
+            }
+            else
+            {
+                Log.d(TAG, "scanResult is null.");
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/info/nightscout/android/upload/nightscout/NightScoutUpload.java b/app/src/main/java/info/nightscout/android/upload/nightscout/NightScoutUpload.java
index 790bf02e01b765e925623dceee1bef26d5c3e5c5..4fe14f2a8542bba2bbd0d346a6faf3663204e003 100644
--- a/app/src/main/java/info/nightscout/android/upload/nightscout/NightScoutUpload.java
+++ b/app/src/main/java/info/nightscout/android/upload/nightscout/NightScoutUpload.java
@@ -27,6 +27,9 @@ import info.nightscout.api.DeviceEndpoints.Battery;
 import info.nightscout.api.DeviceEndpoints.PumpStatus;
 import info.nightscout.api.DeviceEndpoints.PumpInfo;
 import info.nightscout.api.DeviceEndpoints.DeviceStatus;
+import okhttp3.ResponseBody;
+import retrofit2.Response;
+import retrofit2.Retrofit;
 
 class NightScoutUpload {
 
@@ -59,7 +62,7 @@ class NightScoutUpload {
         UploadApi uploadApi = new UploadApi(baseURL, formToken(secret));
 
         boolean eventsUploaded = uploadEvents(uploadApi.getGlucoseEndpoints(),
-                uploadApi.getBolusApi(),
+                uploadApi.getBolusEndpoints(),
                 records);
 
         boolean deviceStatusUploaded = uploadDeviceStatus(uploadApi.getDeviceEndpoints(),
@@ -103,15 +106,16 @@ class NightScoutUpload {
 
         }
 
+        boolean uploaded = true;
         if (glucoseEntries.size() > 0) {
-            glucoseEndpoints.sendEntries(glucoseEntries).execute();
+            Response<ResponseBody> result = glucoseEndpoints.sendEntries(glucoseEntries).execute();
+            uploaded = uploaded && result.isSuccessful();
         }
         if (bolusEntries.size() > 0) {
-            bolusEndpoints.sendEntries(bolusEntries).execute();
+            Response<ResponseBody> result = bolusEndpoints.sendEntries(bolusEntries).execute();
+            uploaded = uploaded && result.isSuccessful();
         }
-
-
-        return true;
+        return uploaded;
     }
 
     private boolean uploadDeviceStatus(DeviceEndpoints deviceEndpoints,
@@ -152,11 +156,13 @@ class NightScoutUpload {
             deviceEntries.add(deviceStatus);
         }
 
+        boolean uploaded = true;
         for (DeviceStatus status : deviceEntries) {
-            deviceEndpoints.sendDeviceStatus(status).execute();
+            Response<ResponseBody> result = deviceEndpoints.sendDeviceStatus(status).execute();
+            uploaded = uploaded && result.isSuccessful();
         }
 
-        return true;
+        return uploaded;
     }
 
     @NonNull
diff --git a/app/src/main/java/info/nightscout/android/upload/nightscout/NightscoutUploadIntentService.java b/app/src/main/java/info/nightscout/android/upload/nightscout/NightscoutUploadIntentService.java
index 51174e3cfe59108f0b24fc827e0f620f6363e424..74afe684f6bbaf431df34c31dd4d08009968bf25 100644
--- a/app/src/main/java/info/nightscout/android/upload/nightscout/NightscoutUploadIntentService.java
+++ b/app/src/main/java/info/nightscout/android/upload/nightscout/NightscoutUploadIntentService.java
@@ -11,8 +11,8 @@ import android.support.v4.content.LocalBroadcastManager;
 import android.util.Log;
 
 import info.nightscout.android.R;
-import info.nightscout.android.medtronic.MainActivity;
 import info.nightscout.android.model.medtronicNg.PumpStatusEvent;
+import info.nightscout.android.utils.DataStore;
 import io.realm.Realm;
 import io.realm.RealmResults;
 
@@ -67,9 +67,8 @@ public class NightscoutUploadIntentService extends IntentService {
                     Log.i(TAG, String.format("Starting upload of %s record using a REST API", records.size()));
                     String urlSetting = prefs.getString(mContext.getString(R.string.preference_nightscout_url), "");
                     String secretSetting = prefs.getString(mContext.getString(R.string.preference_api_secret), "YOURAPISECRET");
-                    int uploaderBatteryLevel = MainActivity.batLevel;
                     Boolean uploadSuccess = mNightScoutUpload.doRESTUpload(urlSetting,
-                            secretSetting, uploaderBatteryLevel, records);
+                            secretSetting, DataStore.getInstance().getUplooaderBatteryLevel(), records);
                     if (uploadSuccess) {
                         mRealm.beginTransaction();
                         for (PumpStatusEvent updateRecord : records) {
diff --git a/app/src/main/java/info/nightscout/android/utils/ConfigurationStore.java b/app/src/main/java/info/nightscout/android/utils/ConfigurationStore.java
new file mode 100644
index 0000000000000000000000000000000000000000..1a4fca0c7c7a15b5e96607ed2f56ea389702c501
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/utils/ConfigurationStore.java
@@ -0,0 +1,67 @@
+package info.nightscout.android.utils;
+
+
+import info.nightscout.android.medtronic.service.MedtronicCnlIntentService;
+import info.nightscout.android.model.medtronicNg.PumpStatusEvent;
+
+/**
+ * Created by volker on 30.03.2017.
+ */
+
+public class ConfigurationStore {
+    private static ConfigurationStore instance;
+
+    private boolean reducePollOnPumpAway = false;
+    private long pollInterval = MedtronicCnlIntentService.POLL_PERIOD_MS;
+    private long lowBatteryPollInterval = MedtronicCnlIntentService.LOW_BATTERY_POLL_PERIOD_MS;
+    private boolean mmolxl;
+    private boolean mmolxlDecimals;
+
+    public static ConfigurationStore getInstance() {
+        if (ConfigurationStore.instance == null) {
+            instance = new ConfigurationStore();
+        }
+
+        return instance;
+    }
+
+    public boolean isReducePollOnPumpAway() {
+        return reducePollOnPumpAway;
+    }
+
+    public void setReducePollOnPumpAway(boolean reducePollOnPumpAway) {
+        this.reducePollOnPumpAway = reducePollOnPumpAway;
+    }
+
+    public long getPollInterval() {
+        return pollInterval;
+    }
+
+    public void setPollInterval(long pollInterval) {
+        this.pollInterval = pollInterval;
+    }
+
+    public long getLowBatteryPollInterval() {
+        return lowBatteryPollInterval;
+    }
+
+    public void setLowBatteryPollInterval(long lowBatteryPollInterval) {
+        this.lowBatteryPollInterval = lowBatteryPollInterval;
+    }
+
+    public boolean isMmolxl() {
+        return mmolxl;
+    }
+
+    public void setMmolxl(boolean mmolxl) {
+        this.mmolxl = mmolxl;
+    }
+
+    public boolean isMmolxlDecimals() {
+        return mmolxlDecimals;
+    }
+
+    public void setMmolxlDecimals(boolean mmolxlDecimals) {
+        this.mmolxlDecimals = mmolxlDecimals;
+    }
+}
diff --git a/app/src/main/java/info/nightscout/android/utils/DataStore.java b/app/src/main/java/info/nightscout/android/utils/DataStore.java
new file mode 100644
index 0000000000000000000000000000000000000000..a61fbf7d5ce8e2dc4c239b68da806647512b4bbf
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/utils/DataStore.java
@@ -0,0 +1,81 @@
+package info.nightscout.android.utils;
+
+
+import com.bugfender.sdk.a.a.k.a;
+
+import java.util.Date;
+
+import info.nightscout.android.model.medtronicNg.PumpStatusEvent;
+import io.realm.Realm;
+
+/**
+ * Created by volker on 30.03.2017.
+ */
+
+public class DataStore {
+    private static DataStore instance;
+
+    private PumpStatusEvent lastPumpStatus;
+    private int uplooaderBatteryLevel = 0;
+    private int unavailableSGVCount = 0;
+    private long activePumpMac = 0;
+
+    private DataStore() {}
+
+    public static DataStore getInstance() {
+        if (DataStore.instance == null) {
+            instance = new DataStore();
+
+            // set some initial dummy values
+            PumpStatusEvent dummyStatus = new PumpStatusEvent();
+            dummyStatus.setEventDate(new Date(0));
+
+            // bypass setter to avoid dealing with a real Realm object
+            instance.lastPumpStatus = dummyStatus;
+        }
+
+        return instance;
+    }
+
+    public PumpStatusEvent getLastPumpStatus() {
+        return lastPumpStatus;
+    }
+
+    public void setLastPumpStatus(PumpStatusEvent lastPumpStatus) {
+        Realm realm = Realm.getDefaultInstance();
+
+        this.lastPumpStatus = realm.copyFromRealm(lastPumpStatus);
+        if (!realm.isClosed()) realm.close();
+    }
+
+    public int getUplooaderBatteryLevel() {
+        return uplooaderBatteryLevel;
+    }
+
+    public void setUplooaderBatteryLevel(int uplooaderBatteryLevel) {
+        this.uplooaderBatteryLevel = uplooaderBatteryLevel;
+    }
+
+    public int getUnavailableSGVCount() {
+        return unavailableSGVCount;
+    }
+
+    public int incUnavailableSGVCount() {
+        return unavailableSGVCount++;
+    }
+
+    public void clearUnavailableSGVCount() {
+        this.unavailableSGVCount = 0;
+    }
+    public void setUnavailableSGVCount(int unavailableSGVCount) {
+        this.unavailableSGVCount = unavailableSGVCount;
+    }
+
+    public long getActivePumpMac() {
+        return activePumpMac;
+    }
+
+    public void setActivePumpMac(long activePumpMac) {
+        this.activePumpMac = activePumpMac;
+    }
+}
diff --git a/app/src/main/java/info/nightscout/android/xdrip_plus/XDripPlusUploadIntentService.java b/app/src/main/java/info/nightscout/android/xdrip_plus/XDripPlusUploadIntentService.java
index eef010f25bcd95a441250f3090c01fd3d367e4e3..d27f95ecf8f02b258b2e06564eb191ad8c8d70e6 100644
--- a/app/src/main/java/info/nightscout/android/xdrip_plus/XDripPlusUploadIntentService.java
+++ b/app/src/main/java/info/nightscout/android/xdrip_plus/XDripPlusUploadIntentService.java
@@ -16,9 +16,9 @@ import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.Locale;
 
-import info.nightscout.android.medtronic.MainActivity;
 import info.nightscout.android.model.medtronicNg.PumpStatusEvent;
 import info.nightscout.android.upload.nightscout.serializer.EntriesSerializer;
+import info.nightscout.android.utils.DataStore;
 import io.realm.Realm;
 import io.realm.RealmResults;
 import io.realm.Sort;
@@ -116,7 +116,7 @@ public class XDripPlusUploadIntentService extends IntentService {
 
     private void addDeviceStatus(JSONArray devicestatusArray, PumpStatusEvent record) throws Exception {
         JSONObject json = new JSONObject();
-        json.put("uploaderBattery", MainActivity.batLevel);
+        json.put("uploaderBattery", DataStore.getInstance().getUplooaderBatteryLevel());
         json.put("device", record.getDeviceName());
         json.put("created_at", ISO8601_DATE_FORMAT.format(record.getPumpDate()));
 
diff --git a/app/src/main/java/info/nightscout/api/UploadApi.java b/app/src/main/java/info/nightscout/api/UploadApi.java
index 8e5a9cfab8044a2bb87a23d4ea8cf7717e1800f6..a2c4a1a322a6c897c2e49b40b52f1ab52ee536a5 100644
--- a/app/src/main/java/info/nightscout/api/UploadApi.java
+++ b/app/src/main/java/info/nightscout/api/UploadApi.java
@@ -15,15 +15,15 @@ import retrofit2.converter.gson.GsonConverterFactory;
 public class UploadApi {
     private Retrofit retrofit;
     private GlucoseEndpoints glucoseEndpoints;
-    private BolusEndpoints bolusApi;
+    private BolusEndpoints bolusEndpoints;
     private DeviceEndpoints deviceEndpoints;
 
     public GlucoseEndpoints getGlucoseEndpoints() {
         return glucoseEndpoints;
     }
 
-    public BolusEndpoints getBolusApi() {
-        return bolusApi;
+    public BolusEndpoints getBolusEndpoints() {
+        return bolusEndpoints;
     }
 
     public DeviceEndpoints getDeviceEndpoints() {
@@ -71,8 +71,7 @@ public class UploadApi {
                 .build();
 
         glucoseEndpoints = retrofit.create(GlucoseEndpoints.class);
-        bolusApi = retrofit.create(BolusEndpoints.class);
+        bolusEndpoints = retrofit.create(BolusEndpoints.class);
         deviceEndpoints = retrofit.create(DeviceEndpoints.class);
-
     }
 }
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index de93838a97ceafac7a7701ecfbb6ee914ed9c5c3..ff89a6f2bb0e9027c0f4fc857a79595b7a6fe4d5 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -70,6 +70,10 @@
             android:dialogTitle="Enter your Nightscout API secret"
             android:key="@string/preference_api_secret"
             android:title="API Secret"/>
+        <Preference android:title="scan NS-Autoconfig QR-Code"
+            android:key="scanButton"
+            android:dependency="@string/preference_enable_rest_upload"
+            android:summary="Click here to scan QR-Code from http://nightscout.github.io/pages/configure/ using ZXing barcode scanner."/>
         <CheckBoxPreference
             android:key="@string/preference_enable_xdrip_plus"
             android:summary="Enable local broadcast of data to xDrip+"