diff --git a/external/builder/builder.js b/external/builder/builder.js
index 6c05bbcd2..31f07fa9e 100644
--- a/external/builder/builder.js
+++ b/external/builder/builder.js
@@ -100,7 +100,8 @@ function preprocess(inFilename, outFilename, defines) {
   var STATE_ELSE_TRUE = 2;
   // inside if, condition true (process lines until #else or #endif)
   var STATE_IF_TRUE = 3;
-  // inside else, #if was true, so #else is false (ignore lines until #endif)
+  // inside else or elif, #if/#elif was true, so following #else or #elif is
+  // false (ignore lines until #endif)
   var STATE_ELSE_FALSE = 4;
 
   var line;
@@ -124,18 +125,18 @@ function preprocess(inFilename, outFilename, defines) {
           state = evaluateCondition(m[2]) ? STATE_IF_TRUE : STATE_IF_FALSE;
           break;
         case 'elif':
-          if (state === STATE_IF_TRUE) {
+          if (state === STATE_IF_TRUE || state === STATE_ELSE_FALSE) {
             state = STATE_ELSE_FALSE;
           } else if (state === STATE_IF_FALSE) {
             state = evaluateCondition(m[2]) ? STATE_IF_TRUE : STATE_IF_FALSE;
-          } else if (state === STATE_ELSE_TRUE || state === STATE_ELSE_FALSE) {
+          } else if (state === STATE_ELSE_TRUE) {
             throw new Error('Found #elif after #else at ' + loc());
           } else {
             throw new Error('Found #elif without matching #if at ' + loc());
           }
           break;
         case 'else':
-          if (state === STATE_IF_TRUE) {
+          if (state === STATE_IF_TRUE || state === STATE_ELSE_FALSE) {
             state = STATE_ELSE_FALSE;
           } else if (state === STATE_IF_FALSE) {
             state = STATE_ELSE_TRUE;
diff --git a/external/builder/fixtures/if-true-elif-false-else-expected.js b/external/builder/fixtures/if-true-elif-false-else-expected.js
new file mode 100644
index 000000000..0220a0031
--- /dev/null
+++ b/external/builder/fixtures/if-true-elif-false-else-expected.js
@@ -0,0 +1,2 @@
+'use strict';
+var a;
diff --git a/external/builder/fixtures/if-true-elif-false-else.js b/external/builder/fixtures/if-true-elif-false-else.js
new file mode 100644
index 000000000..f00de9530
--- /dev/null
+++ b/external/builder/fixtures/if-true-elif-false-else.js
@@ -0,0 +1,8 @@
+'use strict';
+//#if TRUE
+var a;
+//#elif FALSE
+var b;
+//#else
+var c;
+//#endif
diff --git a/web/app.js b/web/app.js
index 56a4cf7cf..7bce5c4ce 100644
--- a/web/app.js
+++ b/web/app.js
@@ -1288,6 +1288,24 @@ function validateFileURL(file) {
 }
 //#endif
 
+function loadAndEnablePDFBug(enabledTabs) {
+  return new Promise(function (resolve, reject) {
+    var appConfig = PDFViewerApplication.appConfig;
+    var script = document.createElement('script');
+    script.src = appConfig.debuggerScriptPath;
+    script.onload = function () {
+      PDFBug.enable(enabledTabs);
+      PDFBug.init(pdfjsLib, appConfig.mainContainer);
+      resolve();
+    };
+    script.onerror = function () {
+      reject(new Error('Cannot load debugger at ' + script.src));
+    };
+    (document.getElementsByTagName('head')[0] || document.body).
+      appendChild(script);
+  });
+}
+
 function webViewerInitialized() {
 //#if GENERIC
   var queryString = document.location.search.substring(1);
@@ -1302,6 +1320,7 @@ function webViewerInitialized() {
 //var file = DEFAULT_URL;
 //#endif
 
+  var waitForBeforeOpening = [];
   var appConfig = PDFViewerApplication.appConfig;
 //#if GENERIC
   var fileInput = document.createElement('input');
@@ -1393,8 +1412,7 @@ function webViewerInitialized() {
       PDFJS.pdfBug = true;
       var pdfBug = hashParams['pdfbug'];
       var enabled = pdfBug.split(',');
-      PDFBug.enable(enabled);
-      PDFBug.init(pdfjsLib, appConfig.mainContainer);
+      waitForBeforeOpening.push(loadAndEnablePDFBug(enabled));
     }
   }
 
@@ -1496,13 +1514,16 @@ function webViewerInitialized() {
     PDFViewerApplication.eventBus.dispatch('download');
   });
 
-//#if (FIREFOX || MOZCENTRAL || CHROME)
-//PDFViewerApplication.setTitleUsingUrl(file);
-//PDFViewerApplication.initPassiveLoading();
-//return;
-//#endif
+  Promise.all(waitForBeforeOpening).then(function () {
+    webViewerOpenFileViaURL(file);
+  }).catch(function (reason) {
+    PDFViewerApplication.error(mozL10n.get('loading_error', null,
+      'An error occurred while opening.'), reason);
+  });
+}
 
 //#if GENERIC
+function webViewerOpenFileViaURL(file) {
   if (file && file.lastIndexOf('file:', 0) === 0) {
     // file:-scheme. Load the contents in the main thread because QtWebKit
     // cannot load file:-URLs in a Web Worker. file:-URLs are usually loaded
@@ -1526,8 +1547,19 @@ function webViewerInitialized() {
   if (file) {
     PDFViewerApplication.open(file);
   }
-//#endif
 }
+//#elif (FIREFOX || MOZCENTRAL || CHROME)
+//function webViewerOpenFileViaURL(file) {
+//  PDFViewerApplication.setTitleUsingUrl(file);
+//  PDFViewerApplication.initPassiveLoading();
+//}
+//#else
+//function webViewerOpenFileURL(file) {
+//  if (file) {
+//    throw new Error('Not implemented: webViewerOpenFileURL');
+//  }
+//}
+//#endif
 
 function webViewerPageRendered(e) {
   var pageNumber = e.pageNumber;
diff --git a/web/debugger.js b/web/debugger.js
index 609e4ccd7..184a713d1 100644
--- a/web/debugger.js
+++ b/web/debugger.js
@@ -158,6 +158,8 @@ var FontInspector = (function FontInspectorClosure() {
   };
 })();
 
+var opMap;
+
 // Manages all the page steppers.
 var StepperManager = (function StepperManagerClosure() {
   var steppers = [];
@@ -171,7 +173,7 @@ var StepperManager = (function StepperManagerClosure() {
     name: 'Stepper',
     panel: null,
     manager: null,
-    init: function init() {
+    init: function init(pdfjsLib) {
       var self = this;
       this.panel.setAttribute('style', 'padding: 5px;');
       stepperControls = document.createElement('div');
@@ -186,6 +188,11 @@ var StepperManager = (function StepperManagerClosure() {
       if (sessionStorage.getItem('pdfjsBreakPoints')) {
         breakPoints = JSON.parse(sessionStorage.getItem('pdfjsBreakPoints'));
       }
+
+      opMap = Object.create(null);
+      for (var key in pdfjsLib.OPS) {
+        opMap[pdfjsLib.OPS[key]] = key;
+      }
     },
     cleanup: function cleanup() {
       stepperChooser.textContent = '';
@@ -251,8 +258,6 @@ var Stepper = (function StepperClosure() {
     return d;
   }
 
-  var opMap = null;
-
   function simplifyArgs(args) {
     if (typeof args === 'string') {
       var MAX_STRING_LENGTH = 75;
@@ -290,7 +295,7 @@ var Stepper = (function StepperClosure() {
     this.operatorListIdx = 0;
   }
   Stepper.prototype = {
-    init: function init(pdfjsLib) {
+    init: function init(operatorList) {
       var panel = this.panel;
       var content = c('div', 'c=continue, s=step');
       var table = c('table');
@@ -304,12 +309,7 @@ var Stepper = (function StepperClosure() {
       headerRow.appendChild(c('th', 'args'));
       panel.appendChild(content);
       this.table = table;
-      if (!opMap) {
-        opMap = Object.create(null);
-        for (var key in pdfjsLib.OPS) {
-          opMap[pdfjsLib.OPS[key]] = key;
-        }
-      }
+      this.updateOperatorList(operatorList);
     },
     updateOperatorList: function updateOperatorList(operatorList) {
       var self = this;
diff --git a/web/viewer.html b/web/viewer.html
index 3086c831f..83ea7fc51 100644
--- a/web/viewer.html
+++ b/web/viewer.html
@@ -65,7 +65,6 @@ See https://github.com/adobe-type-tools/cmap-resources
 <!--#endif-->
 
 <!--#if !MINIFIED -->
-    <script src="debugger.js"></script>
     <script src="viewer.js"></script>
 <!--#else-->
 <!--#include viewer-snippet-minified.html-->
diff --git a/web/viewer.js b/web/viewer.js
index 4ccd9de90..a0c4afbe3 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -161,6 +161,7 @@ function getViewerConfiguration() {
     },
     printContainer: document.getElementById('printContainer'),
     openFileInputName: 'fileInput',
+    debuggerScriptPath: './debugger.js',
   };
 }