diff --git a/client/www/draper.activity_logger-2.1.1.js b/client/www/draper.activity_logger-2.1.1.js
index a008f01..24e6156 100644
--- a/client/www/draper.activity_logger-2.1.1.js
+++ b/client/www/draper.activity_logger-2.1.1.js
@@ -12,140 +12,143 @@
 
 /*jshint unused:false*/
 function activityLogger(webWorkerURL) {
-	'use strict';
+    'use strict';
+    var draperLog = {version: "2.1.1"}; // semver
+    draperLog.worker = new Worker(webWorkerURL);
 
-  var draperLog = {version: "2.1.1"}; // semver  
+    var muteUserActivityLogging = false,
+    muteSystemActivityLogging = false,
+    logToConsole = false,
+    testing = false,
+    workflowCodingVersion = '2.0';
 
-  draperLog.worker = new Worker(webWorkerURL);
+    // Workflow Codes
+    draperLog.WF_OTHER       = 0;
+    draperLog.WF_DEFINE      = 1;
+    draperLog.WF_GETDATA     = 2;
+    draperLog.WF_EXPLORE     = 3;
+    draperLog.WF_CREATE      = 4;
+    draperLog.WF_ENRICH      = 5;
+    draperLog.WF_TRANSFORM   = 6;
 
-  var muteUserActivityLogging = false,
-  muteSystemActivityLogging = false,
-  logToConsole = false,
-  testing = false,
-  workflowCodingVersion = '2.0';
+    /**
+    * Registers this component with Draper's logging server.  The server creates
+    * a unique session_id, that is then used in subsequent logging messages.  This
+    * is a blocking ajax call to ensure logged messages are tagged correctly.
+    * @todo investigate the use of promises, instead of the blocking call.
+    *
+    * @method registerActivityLogger
+    * @param {String} url the url of Draper's Logging Server
+    * @param {String} componentName the name of this component
+    * @param {String} componentVersion the version of this component
+    */
+    draperLog.registerActivityLogger = function(url, componentName, componentVersion) {
 
-  /**
-  * Workflow Codes
-  */
-  draperLog.WF_OTHER       = 0;
-  draperLog.WF_DEFINE      = 1;
-  draperLog.WF_GETDATA     = 2;
-  draperLog.WF_EXPLORE     = 3;
-  draperLog.WF_CREATE      = 4;
-  draperLog.WF_ENRICH      = 5;
-  draperLog.WF_TRANSFORM   = 6;
+        draperLog.url = url;
+        draperLog.componentName = componentName;
+        draperLog.componentVersion = componentVersion;
 
-	/**
-	* Registers this component with Draper's logging server.  The server creates
-	* a unique session_id, that is then used in subsequent logging messages.  This
-	* is a blocking ajax call to ensure logged messages are tagged correctly.
-	* @todo investigate the use of promises, instead of the blocking call.
-	*
-	* @method registerActivityLogger
-	* @param {String} url the url of Draper's Logging Server
-	* @param {String} componentName the name of this component
-	* @param {String} componentVersion the version of this component
-	*/
-	draperLog.registerActivityLogger = function(url, componentName, componentVersion) {
+        // get session id from url
+        function getParameterByName(name) {
+            name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
+            var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
+            results = regex.exec(location.search);
+            return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
+        }
 
-		draperLog.url = url;
-		draperLog.componentName = componentName;
-		draperLog.componentVersion = componentVersion;  
+        draperLog.sessionID = getParameterByName('USID');
+        draperLog.clientHostname = getParameterByName('client');
 
-		// get session id from url
-		function getParameterByName(name) {
-			name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
-			var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
-			results = regex.exec(location.search);
-			return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
-		}
+        if (!draperLog.sessionID) {
+            draperLog.sessionID = draperLog.componentName.slice(0,3) + new Date().getTime();
+        }
 
-		draperLog.sessionID = getParameterByName('USID');
-    draperLog.clientHostname = getParameterByName('client')
+        if (!draperLog.clientHostname) {
+            draperLog.clientHostname = 'UNK';
+        }
 
-    if (!draperLog.sessionID) {
-      draperLog.sessionID = draperLog.componentName.slice(0,3) + new Date().getTime()
-    }
+        // set the logging URL on the Web Worker
+        draperLog.worker.postMessage({
+            cmd: 'setLoggingUrl',
+            msg: url
+        });
 
-    if (!draperLog.clientHostname) {
-      draperLog.clientHostname = 'UNK'
-    }
+        classListener();
 
-		// set the logging URL on the Web Worker
-		draperLog.worker.postMessage({
-	  	cmd: 'setLoggingUrl',
-	  	msg: url
-	  });
+        if (logToConsole) {
+            if (testing) {
+                console.log('DRAPER LOG: (TESTING) Registered Activity Logger ' + draperLog.sessionID);
+            } else {
+                console.log('DRAPER LOG: Registered Activity Logger ' + draperLog.sessionID);
+            }
+        }
 
-		classListener();
+        draperLog.worker.postMessage({
+            cmd: 'sendBuffer',
+            msg: ''
+          });
 
-		if (logToConsole) {
-			if (testing) {
-				console.log('DRAPER LOG: (TESTING) Registered Activity Logger ' + draperLog.sessionID);
-			} else {
-				console.log('DRAPER LOG: Registered Activity Logger ' + draperLog.sessionID);
-			}			
-		}
+        // Log the activity that we are closing the window of the web browser
+        // before we exit. In order to do this, we register a onBeforeUnload 
+        // callback which logs the closing and sends the buffer.
+        window.onbeforeunload = function(){
+            draperLog.logUserActivity(
+                'window closing',
+                'window_closed',
+                draperLog.WF_OTHER);
 
-		draperLog.worker.postMessage({
-		  	cmd: 'sendBuffer',
-		  	msg: ''
-		  });
-		
-		window.onbeforeunload = function(){
-      draperLog.logUserActivity(
-        'window closing',
-        'window_closed',
-        draperLog.WF_OTHER
-        )
-      
-			draperLog.worker.postMessage({
-		  	cmd: 'sendBuffer',
-		  	msg: ''
-		  });
-		};
+            draperLog.worker.postMessage({
+                cmd: 'sendBuffer',
+                msg: ''});
+        };
 
-    window.onfocus = function() {
-      draperLog.logUserActivity(
-        'window gained focus',
-        'window_focus',
-        draperLog.WF_OTHER
-        )
-    }
+        // Log the activity when the user gains focus on the web browser
+        // window. In order to do this, we register an onFocus callback function
+        // which will log the gained focus of the element.
+        window.onfocus = function() {
+          draperLog.logUserActivity(
+            'window gained focus',
+            'window_focus',
+            draperLog.WF_OTHER
+            );
+        };
 
-    window.onblur = function() {
-      draperLog.logUserActivity(
-        'window lost focus',
-        'window_blur',
-        draperLog.WF_OTHER
-        )
-    }
+        // Log the activity when the user leaves focus on the web browser
+        // window. In order to do this, we register an onBlur callback function
+        // which will log the lost focus
+        window.onblur = function() {
+          draperLog.logUserActivity(
+            'window lost focus',
+            'window_blur',
+            draperLog.WF_OTHER
+            );
+        };
 
-		return draperLog;
-	};
+        return draperLog;
+    };
 
-	/**
-	* Create USER activity message.
-	*
-	* @method logUserActivity
-	* @param {String} actionDescription a description of the activity in natural language.
-	* @param {String} userActivity a more generalized one word description of the current activity.
-	* @param {Integer} userWorkflowState an integer representing one of the enumerated states above.
-	* @param {JSON} softwareMetadata any arbitrary JSON that may support this activity
-	*/
-	draperLog.logUserActivity = function (actionDescription, userActivity, userWorkflowState, softwareMetadata) {
-		if(!muteUserActivityLogging) {
-			var msg = {
-				type: 'USERACTION',
-				parms: {
-					desc: actionDescription,
-					activity: userActivity,
-					wf_state: userWorkflowState,
-					wf_version: workflowCodingVersion
-				},
-				meta: softwareMetadata
-			};
-			sendMessage(msg);
+    /**
+    * Create USER activity message.
+    *
+    * @method logUserActivity
+    * @param {String} actionDescription a description of the activity in natural language.
+    * @param {String} userActivity a more generalized one word description of the current activity.
+    * @param {Integer} userWorkflowState an integer representing one of the enumerated states above.
+    * @param {JSON} softwareMetadata any arbitrary JSON that may support this activity
+    */
+    draperLog.logUserActivity = function (actionDescription, userActivity, userWorkflowState, softwareMetadata) {
+        if(!muteUserActivityLogging) {
+            var msg = {
+                type: 'USERACTION',
+                parms: {
+                    desc: actionDescription,
+                    activity: userActivity,
+                    wf_state: userWorkflowState,
+                    wf_version: workflowCodingVersion
+                },
+                meta: softwareMetadata
+            };
+            sendMessage(msg);
 
       if (logToConsole) {
         if (testing) {
@@ -154,27 +157,27 @@
           console.log('DRAPER LOG: Logging UserActivity', msg.parms);
         }
       }
-		}
-	};
+        }
+    };
 
-	/**
-	* Create SYSTEM activity message.
-	*
-	* @method logSystemActivity
-	* @param {String} actionDescription a description of the activity in natural language.
-	* @param {JSON} softwareMetadata any arbitrary JSON that may support this activity
-	*/
-	draperLog.logSystemActivity = function (actionDescription, softwareMetadata) {
+    /**
+    * Create SYSTEM activity message.
+    *
+    * @method logSystemActivity
+    * @param {String} actionDescription a description of the activity in natural language.
+    * @param {JSON} softwareMetadata any arbitrary JSON that may support this activity
+    */
+    draperLog.logSystemActivity = function (actionDescription, softwareMetadata) {
 
-		if(!muteSystemActivityLogging) {
-			var msg = {
-				type: 'SYSACTION',
-				parms: {
-					desc: actionDescription,
-				},
-				meta: softwareMetadata
-			};
-			sendMessage(msg);
+        if(!muteSystemActivityLogging) {
+            var msg = {
+                type: 'SYSACTION',
+                parms: {
+                    desc: actionDescription,
+                },
+                meta: softwareMetadata
+            };
+            sendMessage(msg);
 
       if (logToConsole) {
         if (testing) {
@@ -183,131 +186,137 @@
           console.log('DRAPER LOG: Logging SystemActivity', msg.parms);
         }
       }
-		}
-	};
+        }
+    };
 
-	/**
-	* Send activity message to Draper's logging server.  This function uses Jquery's ajax
-	* function to send the created message to draper's server.
-	*
-	* @method sendMessage
-	* @param {JSON} msg the JSON message.
-	*/
-	function sendMessage(msg) {
-		msg.timestamp = new Date().toJSON();
-		msg.client = draperLog.clientHostname;
-		msg.component = {name: draperLog.componentName, version: draperLog.componentVersion};
-		msg.sessionID = draperLog.sessionID;
-		msg.impLanguage = 'JavaScript';
-		msg.apiVersion = draperLog.version;
+    /**
+    * Send activity message to Draper's logging server.  This function uses Jquery's ajax
+    * function to send the created message to draper's server.
+    *
+    * @method sendMessage
+    * @param {JSON} msg the JSON message.
+    */
+    function sendMessage(msg) {
+        msg.timestamp = new Date().toJSON();
+        msg.client = draperLog.clientHostname;
+        msg.component = {name: draperLog.componentName, version: draperLog.componentVersion};
+        msg.sessionID = draperLog.sessionID;
+        msg.impLanguage = 'JavaScript';
+        msg.apiVersion = draperLog.version;
 
-		// if (!testing) {
-			draperLog.worker.postMessage({
-		  	cmd: 'sendMsg',
-		  	msg: msg
-		  });
-		// }
-	}
+        // if (!testing) {
+            draperLog.worker.postMessage({
+            cmd: 'sendMsg',
+            msg: msg
+          });
+        // }
+    }
 
-	/**
-	* When set to true, logs messages to browser console.
-	*
-	* @method echo
-	* @param {Boolean} set to true to log to console
-	*/
-	draperLog.echo = function(d) {
-		if (!arguments.length) { return logToConsole; }
-		logToConsole = d;
-		draperLog.worker.postMessage({
-	  	cmd: 'setEcho',
-	  	msg: d
-	  });
-		return draperLog;
-	};
+    /**
+    * When set to true, logs messages to browser console.
+    *
+    * @method echo
+    * @param {Boolean} set to true to log to console
+    */
+    draperLog.echo = function(d) {
+        if (!arguments.length) { return logToConsole; }
+        logToConsole = d;
+        draperLog.worker.postMessage({
+        cmd: 'setEcho',
+        msg: d
+      });
+        return draperLog;
+    };
 
   /**
-	* Accepts an array of Strings telling logger to mute those type of messages.
-	* Possible values are 'SYS' and 'USER'.  These messages will not be sent to
-	* server.
-	*
-	* @method mute
-	* @param {Array} array of strings of messages to mute.
-	*/
-	draperLog.mute = function(d) {
-		d.forEach(function(d) {
-			if(d === 'USER') { muteUserActivityLogging = true; }
-			if(d === 'SYS') { muteSystemActivityLogging = true; }
-		});
-		return draperLog;
-	};
+    * Accepts an array of Strings telling logger to mute those type of messages.
+    * Possible values are 'SYS' and 'USER'.  These messages will not be sent to
+    * server.
+    *
+    * @method mute
+    * @param {Array} array of strings of messages to mute.
+    */
+    draperLog.mute = function(d) {
+        d.forEach(function(d) {
+            if(d === 'USER') { muteUserActivityLogging = true; }
+            if(d === 'SYS') { muteSystemActivityLogging = true; }
+        });
+        return draperLog;
+    };
 
-  draperLog.unmute = function(d) {
-    d.forEach(function(d) {
-      if(d === 'USER') { muteUserActivityLogging = false; }
-      if(d === 'SYS') { muteSystemActivityLogging = false; }
-    });
+    draperLog.unmute = function(d) {
+        d.forEach(function(d) {
+          if(d === 'USER') { muteUserActivityLogging = false; }
+          if(d === 'SYS') { muteSystemActivityLogging = false; }
+        });
+        return draperLog;
+    };
+
+  /**
+    * When set to true, no connection will be made against logging server.
+    *
+    * @method testing
+    * @param {Boolean} set to true to disable all connection to logging server
+    */
+    draperLog.testing = function(d) {
+        if (!arguments.length) { return testing; }
+        testing = d;
+        draperLog.worker.postMessage({
+        cmd: 'setTesting',
+        msg: d
+      });
+        return draperLog;
+    };
+
+  /**
+    * DOM Listener for specific events.
+    *
+    */
+    function classListener() {
+
+        $(document).ready(function() {
+            $(".draper").each(function(i,d){
+                $(d).on("click", function(a){
+                    draperLog.logUserActivity('User clicked element', $(this).data('activity'), $(this).data('wf'));
+                });
+            });
+
+            $(window).scroll(function() {
+                clearTimeout($.data(this, 'scrollTimer'));
+                $.data(this, 'scrollTimer', setTimeout(function() {
+                    draperLog.logUserActivity('User scrolled window', 'scroll', 3);
+                }, 500));
+            });
+        });
+    }
+
+    /**
+     * @brief [brief description]
+     * @details [long description]
+     * 
+     * @param elem [description]
+     * @param msg [description]
+     */
+    draperLog.tag = function(elem, msg) {
+        $.each(msg.events, function(i, d) {
+            if (d === 'scroll') {
+                console.log('found scroll');
+                $(elem).scroll(function() {
+                    clearTimeout($.data(this, 'scrollTimer'));
+                    $.data(this, 'scrollTimer', setTimeout(function() {
+                        draperLog.logUserActivity('User scrolled window', 'scroll', 3);
+                    }, 500));
+                });
+            }else{
+                $(elem).on(d, function() {
+                    draperLog.logUserActivity(msg.desc, msg.activity, msg.wf_state);
+                });
+            }
+        });
+    };
+
+    // Return the activity logger object in which is created. With this, 
+    // object functions and variable are created to keep this a separate instance
+    // of the logger.
     return draperLog;
-  };
-
-  /**
-	* When set to true, no connection will be made against logging server.
-	*
-	* @method testing
-	* @param {Boolean} set to true to disable all connection to logging server
-	*/
-	draperLog.testing = function(d) {
-		if (!arguments.length) { return testing; }
-		testing = d;
-		draperLog.worker.postMessage({
-	  	cmd: 'setTesting',
-	  	msg: d
-	  });
-		return draperLog;
-	};
-
-  /**
-	* DOM Listener for specific events.
-	*
-	*/
-	function classListener() {
-
-		$(document).ready(function() {
-			$(".draper").each(function(i,d){
-				$(d).on("click", function(a){
-					draperLog.logUserActivity('User clicked element', $(this).data('activity'), $(this).data('wf'));
-				});
-			});
-
-			$(window).scroll(function() {
-				clearTimeout($.data(this, 'scrollTimer'));
-				$.data(this, 'scrollTimer', setTimeout(function() {
-					draperLog.logUserActivity('User scrolled window', 'scroll', 3);
-				}, 500));
-			});
-		});
-	}
-
-  /**
-	* Tag specific elements
-	*
-	*/
-	draperLog.tag = function(elem, msg) {
-		$.each(msg.events, function(i, d) {
-			if (d === 'scroll') {
-				console.log('found scroll');
-				$(elem).scroll(function() {
-					clearTimeout($.data(this, 'scrollTimer'));
-					$.data(this, 'scrollTimer', setTimeout(function() {
-						draperLog.logUserActivity('User scrolled window', 'scroll', 3);
-					}, 500));
-				});
-			}else{
-				$(elem).on(d, function() {
-					draperLog.logUserActivity(msg.desc, msg.activity, msg.wf_state);
-				});
-			}
-		});
-	};
-
-	return draperLog;
 }
\ No newline at end of file
diff --git a/client/www/draper.activity_worker-2.1.1.js b/client/www/draper.activity_worker-2.1.1.js
index 04f287b..7ce3b8f 100644
--- a/client/www/draper.activity_worker-2.1.1.js
+++ b/client/www/draper.activity_worker-2.1.1.js
@@ -1,105 +1,199 @@
 var logBuffer = [];
-var loggingUrl = 'http://localhost:3001';
+var loggingUrl = 'http://localhost:8080';
 var intervalTime = 5000; //send every 5 seconds
 var testing = false;
 var echo = true;
 var msg = 'DRAPER LOG: ';
 
-function timerMethod() {
-
-	if (logBuffer.length) {
-    if (echo) {
-      console.log(msg + 'sent ' + logBuffer.length + ' logs to - ' + loggingUrl)
-    }
-		if (!testing) {
-			XHR(loggingUrl + '/send_log', logBuffer, function(d) {
-				logBuffer = [];
-			})			
-		} else {
-      logBuffer = [];
-    }		
-	}	else {
-		if (echo) {
-			console.log(msg + 'no log sent, buffer empty.')
-		}		
-	}
-}
-
+// Register the interval timer to poll every intervalTime whether
+// is data that is needed to be send to the server or not.
 var timerId = setInterval(timerMethod, intervalTime);
 
-self.addEventListener('message', function(e) {
-  var data = e.data;
-  switch (data.cmd) {
-    case 'setLoggingUrl':
-			loggingUrl = data.msg;
-      break;
-    case 'sendMsg':
-      logBuffer.push(data.msg)
-      break;
-    case 'setTesting':
-    	if (data.msg) {
-    		var msg = 'DRAPER LOG: (TESTING) ';
-    	} else {
-    		var msg = 'DRAPER LOG: ';
-    	}
-      testing = data.msg;
-      break;
-    case 'setEcho':
-      echo = data.msg;
-      break;
-    case 'sendBuffer':
-    	sendBuffer();
-    	break;
-  };
-}, false);
-
-
-function sendBuffer() {
-  // method to force send the buffer
-	timerMethod();
-	if (echo) {
-		console.log(msg + ' buffer sent')
-	}	
+/**
+ * @brief Function which handles sending debug information to the web browser's
+ * console.
+ * @details Function which handles sending debug information to the web browser's
+ * console. This allows for one line debugging which toggles between debugging or
+ * not
+ * 
+ * @param msg Message to log to the console.
+ */
+function debug(user_msg)
+{
+    if(echo)
+        console.log(msg + user_msg);
 }
-//simple XHR request in pure raw JavaScript
+
+/**
+ * @brief Timer Method to poll and check for new messages to send to the logging 
+ * ELK server.
+ * @details Timer Method to poll and check for new messages to send to the logging 
+ * ELK server. The method will be fired after each intervalTime and attempts to send
+ * any pending logs which may have been created by the user.
+ */
+function timerMethod() {
+    // Check to see if there is anything within the global logBuffer. If there are any
+    // new entries, attemp to send the data.
+    if (logBuffer.length) {
+        
+        // If echo is enabled, echo debugging information to the console for developers
+        // to debug their application and see if logs are being send to the logging 
+        // server
+        debug('Sent ' + logBuffer.length + ' logs to - ' + loggingUrl);
+        
+        // Check to see if the developer has set the module to be within testing mode. In
+        // this mode, we are able to defer attempts at sending the logging request to 
+        // the logging server and just drop the logs.
+        if (testing)
+            logBuffer = [];
+        else
+            XHR(loggingUrl + '/send_log', logBuffer, function(d) { logBuffer = []; });
+    }  
+
+    // If we don't have any logs to send to the server, just return 
+    // back to the caller. There are no actions that need to be done
+    // when it comes to logging.
+    else
+    {
+        // If we have debugging enabled, send a debug message saying there
+        // are no logs present to be sent to the logging server.
+        debug('No log sent, buffer empty.');
+    }
+}
+
+/**
+ * @brief Adding Event Listener for the Activity worker.
+ * @details Adding event listener for the activity worker. This will allow
+ * the activity logger to message the activity worker as it is running.
+ */
+self.addEventListener('message', 
+    function(e) {
+        var data = e.data;
+
+        // Switch based on the command that was received by the message.
+        switch (data.cmd) {
+            // SetLoggingUrl: This allows the developer to change the location in which the 
+            // logging is being stored to. This will allow for custom logging servers.
+            case 'setLoggingUrl':
+                loggingUrl = data.msg;
+                break;
+
+            // SendMsg command: This adds a new log to the log buffer which will be sent 
+            // to the server. The worker pushes this log into the buffer and sits there until
+            // the interval time, or a SendBuffer command forces the worker to send the logs.
+            case 'sendMsg':
+                logBuffer.push(data.msg);
+                break;
+
+            // SetTesting command: This sets the activity logger to a testing mode where
+            // no logs are being send to the server. This will allow the developer to see
+            // what is being logged without the attempt of sending the logs to the log 
+            // server.
+            case 'setTesting':
+                if (data.msg) 
+                    msg = 'DRAPER LOG: (TESTING) ';
+                else 
+                    msg = 'DRAPER LOG: ';
+                
+                testing = data.msg;
+                break;
+
+            // SetEcho command: This allows the developer to debug their application
+            // by echoing debug messages of what is currently being logged by the
+            // tool/application.
+            case 'setEcho':
+                echo = data.msg;
+                break;
+            
+            // SendBuffer command forces the activity worker to send what is currently
+            // in the log buffer. It is the same premise as a flush command where all 
+            // the logs are getting flushed to the server.
+            case 'sendBuffer':
+                sendBuffer();
+                break;
+        }
+    }, false);
+
+/**
+ * @brief Sends the logs to the logging server.
+ * @details Sends the logs to the logging server. This is done by calling the
+ * timerMethod() which is responsible for sending the logs to the server and 
+ * updating the timer interval.
+ */
+function sendBuffer() {
+    // method to force send the buffer
+    timerMethod();
+    if (echo) {
+        console.log(msg + ' buffer sent');
+    }
+}
+
+/**
+ * @brief Connect and send logging information through XMLHttpRequest
+ * @details Connect and send logging information through XMLHttpRequest. 
+ * Function attempts to connect through different means of the 
+ * XMLHttpRequest (xhr) object. Once the xhr object is created, the
+ * logging data that has been buffered is sent to the server.
+ * 
+ * @param url The URL to connect and send the logging data to
+ * @param log The logging information that is being sent to the server
+ * @param callback Callback function to register when a response is 
+ * received.
+ */
 function XHR(url, log, callback) {
-	var xhr;
+    var xhr;
 
-	if(typeof XMLHttpRequest !== 'undefined') xhr = new XMLHttpRequest();
-	else {
-		var versions = ["MSXML2.XmlHttp.5.0", 
-		 				"MSXML2.XmlHttp.4.0",
-		 			  "MSXML2.XmlHttp.3.0", 
-		 			  "MSXML2.XmlHttp.2.0",
-		 				"Microsoft.XmlHttp"]
+    if(typeof XMLHttpRequest !== 'undefined') 
+        xhr = new XMLHttpRequest();
+    else 
+    {
+        var versions = ["MSXML2.XmlHttp.5.0",
+                        "MSXML2.XmlHttp.4.0",
+                        "MSXML2.XmlHttp.3.0",
+                        "MSXML2.XmlHttp.2.0",
+                        "Microsoft.XmlHttp"];
 
-		 for(var i = 0, len = versions.length; i < len; i++) {
-		 	try {
-		 		xhr = new ActiveXObject(versions[i]);
-		 		break;
-		 	}
-		 	catch(e){}
-		 } // end for
-	}
-	
-	xhr.onreadystatechange = ensureReadiness;
-	
-	function ensureReadiness() {
-		if(xhr.readyState < 4) {
-			return;
-		}
-		
-		if(xhr.status !== 200) {
-			return;
-		}
+         for(var i = 0, len = versions.length; i < len; i++) {
+            try {
+                xhr = new ActiveXObject(versions[i]);
+                break;
+            }
+            catch(e){}
+         } // end for
+    }
 
-		// all is well	
-		if(xhr.readyState === 4) {
-			callback(xhr);
-		}			
-	}
-	
-	xhr.open("POST", url, true);
-	xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
-	xhr.send(JSON.stringify(log));
+    // Register the readiness function.
+    xhr.onreadystatechange = ensureReadiness;
+
+    // Create a readiness callback function to handle the changes within
+    // the attempted request. Also, allows the program to handle the request,
+    // if need be.
+    function ensureReadiness() {
+        // If we receive a response readiness that is not 
+        // 4, then dismiss until we do.
+        if(xhr.readyState < 4) {
+            return;
+        }
+
+        // If we have a readiness of 4, but yet, we have an
+        // invalid request, just return.
+        // TODO: Log or handle this to inform the developer that
+        // there are problems occurring?
+        if(xhr.status !== 200) {
+            return;
+        }
+
+        // If the readiness status is set to 4, and receieved
+        // an "OK" from the server, call the register callback if one
+        // exists
+        // TODO: Check for null callback.
+        if(xhr.readyState === 4) {
+            callback(xhr);
+        }
+    }
+
+    // Open and send the data to the logging server.
+    xhr.open("POST", url, true);
+    xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
+    xhr.send(JSON.stringify(log));
 }
diff --git a/helper-libs/javascript/draper.activity_logger-2.1.1.js b/helper-libs/javascript/draper.activity_logger-2.1.1.js
index df4ce32..24e6156 100644
--- a/helper-libs/javascript/draper.activity_logger-2.1.1.js
+++ b/helper-libs/javascript/draper.activity_logger-2.1.1.js
@@ -12,140 +12,143 @@
 
 /*jshint unused:false*/
 function activityLogger(webWorkerURL) {
-	'use strict';
+    'use strict';
+    var draperLog = {version: "2.1.1"}; // semver
+    draperLog.worker = new Worker(webWorkerURL);
 
-  var draperLog = {version: "2.1.1"}; // semver
+    var muteUserActivityLogging = false,
+    muteSystemActivityLogging = false,
+    logToConsole = false,
+    testing = false,
+    workflowCodingVersion = '2.0';
 
-  draperLog.worker = new Worker(webWorkerURL);
+    // Workflow Codes
+    draperLog.WF_OTHER       = 0;
+    draperLog.WF_DEFINE      = 1;
+    draperLog.WF_GETDATA     = 2;
+    draperLog.WF_EXPLORE     = 3;
+    draperLog.WF_CREATE      = 4;
+    draperLog.WF_ENRICH      = 5;
+    draperLog.WF_TRANSFORM   = 6;
 
-  var muteUserActivityLogging = false,
-  muteSystemActivityLogging = false,
-  logToConsole = false,
-  testing = false,
-  workflowCodingVersion = '2.0';
+    /**
+    * Registers this component with Draper's logging server.  The server creates
+    * a unique session_id, that is then used in subsequent logging messages.  This
+    * is a blocking ajax call to ensure logged messages are tagged correctly.
+    * @todo investigate the use of promises, instead of the blocking call.
+    *
+    * @method registerActivityLogger
+    * @param {String} url the url of Draper's Logging Server
+    * @param {String} componentName the name of this component
+    * @param {String} componentVersion the version of this component
+    */
+    draperLog.registerActivityLogger = function(url, componentName, componentVersion) {
 
-  /**
-  * Workflow Codes
-  */
-  draperLog.WF_OTHER       = 0;
-  draperLog.WF_DEFINE      = 1;
-  draperLog.WF_GETDATA     = 2;
-  draperLog.WF_EXPLORE     = 3;
-  draperLog.WF_CREATE      = 4;
-  draperLog.WF_ENRICH      = 5;
-  draperLog.WF_TRANSFORM   = 6;
+        draperLog.url = url;
+        draperLog.componentName = componentName;
+        draperLog.componentVersion = componentVersion;
 
-	/**
-	* Registers this component with Draper's logging server.  The server creates
-	* a unique session_id, that is then used in subsequent logging messages.  This
-	* is a blocking ajax call to ensure logged messages are tagged correctly.
-	* @todo investigate the use of promises, instead of the blocking call.
-	*
-	* @method registerActivityLogger
-	* @param {String} url the url of Draper's Logging Server
-	* @param {String} componentName the name of this component
-	* @param {String} componentVersion the version of this component
-	*/
-	draperLog.registerActivityLogger = function(url, componentName, componentVersion) {
+        // get session id from url
+        function getParameterByName(name) {
+            name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
+            var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
+            results = regex.exec(location.search);
+            return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
+        }
 
-		draperLog.url = url;
-		draperLog.componentName = componentName;
-		draperLog.componentVersion = componentVersion;
+        draperLog.sessionID = getParameterByName('USID');
+        draperLog.clientHostname = getParameterByName('client');
 
-		// get session id from url
-		function getParameterByName(name) {
-			name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
-			var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
-			results = regex.exec(location.search);
-			return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
-		}
+        if (!draperLog.sessionID) {
+            draperLog.sessionID = draperLog.componentName.slice(0,3) + new Date().getTime();
+        }
 
-		draperLog.sessionID = getParameterByName('USID');
-    draperLog.clientHostname = getParameterByName('client');
+        if (!draperLog.clientHostname) {
+            draperLog.clientHostname = 'UNK';
+        }
 
-    if (!draperLog.sessionID) {
-      draperLog.sessionID = draperLog.componentName.slice(0,3) + new Date().getTime();
-    }
+        // set the logging URL on the Web Worker
+        draperLog.worker.postMessage({
+            cmd: 'setLoggingUrl',
+            msg: url
+        });
 
-    if (!draperLog.clientHostname) {
-      draperLog.clientHostname = 'UNK';
-    }
+        classListener();
 
-		// set the logging URL on the Web Worker
-		draperLog.worker.postMessage({
-	  	cmd: 'setLoggingUrl',
-	  	msg: url
-	  });
+        if (logToConsole) {
+            if (testing) {
+                console.log('DRAPER LOG: (TESTING) Registered Activity Logger ' + draperLog.sessionID);
+            } else {
+                console.log('DRAPER LOG: Registered Activity Logger ' + draperLog.sessionID);
+            }
+        }
 
-		classListener();
+        draperLog.worker.postMessage({
+            cmd: 'sendBuffer',
+            msg: ''
+          });
 
-		if (logToConsole) {
-			if (testing) {
-				console.log('DRAPER LOG: (TESTING) Registered Activity Logger ' + draperLog.sessionID);
-			} else {
-				console.log('DRAPER LOG: Registered Activity Logger ' + draperLog.sessionID);
-			}
-		}
+        // Log the activity that we are closing the window of the web browser
+        // before we exit. In order to do this, we register a onBeforeUnload 
+        // callback which logs the closing and sends the buffer.
+        window.onbeforeunload = function(){
+            draperLog.logUserActivity(
+                'window closing',
+                'window_closed',
+                draperLog.WF_OTHER);
 
-		draperLog.worker.postMessage({
-		  	cmd: 'sendBuffer',
-		  	msg: ''
-		  });
+            draperLog.worker.postMessage({
+                cmd: 'sendBuffer',
+                msg: ''});
+        };
 
-		window.onbeforeunload = function(){
-      draperLog.logUserActivity(
-        'window closing',
-        'window_closed',
-        draperLog.WF_OTHER
-        );
+        // Log the activity when the user gains focus on the web browser
+        // window. In order to do this, we register an onFocus callback function
+        // which will log the gained focus of the element.
+        window.onfocus = function() {
+          draperLog.logUserActivity(
+            'window gained focus',
+            'window_focus',
+            draperLog.WF_OTHER
+            );
+        };
 
-			draperLog.worker.postMessage({
-		  	cmd: 'sendBuffer',
-		  	msg: ''
-		  });
-		};
+        // Log the activity when the user leaves focus on the web browser
+        // window. In order to do this, we register an onBlur callback function
+        // which will log the lost focus
+        window.onblur = function() {
+          draperLog.logUserActivity(
+            'window lost focus',
+            'window_blur',
+            draperLog.WF_OTHER
+            );
+        };
 
-    window.onfocus = function() {
-      draperLog.logUserActivity(
-        'window gained focus',
-        'window_focus',
-        draperLog.WF_OTHER
-        );
+        return draperLog;
     };
 
-    window.onblur = function() {
-      draperLog.logUserActivity(
-        'window lost focus',
-        'window_blur',
-        draperLog.WF_OTHER
-        );
-    };
-
-		return draperLog;
-	};
-
-	/**
-	* Create USER activity message.
-	*
-	* @method logUserActivity
-	* @param {String} actionDescription a description of the activity in natural language.
-	* @param {String} userActivity a more generalized one word description of the current activity.
-	* @param {Integer} userWorkflowState an integer representing one of the enumerated states above.
-	* @param {JSON} softwareMetadata any arbitrary JSON that may support this activity
-	*/
-	draperLog.logUserActivity = function (actionDescription, userActivity, userWorkflowState, softwareMetadata) {
-		if(!muteUserActivityLogging) {
-			var msg = {
-				type: 'USERACTION',
-				parms: {
-					desc: actionDescription,
-					activity: userActivity,
-					wf_state: userWorkflowState,
-					wf_version: workflowCodingVersion
-				},
-				meta: softwareMetadata
-			};
-			sendMessage(msg);
+    /**
+    * Create USER activity message.
+    *
+    * @method logUserActivity
+    * @param {String} actionDescription a description of the activity in natural language.
+    * @param {String} userActivity a more generalized one word description of the current activity.
+    * @param {Integer} userWorkflowState an integer representing one of the enumerated states above.
+    * @param {JSON} softwareMetadata any arbitrary JSON that may support this activity
+    */
+    draperLog.logUserActivity = function (actionDescription, userActivity, userWorkflowState, softwareMetadata) {
+        if(!muteUserActivityLogging) {
+            var msg = {
+                type: 'USERACTION',
+                parms: {
+                    desc: actionDescription,
+                    activity: userActivity,
+                    wf_state: userWorkflowState,
+                    wf_version: workflowCodingVersion
+                },
+                meta: softwareMetadata
+            };
+            sendMessage(msg);
 
       if (logToConsole) {
         if (testing) {
@@ -154,27 +157,27 @@
           console.log('DRAPER LOG: Logging UserActivity', msg.parms);
         }
       }
-		}
-	};
+        }
+    };
 
-	/**
-	* Create SYSTEM activity message.
-	*
-	* @method logSystemActivity
-	* @param {String} actionDescription a description of the activity in natural language.
-	* @param {JSON} softwareMetadata any arbitrary JSON that may support this activity
-	*/
-	draperLog.logSystemActivity = function (actionDescription, softwareMetadata) {
+    /**
+    * Create SYSTEM activity message.
+    *
+    * @method logSystemActivity
+    * @param {String} actionDescription a description of the activity in natural language.
+    * @param {JSON} softwareMetadata any arbitrary JSON that may support this activity
+    */
+    draperLog.logSystemActivity = function (actionDescription, softwareMetadata) {
 
-		if(!muteSystemActivityLogging) {
-			var msg = {
-				type: 'SYSACTION',
-				parms: {
-					desc: actionDescription,
-				},
-				meta: softwareMetadata
-			};
-			sendMessage(msg);
+        if(!muteSystemActivityLogging) {
+            var msg = {
+                type: 'SYSACTION',
+                parms: {
+                    desc: actionDescription,
+                },
+                meta: softwareMetadata
+            };
+            sendMessage(msg);
 
       if (logToConsole) {
         if (testing) {
@@ -183,131 +186,137 @@
           console.log('DRAPER LOG: Logging SystemActivity', msg.parms);
         }
       }
-		}
-	};
+        }
+    };
 
-	/**
-	* Send activity message to Draper's logging server.  This function uses Jquery's ajax
-	* function to send the created message to draper's server.
-	*
-	* @method sendMessage
-	* @param {JSON} msg the JSON message.
-	*/
-	function sendMessage(msg) {
-		msg.timestamp = new Date().toJSON();
-		msg.client = draperLog.clientHostname;
-		msg.component = {name: draperLog.componentName, version: draperLog.componentVersion};
-		msg.sessionID = draperLog.sessionID;
-		msg.impLanguage = 'JavaScript';
-		msg.apiVersion = draperLog.version;
+    /**
+    * Send activity message to Draper's logging server.  This function uses Jquery's ajax
+    * function to send the created message to draper's server.
+    *
+    * @method sendMessage
+    * @param {JSON} msg the JSON message.
+    */
+    function sendMessage(msg) {
+        msg.timestamp = new Date().toJSON();
+        msg.client = draperLog.clientHostname;
+        msg.component = {name: draperLog.componentName, version: draperLog.componentVersion};
+        msg.sessionID = draperLog.sessionID;
+        msg.impLanguage = 'JavaScript';
+        msg.apiVersion = draperLog.version;
 
-		// if (!testing) {
-			draperLog.worker.postMessage({
-		  	cmd: 'sendMsg',
-		  	msg: msg
-		  });
-		// }
-	}
+        // if (!testing) {
+            draperLog.worker.postMessage({
+            cmd: 'sendMsg',
+            msg: msg
+          });
+        // }
+    }
 
-	/**
-	* When set to true, logs messages to browser console.
-	*
-	* @method echo
-	* @param {Boolean} set to true to log to console
-	*/
-	draperLog.echo = function(d) {
-		if (!arguments.length) { return logToConsole; }
-		logToConsole = d;
-		draperLog.worker.postMessage({
-	  	cmd: 'setEcho',
-	  	msg: d
-	  });
-		return draperLog;
-	};
+    /**
+    * When set to true, logs messages to browser console.
+    *
+    * @method echo
+    * @param {Boolean} set to true to log to console
+    */
+    draperLog.echo = function(d) {
+        if (!arguments.length) { return logToConsole; }
+        logToConsole = d;
+        draperLog.worker.postMessage({
+        cmd: 'setEcho',
+        msg: d
+      });
+        return draperLog;
+    };
 
   /**
-	* Accepts an array of Strings telling logger to mute those type of messages.
-	* Possible values are 'SYS' and 'USER'.  These messages will not be sent to
-	* server.
-	*
-	* @method mute
-	* @param {Array} array of strings of messages to mute.
-	*/
-	draperLog.mute = function(d) {
-		d.forEach(function(d) {
-			if(d === 'USER') { muteUserActivityLogging = true; }
-			if(d === 'SYS') { muteSystemActivityLogging = true; }
-		});
-		return draperLog;
-	};
+    * Accepts an array of Strings telling logger to mute those type of messages.
+    * Possible values are 'SYS' and 'USER'.  These messages will not be sent to
+    * server.
+    *
+    * @method mute
+    * @param {Array} array of strings of messages to mute.
+    */
+    draperLog.mute = function(d) {
+        d.forEach(function(d) {
+            if(d === 'USER') { muteUserActivityLogging = true; }
+            if(d === 'SYS') { muteSystemActivityLogging = true; }
+        });
+        return draperLog;
+    };
 
-  draperLog.unmute = function(d) {
-    d.forEach(function(d) {
-      if(d === 'USER') { muteUserActivityLogging = false; }
-      if(d === 'SYS') { muteSystemActivityLogging = false; }
-    });
+    draperLog.unmute = function(d) {
+        d.forEach(function(d) {
+          if(d === 'USER') { muteUserActivityLogging = false; }
+          if(d === 'SYS') { muteSystemActivityLogging = false; }
+        });
+        return draperLog;
+    };
+
+  /**
+    * When set to true, no connection will be made against logging server.
+    *
+    * @method testing
+    * @param {Boolean} set to true to disable all connection to logging server
+    */
+    draperLog.testing = function(d) {
+        if (!arguments.length) { return testing; }
+        testing = d;
+        draperLog.worker.postMessage({
+        cmd: 'setTesting',
+        msg: d
+      });
+        return draperLog;
+    };
+
+  /**
+    * DOM Listener for specific events.
+    *
+    */
+    function classListener() {
+
+        $(document).ready(function() {
+            $(".draper").each(function(i,d){
+                $(d).on("click", function(a){
+                    draperLog.logUserActivity('User clicked element', $(this).data('activity'), $(this).data('wf'));
+                });
+            });
+
+            $(window).scroll(function() {
+                clearTimeout($.data(this, 'scrollTimer'));
+                $.data(this, 'scrollTimer', setTimeout(function() {
+                    draperLog.logUserActivity('User scrolled window', 'scroll', 3);
+                }, 500));
+            });
+        });
+    }
+
+    /**
+     * @brief [brief description]
+     * @details [long description]
+     * 
+     * @param elem [description]
+     * @param msg [description]
+     */
+    draperLog.tag = function(elem, msg) {
+        $.each(msg.events, function(i, d) {
+            if (d === 'scroll') {
+                console.log('found scroll');
+                $(elem).scroll(function() {
+                    clearTimeout($.data(this, 'scrollTimer'));
+                    $.data(this, 'scrollTimer', setTimeout(function() {
+                        draperLog.logUserActivity('User scrolled window', 'scroll', 3);
+                    }, 500));
+                });
+            }else{
+                $(elem).on(d, function() {
+                    draperLog.logUserActivity(msg.desc, msg.activity, msg.wf_state);
+                });
+            }
+        });
+    };
+
+    // Return the activity logger object in which is created. With this, 
+    // object functions and variable are created to keep this a separate instance
+    // of the logger.
     return draperLog;
-  };
-
-  /**
-	* When set to true, no connection will be made against logging server.
-	*
-	* @method testing
-	* @param {Boolean} set to true to disable all connection to logging server
-	*/
-	draperLog.testing = function(d) {
-		if (!arguments.length) { return testing; }
-		testing = d;
-		draperLog.worker.postMessage({
-	  	cmd: 'setTesting',
-	  	msg: d
-	  });
-		return draperLog;
-	};
-
-  /**
-	* DOM Listener for specific events.
-	*
-	*/
-	function classListener() {
-
-		$(document).ready(function() {
-			$(".draper").each(function(i,d){
-				$(d).on("click", function(a){
-					draperLog.logUserActivity('User clicked element', $(this).data('activity'), $(this).data('wf'));
-				});
-			});
-
-			$(window).scroll(function() {
-				clearTimeout($.data(this, 'scrollTimer'));
-				$.data(this, 'scrollTimer', setTimeout(function() {
-					draperLog.logUserActivity('User scrolled window', 'scroll', 3);
-				}, 500));
-			});
-		});
-	}
-
-  /**
-	* Tag specific elements
-	*
-	*/
-	draperLog.tag = function(elem, msg) {
-		$.each(msg.events, function(i, d) {
-			if (d === 'scroll') {
-				console.log('found scroll');
-				$(elem).scroll(function() {
-					clearTimeout($.data(this, 'scrollTimer'));
-					$.data(this, 'scrollTimer', setTimeout(function() {
-						draperLog.logUserActivity('User scrolled window', 'scroll', 3);
-					}, 500));
-				});
-			}else{
-				$(elem).on(d, function() {
-					draperLog.logUserActivity(msg.desc, msg.activity, msg.wf_state);
-				});
-			}
-		});
-	};
-
-	return draperLog;
 }
\ No newline at end of file
diff --git a/helper-libs/javascript/draper.activity_worker-2.1.1.js b/helper-libs/javascript/draper.activity_worker-2.1.1.js
index 827da17..7ce3b8f 100644
--- a/helper-libs/javascript/draper.activity_worker-2.1.1.js
+++ b/helper-libs/javascript/draper.activity_worker-2.1.1.js
@@ -1,105 +1,199 @@
 var logBuffer = [];
-var loggingUrl = 'http://localhost:3001';
+var loggingUrl = 'http://localhost:8080';
 var intervalTime = 5000; //send every 5 seconds
 var testing = false;
 var echo = true;
 var msg = 'DRAPER LOG: ';
 
-function timerMethod() {
-
-	if (logBuffer.length) {
-    if (echo) {
-      console.log(msg + 'sent ' + logBuffer.length + ' logs to - ' + loggingUrl);
-    }
-		if (!testing) {
-			XHR(loggingUrl + '/send_log', logBuffer, function(d) {
-				logBuffer = [];
-			});
-		} else {
-      logBuffer = [];
-    }
-	}	else {
-		if (echo) {
-			console.log(msg + 'no log sent, buffer empty.');
-		}
-	}
-}
-
+// Register the interval timer to poll every intervalTime whether
+// is data that is needed to be send to the server or not.
 var timerId = setInterval(timerMethod, intervalTime);
 
-self.addEventListener('message', function(e) {
-  var data = e.data;
-  switch (data.cmd) {
-    case 'setLoggingUrl':
-			loggingUrl = data.msg;
-      break;
-    case 'sendMsg':
-      logBuffer.push(data.msg);
-      break;
-    case 'setTesting':
-    	if (data.msg) {
-    		msg = 'DRAPER LOG: (TESTING) ';
-    	} else {
-    		msg = 'DRAPER LOG: ';
-    	}
-      testing = data.msg;
-      break;
-    case 'setEcho':
-      echo = data.msg;
-      break;
-    case 'sendBuffer':
-    	sendBuffer();
-    	break;
-  }
-}, false);
-
-
-function sendBuffer() {
-  // method to force send the buffer
-	timerMethod();
-	if (echo) {
-		console.log(msg + ' buffer sent');
-	}
+/**
+ * @brief Function which handles sending debug information to the web browser's
+ * console.
+ * @details Function which handles sending debug information to the web browser's
+ * console. This allows for one line debugging which toggles between debugging or
+ * not
+ * 
+ * @param msg Message to log to the console.
+ */
+function debug(user_msg)
+{
+    if(echo)
+        console.log(msg + user_msg);
 }
-//simple XHR request in pure raw JavaScript
+
+/**
+ * @brief Timer Method to poll and check for new messages to send to the logging 
+ * ELK server.
+ * @details Timer Method to poll and check for new messages to send to the logging 
+ * ELK server. The method will be fired after each intervalTime and attempts to send
+ * any pending logs which may have been created by the user.
+ */
+function timerMethod() {
+    // Check to see if there is anything within the global logBuffer. If there are any
+    // new entries, attemp to send the data.
+    if (logBuffer.length) {
+        
+        // If echo is enabled, echo debugging information to the console for developers
+        // to debug their application and see if logs are being send to the logging 
+        // server
+        debug('Sent ' + logBuffer.length + ' logs to - ' + loggingUrl);
+        
+        // Check to see if the developer has set the module to be within testing mode. In
+        // this mode, we are able to defer attempts at sending the logging request to 
+        // the logging server and just drop the logs.
+        if (testing)
+            logBuffer = [];
+        else
+            XHR(loggingUrl + '/send_log', logBuffer, function(d) { logBuffer = []; });
+    }  
+
+    // If we don't have any logs to send to the server, just return 
+    // back to the caller. There are no actions that need to be done
+    // when it comes to logging.
+    else
+    {
+        // If we have debugging enabled, send a debug message saying there
+        // are no logs present to be sent to the logging server.
+        debug('No log sent, buffer empty.');
+    }
+}
+
+/**
+ * @brief Adding Event Listener for the Activity worker.
+ * @details Adding event listener for the activity worker. This will allow
+ * the activity logger to message the activity worker as it is running.
+ */
+self.addEventListener('message', 
+    function(e) {
+        var data = e.data;
+
+        // Switch based on the command that was received by the message.
+        switch (data.cmd) {
+            // SetLoggingUrl: This allows the developer to change the location in which the 
+            // logging is being stored to. This will allow for custom logging servers.
+            case 'setLoggingUrl':
+                loggingUrl = data.msg;
+                break;
+
+            // SendMsg command: This adds a new log to the log buffer which will be sent 
+            // to the server. The worker pushes this log into the buffer and sits there until
+            // the interval time, or a SendBuffer command forces the worker to send the logs.
+            case 'sendMsg':
+                logBuffer.push(data.msg);
+                break;
+
+            // SetTesting command: This sets the activity logger to a testing mode where
+            // no logs are being send to the server. This will allow the developer to see
+            // what is being logged without the attempt of sending the logs to the log 
+            // server.
+            case 'setTesting':
+                if (data.msg) 
+                    msg = 'DRAPER LOG: (TESTING) ';
+                else 
+                    msg = 'DRAPER LOG: ';
+                
+                testing = data.msg;
+                break;
+
+            // SetEcho command: This allows the developer to debug their application
+            // by echoing debug messages of what is currently being logged by the
+            // tool/application.
+            case 'setEcho':
+                echo = data.msg;
+                break;
+            
+            // SendBuffer command forces the activity worker to send what is currently
+            // in the log buffer. It is the same premise as a flush command where all 
+            // the logs are getting flushed to the server.
+            case 'sendBuffer':
+                sendBuffer();
+                break;
+        }
+    }, false);
+
+/**
+ * @brief Sends the logs to the logging server.
+ * @details Sends the logs to the logging server. This is done by calling the
+ * timerMethod() which is responsible for sending the logs to the server and 
+ * updating the timer interval.
+ */
+function sendBuffer() {
+    // method to force send the buffer
+    timerMethod();
+    if (echo) {
+        console.log(msg + ' buffer sent');
+    }
+}
+
+/**
+ * @brief Connect and send logging information through XMLHttpRequest
+ * @details Connect and send logging information through XMLHttpRequest. 
+ * Function attempts to connect through different means of the 
+ * XMLHttpRequest (xhr) object. Once the xhr object is created, the
+ * logging data that has been buffered is sent to the server.
+ * 
+ * @param url The URL to connect and send the logging data to
+ * @param log The logging information that is being sent to the server
+ * @param callback Callback function to register when a response is 
+ * received.
+ */
 function XHR(url, log, callback) {
-	var xhr;
+    var xhr;
 
-	if(typeof XMLHttpRequest !== 'undefined') xhr = new XMLHttpRequest();
-	else {
-		var versions = ["MSXML2.XmlHttp.5.0",
-		 				"MSXML2.XmlHttp.4.0",
-		 			  "MSXML2.XmlHttp.3.0",
-		 			  "MSXML2.XmlHttp.2.0",
-		 				"Microsoft.XmlHttp"];
+    if(typeof XMLHttpRequest !== 'undefined') 
+        xhr = new XMLHttpRequest();
+    else 
+    {
+        var versions = ["MSXML2.XmlHttp.5.0",
+                        "MSXML2.XmlHttp.4.0",
+                        "MSXML2.XmlHttp.3.0",
+                        "MSXML2.XmlHttp.2.0",
+                        "Microsoft.XmlHttp"];
 
-		 for(var i = 0, len = versions.length; i < len; i++) {
-		 	try {
-		 		xhr = new ActiveXObject(versions[i]);
-		 		break;
-		 	}
-		 	catch(e){}
-		 } // end for
-	}
+         for(var i = 0, len = versions.length; i < len; i++) {
+            try {
+                xhr = new ActiveXObject(versions[i]);
+                break;
+            }
+            catch(e){}
+         } // end for
+    }
 
-	xhr.onreadystatechange = ensureReadiness;
+    // Register the readiness function.
+    xhr.onreadystatechange = ensureReadiness;
 
-	function ensureReadiness() {
-		if(xhr.readyState < 4) {
-			return;
-		}
+    // Create a readiness callback function to handle the changes within
+    // the attempted request. Also, allows the program to handle the request,
+    // if need be.
+    function ensureReadiness() {
+        // If we receive a response readiness that is not 
+        // 4, then dismiss until we do.
+        if(xhr.readyState < 4) {
+            return;
+        }
 
-		if(xhr.status !== 200) {
-			return;
-		}
+        // If we have a readiness of 4, but yet, we have an
+        // invalid request, just return.
+        // TODO: Log or handle this to inform the developer that
+        // there are problems occurring?
+        if(xhr.status !== 200) {
+            return;
+        }
 
-		// all is well
-		if(xhr.readyState === 4) {
-			callback(xhr);
-		}
-	}
+        // If the readiness status is set to 4, and receieved
+        // an "OK" from the server, call the register callback if one
+        // exists
+        // TODO: Check for null callback.
+        if(xhr.readyState === 4) {
+            callback(xhr);
+        }
+    }
 
-	xhr.open("POST", url, true);
-	xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
-	xhr.send(JSON.stringify(log));
+    // Open and send the data to the logging server.
+    xhr.open("POST", url, true);
+    xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
+    xhr.send(JSON.stringify(log));
 }
