Bug 960894 - 3.d/4: look up foreign objects through 'this.context'. r=hsinyi
authorVicamo Yang <vyang@mozilla.com>
Mon, 17 Feb 2014 19:35:07 +0800
changeset 169524 9d60d4e854a3b73498f98b87a2279ff46445a823
parent 169523 5725bfc6d45e13da84a3b4a6a1ee123d39cf5259
child 169525 2cdf076eb83313bedb454540da1c41b90464de24
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewershsinyi
bugs960894
milestone30.0a1
Bug 960894 - 3.d/4: look up foreign objects through 'this.context'. r=hsinyi
dom/system/gonk/ril_worker.js
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -89,19 +89,22 @@ let RILQUIRKS_EXTRA_UINT32_2ND_CALL;
 let RILQUIRKS_HAVE_QUERY_ICC_LOCK_RETRY_COUNT;
 
 // Ril quirk to Send STK Profile Download
 let RILQUIRKS_SEND_STK_PROFILE_DOWNLOAD;
 
 // Ril quirk to attach data registration on demand.
 let RILQUIRKS_DATA_REGISTRATION_ON_DEMAND;
 
-function BufObject() {
+function BufObject(aContext) {
+  this.context = aContext;
 }
 BufObject.prototype = {
+  context: null,
+
   mToken: 0,
   mTokenRequestMap: null,
 
   init: function() {
     this._init();
 
     // This gets incremented each time we send out a parcel.
     this.mToken = 1;
@@ -141,17 +144,17 @@ BufObject.prototype = {
     } else if (response_type == RESPONSE_TYPE_UNSOLICITED) {
       request_type = this.readInt32();
       if (DEBUG) debug("Unsolicited response for request type " + request_type);
     } else {
       if (DEBUG) debug("Unknown response type: " + response_type);
       return;
     }
 
-    RIL.handleParcel(request_type, this.readAvailable, options);
+    this.context.RIL.handleParcel(request_type, this.readAvailable, options);
   },
 
   /**
    * Start a new outgoing parcel.
    *
    * @param type
    *        Integer specifying the request type.
    * @param options [optional]
@@ -195,26 +198,30 @@ BufObject.prototype = {
 
 /**
  * The RIL state machine.
  *
  * This object communicates with rild via parcels and with the main thread
  * via post messages. It maintains state about the radio, ICC, calls, etc.
  * and acts upon state changes accordingly.
  */
-function RilObject() {
+function RilObject(aContext) {
+  this.context = aContext;
+
   this.currentCalls = {};
   this.currentConference = {state: null, participants: {}};
   this.currentDataCalls = {};
   this._receivedSmsSegmentsMap = {};
   this._pendingSentSmsMap = {};
   this.pendingNetworkType = {};
   this._receivedSmsCbPagesMap = {};
 }
 RilObject.prototype = {
+  context: null,
+
   v5Legacy: null,
 
   /**
    * Valid calls.
    */
   currentCalls: null,
 
   /**
@@ -445,17 +452,17 @@ RilObject.prototype = {
    * an object, which then contains all of the parameters as attributes.
    * The "@param" documentation is to be interpreted accordingly.
    */
 
   /**
    * Retrieve the ICC's status.
    */
   getICCStatus: function() {
-    Buf.simpleRequest(REQUEST_GET_SIM_STATUS);
+    this.context.Buf.simpleRequest(REQUEST_GET_SIM_STATUS);
   },
 
   /**
    * Helper function for unlocking ICC locks.
    */
   iccUnlockCardLock: function(options) {
     switch (options.lockType) {
       case GECKO_CARDLOCK_PIN:
@@ -495,16 +502,17 @@ RilObject.prototype = {
    * Enter a PIN to unlock the ICC.
    *
    * @param pin
    *        String containing the PIN.
    * @param [optional] aid
    *        AID value.
    */
   enterICCPIN: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_ENTER_SIM_PIN, options);
     Buf.writeInt32(this.v5Legacy ? 1 : 2);
     Buf.writeString(options.pin);
     if (!this.v5Legacy) {
       Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
@@ -513,16 +521,17 @@ RilObject.prototype = {
    * Enter a PIN2 to unlock the ICC.
    *
    * @param pin
    *        String containing the PIN2.
    * @param [optional] aid
    *        AID value.
    */
   enterICCPIN2: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_ENTER_SIM_PIN2, options);
     Buf.writeInt32(this.v5Legacy ? 1 : 2);
     Buf.writeString(options.pin);
     if (!this.v5Legacy) {
       Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
@@ -531,16 +540,17 @@ RilObject.prototype = {
    * Requests a network personalization be deactivated.
    *
    * @param type
    *        Integer indicating the network personalization be deactivated.
    * @param password
    *        String containing the password.
    */
   enterDepersonalization: function(type, password, options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE, options);
     Buf.writeInt32(type);
     Buf.writeString(password);
     Buf.sendParcel();
   },
 
   /**
    * Helper function for changing ICC locks.
@@ -589,16 +599,17 @@ RilObject.prototype = {
    * @param pin
    *        String containing the old PIN value
    * @param newPin
    *        String containing the new PIN value
    * @param [optional] aid
    *        AID value.
    */
   changeICCPIN: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_CHANGE_SIM_PIN, options);
     Buf.writeInt32(this.v5Legacy ? 2 : 3);
     Buf.writeString(options.pin);
     Buf.writeString(options.newPin);
     if (!this.v5Legacy) {
       Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
@@ -610,16 +621,17 @@ RilObject.prototype = {
    * @param pin
    *        String containing the old PIN2 value
    * @param newPin
    *        String containing the new PIN2 value
    * @param [optional] aid
    *        AID value.
    */
   changeICCPIN2: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_CHANGE_SIM_PIN2, options);
     Buf.writeInt32(this.v5Legacy ? 2 : 3);
     Buf.writeString(options.pin);
     Buf.writeString(options.newPin);
     if (!this.v5Legacy) {
       Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
@@ -630,16 +642,17 @@ RilObject.prototype = {
    * @param puk
    *        String containing the PUK value.
    * @param newPin
    *        String containing the new PIN value.
    * @param [optional] aid
    *        AID value.
    */
    enterICCPUK: function(options) {
+     let Buf = this.context.Buf;
      Buf.newParcel(REQUEST_ENTER_SIM_PUK, options);
      Buf.writeInt32(this.v5Legacy ? 2 : 3);
      Buf.writeString(options.puk);
      Buf.writeString(options.newPin);
      if (!this.v5Legacy) {
        Buf.writeString(options.aid || this.aid);
      }
      Buf.sendParcel();
@@ -651,16 +664,17 @@ RilObject.prototype = {
    * @param puk
    *        String containing the PUK2 value.
    * @param newPin
    *        String containing the new PIN2 value.
    * @param [optional] aid
    *        AID value.
    */
    enterICCPUK2: function(options) {
+     let Buf = this.context.Buf;
      Buf.newParcel(REQUEST_ENTER_SIM_PUK2, options);
      Buf.writeInt32(this.v5Legacy ? 2 : 3);
      Buf.writeString(options.puk);
      Buf.writeString(options.newPin);
      if (!this.v5Legacy) {
        Buf.writeString(options.aid || this.aid);
      }
      Buf.sendParcel();
@@ -732,16 +746,17 @@ RilObject.prototype = {
    * Query ICC lock retry count.
    *
    * @param selCode
    *        One of ICC_SEL_CODE_*.
    * @param serviceClass
    *        One of ICC_SERVICE_CLASS_*.
    */
   queryICCLockRetryCount: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_GET_UNLOCK_RETRY_COUNT, options);
     Buf.writeInt32(1);
     Buf.writeString(options.selCode);
     Buf.sendParcel();
   },
 
   /**
    * Query ICC facility lock.
@@ -751,16 +766,17 @@ RilObject.prototype = {
    * @param password
    *        Password for the facility, or "" if not required.
    * @param serviceClass
    *        One of ICC_SERVICE_CLASS_*.
    * @param [optional] aid
    *        AID value.
    */
   queryICCFacilityLock: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_QUERY_FACILITY_LOCK, options);
     Buf.writeInt32(this.v5Legacy ? 3 : 4);
     Buf.writeString(options.facility);
     Buf.writeString(options.password);
     Buf.writeString(options.serviceClass.toString());
     if (!this.v5Legacy) {
       Buf.writeString(options.aid || this.aid);
     }
@@ -777,16 +793,17 @@ RilObject.prototype = {
    * @param password
    *        Password for the facility, or "" if not required.
    * @param serviceClass
    *        One of ICC_SERVICE_CLASS_*.
    * @param [optional] aid
    *        AID value.
    */
   setICCFacilityLock: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SET_FACILITY_LOCK, options);
     Buf.writeInt32(this.v5Legacy ? 4 : 5);
     Buf.writeString(options.facility);
     Buf.writeString(options.enabled ? "1" : "0");
     Buf.writeString(options.password);
     Buf.writeString(options.serviceClass.toString());
     if (!this.v5Legacy) {
       Buf.writeString(options.aid || this.aid);
@@ -812,16 +829,17 @@ RilObject.prototype = {
    *  @param [optional] dataWriter
    *         The function for writing string parameter for the ICC_COMMAND_UPDATE_RECORD.
    *  @param [optional] pin2
    *         String containing the PIN2.
    *  @param [optional] aid
    *         AID value.
    */
   iccIO: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SIM_IO, options);
     Buf.writeInt32(options.command);
     Buf.writeInt32(options.fileId);
     Buf.writeString(options.pathId);
     Buf.writeInt32(options.p1);
     Buf.writeInt32(options.p2);
     Buf.writeInt32(options.p3);
 
@@ -849,16 +867,17 @@ RilObject.prototype = {
 
   /**
    * Get IMSI.
    *
    * @param [optional] aid
    *        AID value.
    */
   getIMSI: function(aid) {
+    let Buf = this.context.Buf;
     if (this.v5Legacy) {
       Buf.simpleRequest(REQUEST_GET_IMSI);
       return;
     }
     Buf.newParcel(REQUEST_GET_IMSI);
     Buf.writeInt32(1);
     Buf.writeString(aid || this.aid);
     Buf.sendParcel();
@@ -874,17 +893,17 @@ RilObject.prototype = {
    */
   readICCContacts: function(options) {
     if (!this.appType) {
       options.errorMsg = CONTACT_ERR_REQUEST_NOT_SUPPORTED;
       this.sendChromeMessage(options);
       return;
     }
 
-    ICCContactHelper.readICCContacts(
+    this.context.ICCContactHelper.readICCContacts(
       this.appType,
       options.contactType,
       function onsuccess(contacts) {
         for (let i = 0; i < contacts.length; i++) {
           let contact = contacts[i];
           let pbrIndex = contact.pbrIndex || 0;
           let recordIndex = pbrIndex * ICC_MAX_LINEAR_FIXED_RECORDS + contact.recordId;
           contact.contactId = this.iccInfo.iccid + recordIndex;
@@ -936,16 +955,17 @@ RilObject.prototype = {
       contact.recordId = recordIndex % ICC_MAX_LINEAR_FIXED_RECORDS;
       isValidRecordId = contact.recordId > 0 && contact.recordId < 0xff;
     }
 
     if (DEBUG) {
       debug("Update ICC Contact " + JSON.stringify(contact));
     }
 
+    let ICCContactHelper = this.context.ICCContactHelper;
     // If contact has 'recordId' property, updates corresponding record.
     // If not, inserts the contact into a free record.
     if (isValidRecordId) {
       ICCContactHelper.updateICCContact(
         this.appType, options.contactType, contact, options.pin2, onsuccess, onerror);
     } else {
       ICCContactHelper.addICCContact(
         this.appType, options.contactType, contact, options.pin2, onsuccess, onerror);
@@ -954,26 +974,29 @@ RilObject.prototype = {
 
   /**
    * Request the phone's radio to be enabled or disabled.
    *
    * @param enabled
    *        Boolean indicating the desired state.
    */
   setRadioEnabled: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_RADIO_POWER, options);
     Buf.writeInt32(1);
     Buf.writeInt32(options.enabled ? 1 : 0);
     Buf.sendParcel();
   },
 
   /**
    * Query call waiting status via MMI.
    */
   _handleQueryMMICallWaiting: function(options) {
+    let Buf = this.context.Buf;
+
     function callback(options) {
       options.length = Buf.readInt32();
       options.enabled = (Buf.readInt32() === 1);
       let services = Buf.readInt32();
       if (options.enabled) {
         options.statusMessage = MMI_SM_KS_SERVICE_ENABLED_FOR;
         let serviceClass = [];
         for (let serviceClassMask = 1;
@@ -1017,102 +1040,106 @@ RilObject.prototype = {
     this.setCallWaiting(options);
   },
 
   /**
    * Query call waiting status.
    *
    */
   queryCallWaiting: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_QUERY_CALL_WAITING, options);
     Buf.writeInt32(1);
     // As per 3GPP TS 24.083, section 1.6 UE doesn't need to send service
     // class parameter in call waiting interrogation  to network
     Buf.writeInt32(ICC_SERVICE_CLASS_NONE);
     Buf.sendParcel();
   },
 
   /**
    * Set call waiting status.
    *
    * @param on
    *        Boolean indicating the desired waiting status.
    */
   setCallWaiting: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SET_CALL_WAITING, options);
     Buf.writeInt32(2);
     Buf.writeInt32(options.enabled ? 1 : 0);
     Buf.writeInt32(options.serviceClass !== undefined ?
                     options.serviceClass : ICC_SERVICE_CLASS_VOICE);
     Buf.sendParcel();
   },
 
   /**
    * Queries current CLIP status.
    *
    * (MMI request for code "*#30#")
    *
    */
   queryCLIP: function(options) {
-    Buf.simpleRequest(REQUEST_QUERY_CLIP, options);
+    this.context.Buf.simpleRequest(REQUEST_QUERY_CLIP, options);
   },
 
   /**
    * Queries current CLIR status.
    *
    */
   getCLIR: function(options) {
-    Buf.simpleRequest(REQUEST_GET_CLIR, options);
+    this.context.Buf.simpleRequest(REQUEST_GET_CLIR, options);
   },
 
   /**
    * Enables or disables the presentation of the calling line identity (CLI) to
    * the called party when originating a call.
    *
    * @param options.clirMode
    *        Is one of the CLIR_* constants in
    *        nsIDOMMozMobileConnection interface.
    */
   setCLIR: function(options) {
     if (options) {
       this.clirMode = options.clirMode;
     }
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SET_CLIR, options);
     Buf.writeInt32(1);
     Buf.writeInt32(this.clirMode);
     Buf.sendParcel();
   },
 
   /**
    * Set screen state.
    *
    * @param on
    *        Boolean indicating whether the screen should be on or off.
    */
   setScreenState: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SCREEN_STATE);
     Buf.writeInt32(1);
     Buf.writeInt32(options.on ? 1 : 0);
     Buf.sendParcel();
   },
 
   getVoiceRegistrationState: function() {
-    Buf.simpleRequest(REQUEST_VOICE_REGISTRATION_STATE);
+    this.context.Buf.simpleRequest(REQUEST_VOICE_REGISTRATION_STATE);
   },
 
   getVoiceRadioTechnology: function() {
-    Buf.simpleRequest(REQUEST_VOICE_RADIO_TECH);
+    this.context.Buf.simpleRequest(REQUEST_VOICE_RADIO_TECH);
   },
 
   getDataRegistrationState: function() {
-    Buf.simpleRequest(REQUEST_DATA_REGISTRATION_STATE);
+    this.context.Buf.simpleRequest(REQUEST_DATA_REGISTRATION_STATE);
   },
 
   getOperator: function() {
-    Buf.simpleRequest(REQUEST_OPERATOR);
+    this.context.Buf.simpleRequest(REQUEST_OPERATOR);
   },
 
   /**
    * Set the preferred network type.
    *
    * @param options An object contains a valid index of
    *                RIL_PREFERRED_NETWORK_TYPE_TO_GECKO as its `networkType`
    *                attribute, or undefined to set current preferred network
@@ -1121,27 +1148,28 @@ RilObject.prototype = {
   setPreferredNetworkType: function(options) {
     if (options) {
       this.preferredNetworkType = options.networkType;
     }
     if (this.preferredNetworkType == null) {
       return;
     }
 
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SET_PREFERRED_NETWORK_TYPE, options);
     Buf.writeInt32(1);
     Buf.writeInt32(this.preferredNetworkType);
     Buf.sendParcel();
   },
 
   /**
    * Get the preferred network type.
    */
   getPreferredNetworkType: function(options) {
-    Buf.simpleRequest(REQUEST_GET_PREFERRED_NETWORK_TYPE, options);
+    this.context.Buf.simpleRequest(REQUEST_GET_PREFERRED_NETWORK_TYPE, options);
   },
 
   /**
    * Request various states about the network.
    */
   requestNetworkInfo: function() {
     if (this._processingNetworkInfo) {
       if (DEBUG) debug("Network info requested, but we're already requesting network info.");
@@ -1159,86 +1187,90 @@ RilObject.prototype = {
     this.getSignalStrength();
   },
 
   /**
    * Get the available networks
    */
   getAvailableNetworks: function(options) {
     if (DEBUG) debug("Getting available networks");
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_QUERY_AVAILABLE_NETWORKS, options);
     Buf.sendParcel();
   },
 
   /**
    * Request the radio's network selection mode
    */
   getNetworkSelectionMode: function() {
     if (DEBUG) debug("Getting network selection mode");
-    Buf.simpleRequest(REQUEST_QUERY_NETWORK_SELECTION_MODE);
+    this.context.Buf.simpleRequest(REQUEST_QUERY_NETWORK_SELECTION_MODE);
   },
 
   /**
    * Tell the radio to automatically choose a voice/data network
    */
   selectNetworkAuto: function(options) {
     if (DEBUG) debug("Setting automatic network selection");
-    Buf.simpleRequest(REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, options);
+    this.context.Buf.simpleRequest(REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, options);
   },
 
   /**
    * Set the roaming preference mode
    */
   setRoamingPreference: function(options) {
     let roamingMode = CDMA_ROAMING_PREFERENCE_TO_GECKO.indexOf(options.mode);
 
     if (roamingMode === -1) {
       options.errorMsg = GECKO_ERROR_INVALID_PARAMETER;
       this.sendChromeMessage(options);
       return;
     }
 
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_CDMA_SET_ROAMING_PREFERENCE, options);
     Buf.writeInt32(1);
     Buf.writeInt32(roamingMode);
     Buf.sendParcel();
   },
 
   /**
    * Get the roaming preference mode
    */
   queryRoamingPreference: function(options) {
-    Buf.simpleRequest(REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, options);
+    this.context.Buf.simpleRequest(REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, options);
   },
 
   /**
    * Set the voice privacy mode
    */
   setVoicePrivacyMode: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, options);
     Buf.writeInt32(1);
     Buf.writeInt32(options.enabled ? 1 : 0);
     Buf.sendParcel();
   },
 
   /**
    * Get the voice privacy mode
    */
   queryVoicePrivacyMode: function(options) {
-    Buf.simpleRequest(REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE, options);
+    this.context.Buf.simpleRequest(REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE, options);
   },
 
   /**
    * Open Logical UICC channel (aid) for Secure Element access
    */
   iccOpenChannel: function(options) {
     if (DEBUG) {
       debug("iccOpenChannel: " + JSON.stringify(options));
     }
 
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SIM_OPEN_CHANNEL, options);
     Buf.writeString(options.aid);
     Buf.sendParcel();
   },
 
 /**
    * Exchange APDU data on an open Logical UICC channel
    */
@@ -1251,16 +1283,17 @@ RilObject.prototype = {
     let path = options.apdu.path || "";
     let data = options.apdu.data || "";
     let data2 = options.apdu.data2 || "";
 
     let p1 = options.apdu.p1;
     let p2 = options.apdu.p2;
     let p3 = options.apdu.p3; // Extra
 
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SIM_ACCESS_CHANNEL, options);
     Buf.writeInt32(cla);
     Buf.writeInt32(command);
     Buf.writeInt32(channel);
     Buf.writeString(path); // path
     Buf.writeInt32(p1);
     Buf.writeInt32(p2);
     Buf.writeInt32(p3);
@@ -1271,72 +1304,74 @@ RilObject.prototype = {
   },
 
   /**
    * Close Logical UICC channel
    */
   iccCloseChannel: function(options) {
     if (DEBUG) debug("iccCloseChannel: " + JSON.stringify(options));
 
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SIM_CLOSE_CHANNEL, options);
     Buf.writeInt32(1);
     Buf.writeInt32(options.channel);
     Buf.sendParcel();
   },
 
   /**
    * Tell the radio to choose a specific voice/data network
    */
   selectNetwork: function(options) {
     if (DEBUG) {
       debug("Setting manual network selection: " + options.mcc + ", " + options.mnc);
     }
 
     let numeric = (options.mcc && options.mnc) ? options.mcc + options.mnc : null;
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SET_NETWORK_SELECTION_MANUAL, options);
     Buf.writeString(numeric);
     Buf.sendParcel();
   },
 
   /**
    * Get current calls.
    */
   getCurrentCalls: function() {
-    Buf.simpleRequest(REQUEST_GET_CURRENT_CALLS);
+    this.context.Buf.simpleRequest(REQUEST_GET_CURRENT_CALLS);
   },
 
   /**
    * Get the signal strength.
    */
   getSignalStrength: function() {
-    Buf.simpleRequest(REQUEST_SIGNAL_STRENGTH);
+    this.context.Buf.simpleRequest(REQUEST_SIGNAL_STRENGTH);
   },
 
   getIMEI: function(options) {
-    Buf.simpleRequest(REQUEST_GET_IMEI, options);
+    this.context.Buf.simpleRequest(REQUEST_GET_IMEI, options);
   },
 
   getIMEISV: function() {
-    Buf.simpleRequest(REQUEST_GET_IMEISV);
+    this.context.Buf.simpleRequest(REQUEST_GET_IMEISV);
   },
 
   getDeviceIdentity: function() {
-    Buf.simpleRequest(REQUEST_DEVICE_IDENTITY);
+    this.context.Buf.simpleRequest(REQUEST_DEVICE_IDENTITY);
   },
 
   getBasebandVersion: function() {
-    Buf.simpleRequest(REQUEST_BASEBAND_VERSION);
+    this.context.Buf.simpleRequest(REQUEST_BASEBAND_VERSION);
   },
 
   sendExitEmergencyCbModeRequest: function(options) {
-    Buf.simpleRequest(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, options);
+    this.context.Buf.simpleRequest(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, options);
   },
 
   getCdmaSubscription: function() {
-    Buf.simpleRequest(REQUEST_CDMA_SUBSCRIPTION);
+    this.context.Buf.simpleRequest(REQUEST_CDMA_SUBSCRIPTION);
   },
 
   exitEmergencyCbMode: function(options) {
     // The function could be called by an API from RadioInterfaceLayer or by
     // ril_worker itself. From ril_worker, we won't pass the parameter
     // 'options'. In this case, it is marked as internal.
     if (!options) {
       options = {internal: true};
@@ -1427,16 +1462,17 @@ RilObject.prototype = {
       this.setRadioEnabled({enabled: true});
       return;
     }
 
     this.sendDialRequest(options);
   },
 
   sendDialRequest: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(options.request, options);
     Buf.writeString(options.number);
     Buf.writeInt32(options.clirMode || 0);
     Buf.writeInt32(options.uusInfo || 0);
     // TODO Why do we need this extra 0? It was put it in to make this
     // match the format of the binary message.
     Buf.writeInt32(0);
     Buf.sendParcel();
@@ -1458,16 +1494,17 @@ RilObject.prototype = {
    *        Call index (1-based) as reported by REQUEST_GET_CURRENT_CALLS.
    */
   hangUp: function(options) {
     let call = this.currentCalls[options.callIndex];
     if (!call) {
       return;
     }
 
+    let Buf = this.context.Buf;
     switch (call.state) {
       case CALL_STATE_ACTIVE:
       case CALL_STATE_DIALING:
       case CALL_STATE_ALERTING:
         Buf.newParcel(REQUEST_HANGUP);
         Buf.writeInt32(1);
         Buf.writeInt32(options.callIndex);
         Buf.sendParcel();
@@ -1480,16 +1517,17 @@ RilObject.prototype = {
 
   /**
    * Mute or unmute the radio.
    *
    * @param mute
    *        Boolean to indicate whether to mute or unmute the radio.
    */
   setMute: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SET_MUTE);
     Buf.writeInt32(1);
     Buf.writeInt32(options.muted ? 1 : 0);
     Buf.sendParcel();
   },
 
   /**
    * Answer an incoming/waiting call.
@@ -1502,16 +1540,17 @@ RilObject.prototype = {
     // notification the incoming/waiting call may have changed. The main
     // thread thinks that it is answering the call with the given index,
     // so only answer if that is still incoming/waiting.
     let call = this.currentCalls[options.callIndex];
     if (!call) {
       return;
     }
 
+    let Buf = this.context.Buf;
     switch (call.state) {
       case CALL_STATE_INCOMING:
         Buf.simpleRequest(REQUEST_ANSWER);
         break;
       case CALL_STATE_WAITING:
         // Answer the waiting (second) call, and hold the first call.
         Buf.simpleRequest(REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE);
         break;
@@ -1529,16 +1568,17 @@ RilObject.prototype = {
     // notification the incoming/waiting call may have changed. The main
     // thread thinks that it is rejecting the call with the given index,
     // so only reject if that is still incoming/waiting.
     let call = this.currentCalls[options.callIndex];
     if (!call) {
       return;
     }
 
+    let Buf = this.context.Buf;
     if (this._isCdma) {
       // AT+CHLD=0 means "release held or UDUB."
       Buf.simpleRequest(REQUEST_HANGUP_WAITING_OR_BACKGROUND);
       return;
     }
 
     switch (call.state) {
       case CALL_STATE_INCOMING:
@@ -1549,54 +1589,56 @@ RilObject.prototype = {
         Buf.simpleRequest(REQUEST_HANGUP_WAITING_OR_BACKGROUND);
         break;
     }
   },
 
   holdCall: function(options) {
     let call = this.currentCalls[options.callIndex];
     if (call && call.state == CALL_STATE_ACTIVE) {
+      let Buf = this.context.Buf;
       if (this._isCdma) {
         Buf.newParcel(REQUEST_CDMA_FLASH);
         Buf.writeString("");
         Buf.sendParcel();
       } else {
         Buf.simpleRequest(REQUEST_SWITCH_HOLDING_AND_ACTIVE);
       }
     }
   },
 
   resumeCall: function(options) {
     let call = this.currentCalls[options.callIndex];
     if (call && call.state == CALL_STATE_HOLDING) {
-      Buf.simpleRequest(REQUEST_SWITCH_HOLDING_AND_ACTIVE);
+      this.context.Buf.simpleRequest(REQUEST_SWITCH_HOLDING_AND_ACTIVE);
     }
   },
 
   // Flag indicating whether user has requested making a conference call.
   _hasConferenceRequest: false,
 
   conferenceCall: function(options) {
     this._hasConferenceRequest = true;
-    Buf.simpleRequest(REQUEST_CONFERENCE, options);
+    this.context.Buf.simpleRequest(REQUEST_CONFERENCE, options);
   },
 
   separateCall: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SEPARATE_CONNECTION, options);
     Buf.writeInt32(1);
     Buf.writeInt32(options.callIndex);
     Buf.sendParcel();
   },
 
   holdConference: function() {
-    Buf.simpleRequest(REQUEST_SWITCH_HOLDING_AND_ACTIVE);
+    this.context.Buf.simpleRequest(REQUEST_SWITCH_HOLDING_AND_ACTIVE);
   },
 
   resumeConference: function() {
-    Buf.simpleRequest(REQUEST_SWITCH_HOLDING_AND_ACTIVE);
+    this.context.Buf.simpleRequest(REQUEST_SWITCH_HOLDING_AND_ACTIVE);
   },
 
   /**
    * Send an SMS.
    *
    * The `options` parameter object should contain the following attributes:
    *
    * @param number
@@ -1616,37 +1658,39 @@ RilObject.prototype = {
 
     if (!options.segmentSeq) {
       // Fist segment to send
       options.segmentSeq = 1;
       options.body = options.segments[0].body;
       options.encodedBodyLength = options.segments[0].encodedBodyLength;
     }
 
+    let Buf = this.context.Buf;
     if (this._isCdma) {
       Buf.newParcel(REQUEST_CDMA_SEND_SMS, options);
-      CdmaPDUHelper.writeMessage(options);
+      this.context.CdmaPDUHelper.writeMessage(options);
     } else {
       Buf.newParcel(REQUEST_SEND_SMS, options);
       Buf.writeInt32(2);
       Buf.writeString(options.SMSC);
-      GsmPDUHelper.writeMessage(options);
+      this.context.GsmPDUHelper.writeMessage(options);
     }
     Buf.sendParcel();
   },
 
   /**
    * Acknowledge the receipt and handling of an SMS.
    *
    * @param success
    *        Boolean indicating whether the message was successfuly handled.
    * @param cause
    *        SMS_* constant indicating the reason for unsuccessful handling.
    */
   acknowledgeGsmSms: function(success, cause) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SMS_ACKNOWLEDGE);
     Buf.writeInt32(2);
     Buf.writeInt32(success ? 1 : 0);
     Buf.writeInt32(cause);
     Buf.sendParcel();
   },
 
   /**
@@ -1670,16 +1714,17 @@ RilObject.prototype = {
    * Acknowledge the receipt and handling of a CDMA SMS.
    *
    * @param success
    *        Boolean indicating whether the message was successfuly handled.
    * @param cause
    *        SMS_* constant indicating the reason for unsuccessful handling.
    */
   acknowledgeCdmaSms: function(success, cause) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_CDMA_SMS_ACKNOWLEDGE);
     Buf.writeInt32(success ? 0 : 1);
     Buf.writeInt32(cause);
     Buf.sendParcel();
   },
 
   setCellBroadcastDisabled: function(options) {
     this.cellBroadcastDisabled = options.disabled;
@@ -1722,16 +1767,17 @@ RilObject.prototype = {
       this.setSmsBroadcastConfig(this.mergedCellBroadcastConfig);
     } else {
       // It's unnecessary to set config first if we're deactivating.
       this.setSmsBroadcastActivation(false);
     }
   },
 
   setGsmSmsBroadcastConfig: function(config) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_GSM_SET_BROADCAST_SMS_CONFIG);
 
     let numConfigs = config ? config.length / 2 : 0;
     Buf.writeInt32(numConfigs);
     for (let i = 0; i < config.length;) {
       Buf.writeInt32(config[i++]);
       Buf.writeInt32(config[i++]);
       Buf.writeInt32(0x00);
@@ -1743,16 +1789,17 @@ RilObject.prototype = {
   },
 
   /**
    * Send CDMA SMS broadcast config.
    *
    * @see 3GPP2 C.R1001 Sec. 9.2 and 9.3
    */
   setCdmaSmsBroadcastConfig: function(config) {
+    let Buf = this.context.Buf;
     // |config| is an array of half-closed range: [[from, to), [from, to), ...].
     // It will be further decomposed, ex: [1, 4) => 1, 2, 3.
     Buf.newParcel(REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG);
 
     let numConfigs = 0;
     for (let i = 0; i < config.length; i += 2) {
       numConfigs += (config[i+1] - config[i]);
     }
@@ -1778,57 +1825,60 @@ RilObject.prototype = {
     } else {
       this.setGsmSmsBroadcastConfig(config);
     }
   },
 
   setSmsBroadcastActivation: function(activate) {
     let parcelType = this._isCdma ? REQUEST_CDMA_SMS_BROADCAST_ACTIVATION :
                                     REQUEST_GSM_SMS_BROADCAST_ACTIVATION;
+    let Buf = this.context.Buf;
     Buf.newParcel(parcelType);
     Buf.writeInt32(1);
     // See hardware/ril/include/telephony/ril.h, 0 - Activate, 1 - Turn off.
     Buf.writeInt32(activate ? 0 : 1);
     Buf.sendParcel();
   },
 
   /**
    * Start a DTMF Tone.
    *
    * @param dtmfChar
    *        DTMF signal to send, 0-9, *, +
    */
   startTone: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_DTMF_START);
     Buf.writeString(options.dtmfChar);
     Buf.sendParcel();
   },
 
   stopTone: function() {
-    Buf.simpleRequest(REQUEST_DTMF_STOP);
+    this.context.Buf.simpleRequest(REQUEST_DTMF_STOP);
   },
 
   /**
    * Send a DTMF tone.
    *
    * @param dtmfChar
    *        DTMF signal to send, 0-9, *, +
    */
   sendTone: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_DTMF);
     Buf.writeString(options.dtmfChar);
     Buf.sendParcel();
   },
 
   /**
    * Get the Short Message Service Center address.
    */
   getSmscAddress: function(options) {
     if (!this.SMSC) {
-      Buf.simpleRequest(REQUEST_GET_SMSC_ADDRESS, options);
+      this.context.Buf.simpleRequest(REQUEST_GET_SMSC_ADDRESS, options);
       return;
     }
 
     if (!options || options.rilMessageType !== "getSmscAddress") {
       return;
     }
 
     options.smscAddress = this.SMSC;
@@ -1838,16 +1888,17 @@ RilObject.prototype = {
 
   /**
    * Set the Short Message Service Center address.
    *
    * @param smscAddress
    *        Short Message Service Center address in PDU format.
    */
   setSmscAddress: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SET_SMSC_ADDRESS, options);
     Buf.writeString(options.smscAddress);
     Buf.sendParcel();
   },
 
   /**
    * Setup a data call.
    *
@@ -1882,16 +1933,17 @@ RilObject.prototype = {
     // See also bug 901232 and 867873
     let radioTech;
     if (this.v5Legacy) {
       radioTech = this._isCdma ? DATACALL_RADIOTECHNOLOGY_CDMA
                                : DATACALL_RADIOTECHNOLOGY_GSM;
     } else {
       radioTech = options.radioTech + 2;
     }
+    let Buf = this.context.Buf;
     let token = Buf.newParcel(REQUEST_SETUP_DATA_CALL, options);
     Buf.writeInt32(7);
     Buf.writeString(radioTech.toString());
     Buf.writeString(DATACALL_PROFILE_DEFAULT.toString());
     Buf.writeString(options.apn);
     Buf.writeString(options.user);
     Buf.writeString(options.passwd);
     Buf.writeString(options.chappap.toString());
@@ -1909,52 +1961,54 @@ RilObject.prototype = {
    *        One of DATACALL_DEACTIVATE_* constants.
    */
   deactivateDataCall: function(options) {
     let datacall = this.currentDataCalls[options.cid];
     if (!datacall) {
       return;
     }
 
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_DEACTIVATE_DATA_CALL, options);
     Buf.writeInt32(2);
     Buf.writeString(options.cid);
     Buf.writeString(options.reason || DATACALL_DEACTIVATE_NO_REASON);
     Buf.sendParcel();
 
     datacall.state = GECKO_NETWORK_STATE_DISCONNECTING;
     this.sendChromeMessage(datacall);
   },
 
   /**
    * Get a list of data calls.
    */
   getDataCallList: function() {
-    Buf.simpleRequest(REQUEST_DATA_CALL_LIST);
+    this.context.Buf.simpleRequest(REQUEST_DATA_CALL_LIST);
   },
 
   _attachDataRegistration: false,
   /**
    * Manually attach/detach data registration.
    *
    * @param attach
    *        Boolean value indicating attach or detach.
    */
   setDataRegistration: function(options) {
     let request = options.attach ? RIL_REQUEST_GPRS_ATTACH :
                                    RIL_REQUEST_GPRS_DETACH;
     this._attachDataRegistration = options.attach;
-    Buf.simpleRequest(request);
+    this.context.Buf.simpleRequest(request);
   },
 
   /**
    * Get failure casue code for the most recently failed PDP context.
    */
   getFailCauseCode: function(callback) {
-    Buf.simpleRequest(REQUEST_LAST_CALL_FAIL_CAUSE, {callback: callback});
+    this.context.Buf.simpleRequest(REQUEST_LAST_CALL_FAIL_CAUSE,
+                                   {callback: callback});
   },
 
   /**
    * Helper to parse MMI/USSD string. TS.22.030 Figure 3.5.3.2.
    */
   _parseMMI: function(mmiString) {
     if (!mmiString || !mmiString.length) {
       return null;
@@ -2378,40 +2432,42 @@ RilObject.prototype = {
   /**
    * Send USSD.
    *
    * @param ussd
    *        String containing the USSD code.
    *
    */
    sendUSSD: function(options) {
+     let Buf = this.context.Buf;
      Buf.newParcel(REQUEST_SEND_USSD, options);
      Buf.writeString(options.ussd);
      Buf.sendParcel();
    },
 
   /**
    * Cancel pending USSD.
    */
    cancelUSSD: function(options) {
      options.mmiServiceCode = MMI_KS_SC_USSD;
-     Buf.simpleRequest(REQUEST_CANCEL_USSD, options);
+     this.context.Buf.simpleRequest(REQUEST_CANCEL_USSD, options);
    },
 
   /**
    * Queries current call forward rules.
    *
    * @param reason
    *        One of nsIDOMMozMobileCFInfo.CALL_FORWARD_REASON_* constants.
    * @param serviceClass
    *        One of ICC_SERVICE_CLASS_* constants.
    * @param number
    *        Phone number of forwarding address.
    */
   queryCallForwardStatus: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_QUERY_CALL_FORWARD_STATUS, options);
     Buf.writeInt32(CALL_FORWARD_ACTION_QUERY_STATUS);
     Buf.writeInt32(options.reason);
     Buf.writeInt32(options.serviceClass || ICC_SERVICE_CLASS_NONE);
     Buf.writeInt32(this._toaFromString(options.number));
     Buf.writeString(options.number);
     Buf.writeInt32(0);
     Buf.sendParcel();
@@ -2427,16 +2483,17 @@ RilObject.prototype = {
    * @param serviceClass
    *        One of ICC_SERVICE_CLASS_* constants.
    * @param number
    *        Phone number of forwarding address.
    * @param timeSeconds
    *        Time in seconds to wait beforec all is forwarded.
    */
   setCallForward: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_SET_CALL_FORWARD, options);
     Buf.writeInt32(options.action);
     Buf.writeInt32(options.reason);
     Buf.writeInt32(options.serviceClass);
     Buf.writeInt32(this._toaFromString(options.number));
     Buf.writeString(options.number);
     Buf.writeInt32(options.timeSeconds);
     Buf.sendParcel();
@@ -2477,16 +2534,17 @@ RilObject.prototype = {
    * Change call barring facility password.
    *
    * @param pin
    *        Old password.
    * @param newPin
    *        New password.
    */
   changeCallBarringPassword: function(options) {
+    let Buf = this.context.Buf;
     Buf.newParcel(REQUEST_CHANGE_BARRING_PASSWORD, options);
     Buf.writeInt32(3);
     // Set facility to ICC_CB_FACILITY_BA_ALL by following TS.22.030 clause
     // 6.5.4 and Table B.1.
     Buf.writeString(ICC_CB_FACILITY_BA_ALL);
     Buf.writeString(options.pin);
     Buf.writeString(options.newPin);
     Buf.sendParcel();
@@ -2494,28 +2552,32 @@ RilObject.prototype = {
 
   /**
    * Handle STK CALL_SET_UP request.
    *
    * @param hasConfirmed
    *        Does use have confirmed the call requested from ICC?
    */
   stkHandleCallSetup: function(options) {
+     let Buf = this.context.Buf;
      Buf.newParcel(REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM);
      Buf.writeInt32(1);
      Buf.writeInt32(options.hasConfirmed ? 1 : 0);
      Buf.sendParcel();
   },
 
   /**
    * Send STK Profile Download.
    *
    * @param profile Profile supported by ME.
    */
   sendStkTerminalProfile: function(profile) {
+    let Buf = this.context.Buf;
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     Buf.newParcel(REQUEST_STK_SET_PROFILE);
     Buf.writeInt32(profile.length * 2);
     for (let i = 0; i < profile.length; i++) {
       GsmPDUHelper.writeHexOctet(profile[i]);
     }
     Buf.writeInt32(0);
     Buf.sendParcel();
   },
@@ -2534,16 +2596,20 @@ RilObject.prototype = {
    * @param [optional] timer
    */
   sendStkTerminalResponse: function(response) {
     if (response.hasConfirmed !== undefined) {
       this.stkHandleCallSetup(response);
       return;
     }
 
+    let Buf = this.context.Buf;
+    let ComprehensionTlvHelper = this.context.ComprehensionTlvHelper;
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     let command = response.command;
     Buf.newParcel(REQUEST_STK_SEND_TERMINAL_RESPONSE);
 
     // 1st mark for Parcel size
     Buf.startCalOutgoingSize(function(size) {
       // Parcel size is in string length, which costs 2 uint8 per char.
       Buf.writeInt32(size / 2);
     });
@@ -2810,16 +2876,21 @@ RilObject.prototype = {
    * @param [optional] timerId
    * @param [optional] timerValue
    * @param [optional] terminationCause
    */
   sendICCEnvelopeCommand: function(options) {
     if (DEBUG) {
       debug("Stk Envelope " + JSON.stringify(options));
     }
+
+    let Buf = this.context.Buf;
+    let ComprehensionTlvHelper = this.context.ComprehensionTlvHelper;
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     Buf.newParcel(REQUEST_STK_SEND_ENVELOPE_COMMAND);
 
     // 1st mark for Parcel size
     Buf.startCalOutgoingSize(function(size) {
       // Parcel size is in string length, which costs 2 uint8 per char.
       Buf.writeInt32(size / 2);
     });
 
@@ -2886,17 +2957,17 @@ RilObject.prototype = {
 
     // Address
     if (options.address) {
       GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_ADDRESS |
                                  COMPREHENSIONTLV_FLAG_CR);
       ComprehensionTlvHelper.writeLength(
         Math.ceil(options.address.length/2) + 1 // address BCD + TON
       );
-      ICCPDUHelper.writeDiallingNumber(options.address);
+      this.context.ICCPDUHelper.writeDiallingNumber(options.address);
     }
 
     // Cause of disconnection.
     if (options.cause != null) {
       ComprehensionTlvHelper.writeCauseTlv(options.cause);
     }
 
     // Timer Identifier
@@ -2968,17 +3039,17 @@ RilObject.prototype = {
              (mmi.procedure == MMI_PROCEDURE_ACTIVATION ||
               mmi.procedure == MMI_PROCEDURE_DEACTIVATION));
    },
 
   /**
    * Report STK Service is running.
    */
   reportStkServiceIsRunning: function() {
-    Buf.simpleRequest(REQUEST_REPORT_STK_SERVICE_IS_RUNNING);
+    this.context.Buf.simpleRequest(REQUEST_REPORT_STK_SERVICE_IS_RUNNING);
   },
 
   /**
    * Process ICC status.
    */
   _processICCStatus: function(iccStatus) {
     this.iccStatus = iccStatus;
     let newCardState;
@@ -2993,21 +3064,22 @@ RilObject.prototype = {
         this.operator = null;
         // We should send |cardstatechange| before |iccinfochange|, otherwise we
         // may lost cardstatechange event when icc card becomes undetected.
         this.cardState = GECKO_CARDSTATE_UNDETECTED;
         this.sendChromeMessage({rilMessageType: "cardstatechange",
                                 cardState: this.cardState});
 
         this.iccInfo = {iccType: null};
-        ICCUtilsHelper.handleICCInfoChange();
+        this.context.ICCUtilsHelper.handleICCInfoChange();
       }
       return;
     }
 
+    let ICCRecordHelper = this.context.ICCRecordHelper;
     // fetchICCRecords will need to read aid, so read aid here.
     this.aid = app.aid;
     this.appType = app.app_type;
     this.iccInfo.iccType = GECKO_CARD_TYPE[this.appType];
     // Try to get iccId only when cardState left GECKO_CARDSTATE_UNDETECTED.
     if (iccStatus.cardState === CARD_STATE_PRESENT &&
         (this.cardState === GECKO_CARDSTATE_UNINITIALIZED ||
          this.cardState === GECKO_CARDSTATE_UNDETECTED)) {
@@ -3048,17 +3120,17 @@ RilObject.prototype = {
     }
 
     // This was moved down from CARD_APPSTATE_READY
     this.requestNetworkInfo();
     if (newCardState == GECKO_CARDSTATE_READY) {
       // For type SIM, we need to check EF_phase first.
       // Other types of ICC we can send Terminal_Profile immediately.
       if (this.appType == CARD_APPTYPE_SIM) {
-        SimRecordHelper.readSimPhase();
+        this.context.SimRecordHelper.readSimPhase();
       } else if (RILQUIRKS_SEND_STK_PROFILE_DOWNLOAD) {
         this.sendStkTerminalProfile(STK_SUPPORTED_TERMINAL_PROFILE);
       }
 
       ICCRecordHelper.fetchICCRecords();
     }
 
     this.cardState = newCardState;
@@ -3069,17 +3141,17 @@ RilObject.prototype = {
    /**
    * Helper for processing responses of functions such as enterICC* and changeICC*.
    */
   _processEnterAndChangeICCResponses: function(length, options) {
     options.success = (options.rilRequestError === 0);
     if (!options.success) {
       options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
     }
-    options.retryCount = length ? Buf.readInt32List()[0] : -1;
+    options.retryCount = length ? this.context.Buf.readInt32List()[0] : -1;
     if (options.rilMessageType != "sendMMI") {
       this.sendChromeMessage(options);
       return;
     }
 
     let mmiServiceCode = options.mmiServiceCode;
 
     if (options.success) {
@@ -3437,16 +3509,17 @@ RilObject.prototype = {
         // According to ril.h, the operator fields will be NULL when the operator
         // is not currently registered. We can avoid trying to parse the numeric
         // tuple in that case.
         if (DEBUG) {
           debug("Operator is currently unregistered");
         }
       }
 
+      let ICCUtilsHelper = this.context.ICCUtilsHelper;
       let networkName;
       // We won't get network name using PNN and OPL if voice registration isn't ready
       if (this.voiceRegistrationState.cell &&
           this.voiceRegistrationState.cell.gsmLocationAreaCode != -1) {
         networkName = ICCUtilsHelper.getNetworkNameFromICC(
           this.operator.mcc,
           this.operator.mnc,
           this.voiceRegistrationState.cell.gsmLocationAreaCode);
@@ -3905,17 +3978,17 @@ RilObject.prototype = {
 
     let message = {rilMessageType: "emergencyCbModeChange",
                    active: active,
                    timeoutMs: EMERGENCY_CB_MODE_TIMEOUT_MS};
     this.sendChromeMessage(message);
   },
 
   _processNetworks: function() {
-    let strings = Buf.readStringList();
+    let strings = this.context.Buf.readStringList();
     let networks = [];
 
     for (let i = 0; i < strings.length; i += 4) {
       let network = {
         longName: strings[i],
         shortName: strings[i + 1],
         mcc: null,
         mnc: null,
@@ -4053,16 +4126,19 @@ RilObject.prototype = {
   },
 
   /**
    * @param message A decoded SMS-DELIVER message.
    *
    * @see 3GPP TS 31.111 section 7.1.1
    */
   dataDownloadViaSMSPP: function(message) {
+    let Buf = this.context.Buf;
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     let options = {
       pid: message.pid,
       dcs: message.dcs,
       encoding: message.encoding,
     };
     Buf.newParcel(REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, options);
 
     Buf.seekIncoming(-1 * (Buf.getCurrentParcelSize() - Buf.getReadAvailable()
@@ -4122,16 +4198,19 @@ RilObject.prototype = {
    *                SMS-DELIVER message handling.
    * @param responsePduLen ICC IO response PDU length in octets.
    * @param options An object that contains four attributes: `pid`, `dcs`,
    *                `encoding` and `responsePduLen`.
    *
    * @see 3GPP TS 23.040 section 9.2.2.1a
    */
   acknowledgeIncomingGsmSmsWithPDU: function(success, responsePduLen, options) {
+    let Buf = this.context.Buf;
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     Buf.newParcel(REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU);
 
     // Two strings.
     Buf.writeInt32(2);
 
     // String 1: Success
     Buf.writeString(success ? "1" : "0");
 
@@ -4164,16 +4243,19 @@ RilObject.prototype = {
 
     Buf.sendParcel();
   },
 
   /**
    * @param message A decoded SMS-DELIVER message.
    */
   writeSmsToSIM: function(message) {
+    let Buf = this.context.Buf;
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     Buf.newParcel(REQUEST_WRITE_SMS_TO_SIM);
 
     // Write EFsms Status
     Buf.writeInt32(EFSMS_STATUS_FREE);
 
     Buf.seekIncoming(-1 * (Buf.getCurrentParcelSize() - Buf.getReadAvailable()
                            - 2 * Buf.UINT32_SIZE)); // Skip response_type & request_type.
     let messageStringLength = Buf.readInt32(); // In semi-octets
@@ -4244,18 +4326,19 @@ RilObject.prototype = {
         message.rilMessageType = "broadcastsms-received";
       } else {
         message.rilMessageType = "sms-received";
       }
 
       this.sendChromeMessage(message);
 
       // Update MWI Status into ICC if present.
-      if (message.mwi && ICCUtilsHelper.isICCServiceAvailable("MWIS")) {
-        SimRecordHelper.updateMWIS(message.mwi);
+      if (message.mwi &&
+          this.context.ICCUtilsHelper.isICCServiceAvailable("MWIS")) {
+        this.context.SimRecordHelper.updateMWIS(message.mwi);
       }
 
       // We will acknowledge receipt of the SMS after we try to store it
       // in the database.
       return MOZ_FCS_WAIT_FOR_EXPLICIT_ACK;
     }
 
     return PDU_FCS_OK;
@@ -4265,17 +4348,17 @@ RilObject.prototype = {
    * Helper for processing SMS-STATUS-REPORT PDUs.
    *
    * @param length
    *        Length of SMS string in the incoming parcel.
    *
    * @return A failure cause defined in 3GPP 23.040 clause 9.2.3.22.
    */
   _processSmsStatusReport: function(length) {
-    let [message, result] = GsmPDUHelper.processReceivedSms(length);
+    let [message, result] = this.context.GsmPDUHelper.processReceivedSms(length);
     if (!message) {
       if (DEBUG) debug("invalid SMS-STATUS-REPORT");
       return PDU_FCS_UNSPECIFIED;
     }
 
     let options = this._pendingSentSmsMap[message.messageRef];
     if (!options) {
       if (DEBUG) debug("no pending SMS-SUBMIT message");
@@ -4543,16 +4626,17 @@ RilObject.prototype = {
             rilMessageToken: options.rilMessageToken,
             errorMsg: options.rilRequestError,
           });
           break;
       }
       return;
     }
 
+    let Buf = this.context.Buf;
     options.messageRef = Buf.readInt32();
     options.ackPDU = Buf.readString();
     options.errorCode = Buf.readInt32();
 
     if ((options.segmentMaxSeq > 1)
         && (options.segmentSeq < options.segmentMaxSeq)) {
       // Not last segment
       this._processSentSmsSegment(options);
@@ -4914,31 +4998,32 @@ RilObject.prototype = {
     this.sendChromeMessage({rilMessageType: "datacalllist",
                             datacalls: datacall_list});
   },
 
   /**
    * Process STK Proactive Command.
    */
   processStkProactiveCommand: function() {
+    let Buf = this.context.Buf;
     let length = Buf.readInt32();
     let berTlv;
     try {
-      berTlv = BerTlvHelper.decode(length / 2);
+      berTlv = this.context.BerTlvHelper.decode(length / 2);
     } catch (e) {
       if (DEBUG) debug("processStkProactiveCommand : " + e);
       this.sendStkTerminalResponse({
         resultCode: STK_RESULT_CMD_DATA_NOT_UNDERSTOOD});
       return;
     }
 
     Buf.readStringDelimiter(length);
 
     let ctlvs = berTlv.value;
-    let ctlv = StkProactiveCmdHelper.searchForTag(
+    let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
         COMPREHENSIONTLV_TAG_COMMAND_DETAILS, ctlvs);
     if (!ctlv) {
       this.sendStkTerminalResponse({
         resultCode: STK_RESULT_CMD_DATA_NOT_UNDERSTOOD});
       throw new Error("Can't find COMMAND_DETAILS ComprehensionTlv");
     }
 
     let cmdDetails = ctlv.value;
@@ -4952,17 +5037,18 @@ RilObject.prototype = {
     if (cmdDetails.typeOfCommand == STK_CMD_MORE_TIME) {
       this.sendStkTerminalResponse({
         command: cmdDetails,
         resultCode: STK_RESULT_OK});
       return;
     }
 
     cmdDetails.rilMessageType = "stkcommand";
-    cmdDetails.options = StkCommandParamsFactory.createParam(cmdDetails, ctlvs);
+    cmdDetails.options =
+      this.context.StkCommandParamsFactory.createParam(cmdDetails, ctlvs);
     this.sendChromeMessage(cmdDetails);
   },
 
   /**
    * Send messages to the main thread.
    */
   sendChromeMessage: function(message) {
     message.rilMessageClientId = CLIENT_ID;
@@ -5013,16 +5099,17 @@ RilObject.prototype = {
 };
 
 RilObject.prototype[REQUEST_GET_SIM_STATUS] = function REQUEST_GET_SIM_STATUS(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
   let iccStatus = {};
+  let Buf = this.context.Buf;
   iccStatus.cardState = Buf.readInt32(); // CARD_STATE_*
   iccStatus.universalPINState = Buf.readInt32(); // CARD_PINSTATE_*
   iccStatus.gsmUmtsSubscriptionAppIndex = Buf.readInt32();
   iccStatus.cdmaSubscriptionAppIndex = Buf.readInt32();
   if (!this.v5Legacy) {
     iccStatus.imsSubscriptionAppIndex = Buf.readInt32();
   }
 
@@ -5076,16 +5163,17 @@ RilObject.prototype[REQUEST_ENTER_NETWOR
   function REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE(length, options) {
   this._processEnterAndChangeICCResponses(length, options);
 };
 RilObject.prototype[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
+  let Buf = this.context.Buf;
   let calls_length = 0;
   // The RIL won't even send us the length integer if there are no active calls.
   // So only read this integer if the parcel actually has it.
   if (length) {
     calls_length = Buf.readInt32();
   }
   if (!calls_length) {
     this._processCalls(null);
@@ -5143,17 +5231,17 @@ RilObject.prototype[REQUEST_DIAL] = func
     }).bind(this, options));
   }
 };
 RilObject.prototype[REQUEST_GET_IMSI] = function REQUEST_GET_IMSI(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
-  this.iccInfoPrivate.imsi = Buf.readString();
+  this.iccInfoPrivate.imsi = this.context.Buf.readString();
   if (DEBUG) {
     debug("IMSI: " + this.iccInfoPrivate.imsi);
   }
 
   options.rilMessageType = "iccimsi";
   options.imsi = this.iccInfoPrivate.imsi;
   this.sendChromeMessage(options);
 };
@@ -5202,29 +5290,31 @@ RilObject.prototype[REQUEST_CONFERENCE] 
                errorName: "addError",
                errorMsg: RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError]};
     this.sendChromeMessage(options);
     return;
   }
 };
 RilObject.prototype[REQUEST_UDUB] = null;
 RilObject.prototype[REQUEST_LAST_CALL_FAIL_CAUSE] = function REQUEST_LAST_CALL_FAIL_CAUSE(length, options) {
+  let Buf = this.context.Buf;
   let num = length ? Buf.readInt32() : 0;
   let failCause = num ? RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[Buf.readInt32()] : null;
   if (options.callback) {
     options.callback(failCause);
   }
 };
 RilObject.prototype[REQUEST_SIGNAL_STRENGTH] = function REQUEST_SIGNAL_STRENGTH(length, options) {
   this._receivedNetworkInfo(NETWORK_INFO_SIGNAL);
 
   if (options.rilRequestError) {
     return;
   }
 
+  let Buf = this.context.Buf;
   let signal = {
     gsmSignalStrength: Buf.readInt32(),
     gsmBitErrorRate:   Buf.readInt32(),
     cdmaDBM:           Buf.readInt32(),
     cdmaECIO:          Buf.readInt32(),
     evdoDBM:           Buf.readInt32(),
     evdoECIO:          Buf.readInt32(),
     evdoSNR:           Buf.readInt32()
@@ -5244,17 +5334,17 @@ RilObject.prototype[REQUEST_SIGNAL_STREN
 };
 RilObject.prototype[REQUEST_VOICE_REGISTRATION_STATE] = function REQUEST_VOICE_REGISTRATION_STATE(length, options) {
   this._receivedNetworkInfo(NETWORK_INFO_VOICE_REGISTRATION_STATE);
 
   if (options.rilRequestError) {
     return;
   }
 
-  let state = Buf.readStringList();
+  let state = this.context.Buf.readStringList();
   if (DEBUG) debug("voice registration state: " + state);
 
   this._processVoiceRegistrationState(state);
 
   if (this.cachedDialRequest &&
        (this.voiceRegistrationState.emergencyCallsOnly ||
         this.voiceRegistrationState.connected) &&
       this.voiceRegistrationState.radioTech != NETWORK_CREG_TECH_UNKNOWN) {
@@ -5265,27 +5355,27 @@ RilObject.prototype[REQUEST_VOICE_REGIST
 };
 RilObject.prototype[REQUEST_DATA_REGISTRATION_STATE] = function REQUEST_DATA_REGISTRATION_STATE(length, options) {
   this._receivedNetworkInfo(NETWORK_INFO_DATA_REGISTRATION_STATE);
 
   if (options.rilRequestError) {
     return;
   }
 
-  let state = Buf.readStringList();
+  let state = this.context.Buf.readStringList();
   this._processDataRegistrationState(state);
 };
 RilObject.prototype[REQUEST_OPERATOR] = function REQUEST_OPERATOR(length, options) {
   this._receivedNetworkInfo(NETWORK_INFO_OPERATOR);
 
   if (options.rilRequestError) {
     return;
   }
 
-  let operatorData = Buf.readStringList();
+  let operatorData = this.context.Buf.readStringList();
   if (DEBUG) debug("Operator: " + operatorData);
   this._processOperator(operatorData);
 };
 RilObject.prototype[REQUEST_RADIO_POWER] = function REQUEST_RADIO_POWER(length, options) {
   if (options.rilMessageType == null) {
     // The request was made by ril_worker itself.
     if (options.rilRequestError) {
       if (this.cachedDialRequest && options.enabled) {
@@ -5305,17 +5395,17 @@ RilObject.prototype[REQUEST_SEND_SMS] = 
   this._processSmsSendResult(length, options);
 };
 RilObject.prototype[REQUEST_SEND_SMS_EXPECT_MORE] = null;
 
 RilObject.prototype.readSetupDataCall_v5 = function readSetupDataCall_v5(options) {
   if (!options) {
     options = {};
   }
-  let [cid, ifname, ipaddr, dns, gw] = Buf.readStringList();
+  let [cid, ifname, ipaddr, dns, gw] = this.context.Buf.readStringList();
   options.cid = cid;
   options.ifname = ifname;
   options.ipaddr = ipaddr;
   options.dns = dns;
   options.gw = gw;
   options.active = DATACALL_ACTIVE_UNKNOWN;
   options.state = GECKO_NETWORK_STATE_CONNECTING;
   return options;
@@ -5340,23 +5430,25 @@ RilObject.prototype[REQUEST_SETUP_DATA_C
     this.getDataCallList();
     return;
   }
   // Pass `options` along. That way we retain the APN and other info about
   // how the data call was set up.
   this[REQUEST_DATA_CALL_LIST](length, options);
 };
 RilObject.prototype[REQUEST_SIM_IO] = function REQUEST_SIM_IO(length, options) {
+  let ICCIOHelper = this.context.ICCIOHelper;
   if (!length) {
     ICCIOHelper.processICCIOError(options);
     return;
   }
 
   // Don't need to read rilRequestError since we can know error status from
   // sw1 and sw2.
+  let Buf = this.context.Buf;
   options.sw1 = Buf.readInt32();
   options.sw2 = Buf.readInt32();
   if (options.sw1 != ICC_STATUS_NORMAL_ENDING) {
     ICCIOHelper.processICCIOError(options);
     return;
   }
   ICCIOHelper.processICCIO(options);
 };
@@ -5380,16 +5472,17 @@ RilObject.prototype[REQUEST_CANCEL_USSD]
 RilObject.prototype[REQUEST_GET_CLIR] = function REQUEST_GET_CLIR(length, options) {
   options.success = (options.rilRequestError === 0);
   if (!options.success) {
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
     this.sendChromeMessage(options);
     return;
   }
 
+  let Buf = this.context.Buf;
   let bufLength = Buf.readInt32();
   if (!bufLength || bufLength < 2) {
     options.success = false;
     options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
     this.sendChromeMessage(options);
     return;
   }
 
@@ -5486,16 +5579,17 @@ RilObject.prototype[REQUEST_QUERY_CALL_F
   function REQUEST_QUERY_CALL_FORWARD_STATUS(length, options) {
   options.success = (options.rilRequestError === 0);
   if (!options.success) {
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
     this.sendChromeMessage(options);
     return;
   }
 
+  let Buf = this.context.Buf;
   let rulesLength = 0;
   if (length) {
     rulesLength = Buf.readInt32();
   }
   if (!rulesLength) {
     options.success = false;
     options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
     this.sendChromeMessage(options);
@@ -5554,16 +5648,17 @@ RilObject.prototype[REQUEST_QUERY_CALL_W
     return;
   }
 
   if (options.callback) {
     options.callback.call(this, options);
     return;
   }
 
+  let Buf = this.context.Buf;
   options.length = Buf.readInt32();
   options.enabled = ((Buf.readInt32() == 1) &&
                      ((Buf.readInt32() & ICC_SERVICE_CLASS_VOICE) == 0x01));
   this.sendChromeMessage(options);
 };
 
 RilObject.prototype[REQUEST_SET_CALL_WAITING] = function REQUEST_SET_CALL_WAITING(length, options) {
   options.success = (options.rilRequestError === 0);
@@ -5577,17 +5672,17 @@ RilObject.prototype[REQUEST_SET_CALL_WAI
     options.callback.call(this, options);
     return;
   }
 
   this.sendChromeMessage(options);
 };
 RilObject.prototype[REQUEST_SMS_ACKNOWLEDGE] = null;
 RilObject.prototype[REQUEST_GET_IMEI] = function REQUEST_GET_IMEI(length, options) {
-  this.IMEI = Buf.readString();
+  this.IMEI = this.context.Buf.readString();
   let rilMessageType = options.rilMessageType;
   // So far we only send the IMEI back to chrome if it was requested via MMI.
   if (rilMessageType !== "sendMMI") {
     return;
   }
 
   options.success = (options.rilRequestError === 0);
   options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
@@ -5597,17 +5692,17 @@ RilObject.prototype[REQUEST_GET_IMEI] = 
   options.statusMessage = this.IMEI;
   this.sendChromeMessage(options);
 };
 RilObject.prototype[REQUEST_GET_IMEISV] = function REQUEST_GET_IMEISV(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
-  this.IMEISV = Buf.readString();
+  this.IMEISV = this.context.Buf.readString();
 };
 RilObject.prototype[REQUEST_ANSWER] = null;
 RilObject.prototype[REQUEST_DEACTIVATE_DATA_CALL] = function REQUEST_DEACTIVATE_DATA_CALL(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
   let datacall = this.currentDataCalls[options.cid];
@@ -5620,17 +5715,17 @@ RilObject.prototype[REQUEST_QUERY_FACILI
   options.success = (options.rilRequestError === 0);
   if (!options.success) {
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
   }
 
   let services;
   if (length) {
     // Buf.readInt32List()[0] for Call Barring is a bit vector of services.
-    services = Buf.readInt32List()[0];
+    services = this.context.Buf.readInt32List()[0];
   } else {
     options.success = false;
     options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
     this.sendChromeMessage(options);
     return;
   }
 
   options.enabled = services === 0 ? false : true;
@@ -5655,17 +5750,17 @@ RilObject.prototype[REQUEST_QUERY_FACILI
   this.sendChromeMessage(options);
 };
 RilObject.prototype[REQUEST_SET_FACILITY_LOCK] = function REQUEST_SET_FACILITY_LOCK(length, options) {
   options.success = (options.rilRequestError === 0);
   if (!options.success) {
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
   }
 
-  options.retryCount = length ? Buf.readInt32List()[0] : -1;
+  options.retryCount = length ? this.context.Buf.readInt32List()[0] : -1;
 
   if (options.success && (options.rilMessageType === "sendMMI")) {
     switch (options.procedure) {
       case MMI_PROCEDURE_ACTIVATION:
         options.statusMessage = MMI_SM_KS_SERVICE_ENABLED;
         break;
       case MMI_PROCEDURE_DEACTIVATION:
         options.statusMessage = MMI_SM_KS_SERVICE_DISABLED;
@@ -5683,17 +5778,17 @@ RilObject.prototype[REQUEST_CHANGE_BARRI
 };
 RilObject.prototype[REQUEST_SIM_OPEN_CHANNEL] = function REQUEST_SIM_OPEN_CHANNEL(length, options) {
   if (options.rilRequestError) {
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
     this.sendChromeMessage(options);
     return;
   }
 
-  options.channel = Buf.readInt32();
+  options.channel = this.context.Buf.readInt32();
   if (DEBUG) debug("Setting channel number in options: " + options.channel);
   this.sendChromeMessage(options);
 };
 RilObject.prototype[REQUEST_SIM_CLOSE_CHANNEL] = function REQUEST_SIM_CLOSE_CHANNEL(length, options) {
   if (options.rilRequestError) {
     options.error = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
     this.sendChromeMessage(options);
     return;
@@ -5703,33 +5798,34 @@ RilObject.prototype[REQUEST_SIM_CLOSE_CH
   this.sendChromeMessage(options);
 };
 RilObject.prototype[REQUEST_SIM_ACCESS_CHANNEL] = function REQUEST_SIM_ACCESS_CHANNEL(length, options) {
   if (options.rilRequestError) {
     options.error = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
     this.sendChromeMessage(options);
   }
 
+  let Buf = this.context.Buf;
   options.sw1 = Buf.readInt32();
   options.sw2 = Buf.readInt32();
   options.simResponse = Buf.readString();
   if (DEBUG) {
     debug("Setting return values for RIL[REQUEST_SIM_ACCESS_CHANNEL]: ["
           + options.sw1 + "," + options.sw2 + ", " + options.simResponse + "]");
   }
   this.sendChromeMessage(options);
 };
 RilObject.prototype[REQUEST_QUERY_NETWORK_SELECTION_MODE] = function REQUEST_QUERY_NETWORK_SELECTION_MODE(length, options) {
   this._receivedNetworkInfo(NETWORK_INFO_NETWORK_SELECTION_MODE);
 
   if (options.rilRequestError) {
     return;
   }
 
-  let mode = Buf.readInt32List();
+  let mode = this.context.Buf.readInt32List();
   let selectionMode;
 
   switch (mode[0]) {
     case NETWORK_SELECTION_MODE_AUTOMATIC:
       selectionMode = GECKO_NETWORK_SELECTION_AUTOMATIC;
       break;
     case NETWORK_SELECTION_MODE_MANUAL:
       selectionMode = GECKO_NETWORK_SELECTION_MANUAL;
@@ -5769,17 +5865,17 @@ RilObject.prototype[REQUEST_QUERY_AVAILA
 };
 RilObject.prototype[REQUEST_DTMF_START] = null;
 RilObject.prototype[REQUEST_DTMF_STOP] = null;
 RilObject.prototype[REQUEST_BASEBAND_VERSION] = function REQUEST_BASEBAND_VERSION(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
-  this.basebandVersion = Buf.readString();
+  this.basebandVersion = this.context.Buf.readString();
   if (DEBUG) debug("Baseband version: " + this.basebandVersion);
 };
 RilObject.prototype[REQUEST_SEPARATE_CONNECTION] = function REQUEST_SEPARATE_CONNECTION(length, options) {
   if (options.rilRequestError) {
     options = {rilMessageType: "conferenceError",
                errorName: "removeError",
                errorMsg: RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError]};
     this.sendChromeMessage(options);
@@ -5791,16 +5887,17 @@ RilObject.prototype[REQUEST_GET_MUTE] = 
 RilObject.prototype[REQUEST_QUERY_CLIP] = function REQUEST_QUERY_CLIP(length, options) {
   options.success = (options.rilRequestError === 0);
   if (!options.success) {
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
     this.sendChromeMessage(options);
     return;
   }
 
+  let Buf = this.context.Buf;
   let bufLength = Buf.readInt32();
   if (!bufLength) {
     options.success = false;
     options.errorMsg = GECKO_ERROR_GENERIC_FAILURE;
     this.sendChromeMessage(options);
     return;
   }
 
@@ -5827,28 +5924,30 @@ RilObject.prototype[REQUEST_QUERY_CLIP] 
   this.sendChromeMessage(options);
 };
 RilObject.prototype[REQUEST_LAST_DATA_CALL_FAIL_CAUSE] = null;
 
 RilObject.prototype.readDataCall_v5 = function(options) {
   if (!options) {
     options = {};
   }
+  let Buf = this.context.Buf;
   options.cid = Buf.readInt32().toString();
   options.active = Buf.readInt32(); // DATACALL_ACTIVE_*
   options.type = Buf.readString();
   options.apn = Buf.readString();
   options.address = Buf.readString();
   return options;
 };
 
 RilObject.prototype.readDataCall_v6 = function(options) {
   if (!options) {
     options = {};
   }
+  let Buf = this.context.Buf;
   options.status = Buf.readInt32();  // DATACALL_FAIL_*
   options.suggestedRetryTime = Buf.readInt32();
   options.cid = Buf.readInt32().toString();
   options.active = Buf.readInt32();  // DATACALL_ACTIVE_*
   options.type = Buf.readString();
   options.ifname = Buf.readString();
   options.ipaddr = Buf.readString();
   options.dns = Buf.readString();
@@ -5871,16 +5970,17 @@ RilObject.prototype[REQUEST_DATA_CALL_LI
     return;
   }
 
   if (!length) {
     this._processDataCallList(null);
     return;
   }
 
+  let Buf = this.context.Buf;
   let version = 0;
   if (!this.v5Legacy) {
     version = Buf.readInt32();
   }
   let num = Buf.readInt32();
   let datacalls = {};
   for (let i = 0; i < num; i++) {
     let datacall;
@@ -5940,16 +6040,17 @@ RilObject.prototype[REQUEST_SET_PREFERRE
 RilObject.prototype[REQUEST_GET_PREFERRED_NETWORK_TYPE] = function REQUEST_GET_PREFERRED_NETWORK_TYPE(length, options) {
   if (options.rilRequestError) {
     options.success = false;
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
     this.sendChromeMessage(options);
     return;
   }
 
+  let Buf = this.context.Buf;
   let networkType = RIL_PREFERRED_NETWORK_TYPE_TO_GECKO.indexOf(GECKO_PREFERRED_NETWORK_TYPE_DEFAULT);
   let responseLen = Buf.readInt32(); // Number of INT32 responsed.
   if (responseLen) {
     this.preferredNetworkType = networkType = Buf.readInt32();
   }
   options.networkType = networkType;
   options.success = true;
 
@@ -5963,17 +6064,17 @@ RilObject.prototype[REQUEST_CDMA_SET_ROA
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
   }
   this.sendChromeMessage(options);
 };
 RilObject.prototype[REQUEST_CDMA_QUERY_ROAMING_PREFERENCE] = function REQUEST_CDMA_QUERY_ROAMING_PREFERENCE(length, options) {
   if (options.rilRequestError) {
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
   } else {
-    let mode = Buf.readInt32List();
+    let mode = this.context.Buf.readInt32List();
     options.mode = CDMA_ROAMING_PREFERENCE_TO_GECKO[mode[0]];
   }
   this.sendChromeMessage(options);
 };
 RilObject.prototype[REQUEST_SET_TTY_MODE] = null;
 RilObject.prototype[REQUEST_QUERY_TTY_MODE] = null;
 RilObject.prototype[REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE] = function REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE(length, options) {
   if (options.rilRequestError) {
@@ -5986,17 +6087,17 @@ RilObject.prototype[REQUEST_CDMA_SET_PRE
 };
 RilObject.prototype[REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE] = function REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE(length, options) {
   if (options.rilRequestError) {
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
     this.sendChromeMessage(options);
     return;
   }
 
-  let enabled = Buf.readInt32List();
+  let enabled = this.context.Buf.readInt32List();
   options.enabled = enabled[0] ? true : false;
   this.sendChromeMessage(options);
 };
 RilObject.prototype[REQUEST_CDMA_FLASH] = null;
 RilObject.prototype[REQUEST_CDMA_BURST_DTMF] = null;
 RilObject.prototype[REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY] = null;
 RilObject.prototype[REQUEST_CDMA_SEND_SMS] = function REQUEST_CDMA_SEND_SMS(length, options) {
   this._processSmsSendResult(length, options);
@@ -6012,34 +6113,34 @@ RilObject.prototype[REQUEST_GSM_SMS_BROA
 RilObject.prototype[REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG] = null;
 RilObject.prototype[REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG] = null;
 RilObject.prototype[REQUEST_CDMA_SMS_BROADCAST_ACTIVATION] = null;
 RilObject.prototype[REQUEST_CDMA_SUBSCRIPTION] = function REQUEST_CDMA_SUBSCRIPTION(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
-  let result = Buf.readStringList();
+  let result = this.context.Buf.readStringList();
 
   this.iccInfo.mdn = result[0];
   // The result[1] is Home SID. (Already be handled in readCDMAHome())
   // The result[2] is Home NID. (Already be handled in readCDMAHome())
   // The result[3] is MIN.
   // The result[4] is PRL version.
 
-  ICCUtilsHelper.handleICCInfoChange();
+  this.context.ICCUtilsHelper.handleICCInfoChange();
 };
 RilObject.prototype[REQUEST_CDMA_WRITE_SMS_TO_RUIM] = null;
 RilObject.prototype[REQUEST_CDMA_DELETE_SMS_ON_RUIM] = null;
 RilObject.prototype[REQUEST_DEVICE_IDENTITY] = function REQUEST_DEVICE_IDENTITY(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
-  let result = Buf.readStringList();
+  let result = this.context.Buf.readStringList();
 
   // The result[0] is for IMEI. (Already be handled in REQUEST_GET_IMEI)
   // The result[1] is for IMEISV. (Already be handled in REQUEST_GET_IMEISV)
   // They are both ignored.
   this.ESN = result[2];
   this.MEID = result[3];
 };
 RilObject.prototype[REQUEST_EXIT_EMERGENCY_CALLBACK_MODE] = function REQUEST_EXIT_EMERGENCY_CALLBACK_MODE(length, options) {
@@ -6049,17 +6150,17 @@ RilObject.prototype[REQUEST_EXIT_EMERGEN
 
   options.success = (options.rilRequestError === 0);
   if (!options.success) {
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
   }
   this.sendChromeMessage(options);
 };
 RilObject.prototype[REQUEST_GET_SMSC_ADDRESS] = function REQUEST_GET_SMSC_ADDRESS(length, options) {
-  this.SMSC = options.rilRequestError ? null : Buf.readString();
+  this.SMSC = options.rilRequestError ? null : this.context.Buf.readString();
 
   if (!options || options.rilMessageType !== "getSmscAddress") {
     return;
   }
 
   options.smscAddress = this.SMSC;
   options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
   this.sendChromeMessage(options);
@@ -6069,16 +6170,17 @@ RilObject.prototype[REQUEST_REPORT_SMS_M
 RilObject.prototype[REQUEST_REPORT_STK_SERVICE_IS_RUNNING] = null;
 RilObject.prototype[REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU] = null;
 RilObject.prototype[REQUEST_STK_SEND_ENVELOPE_WITH_STATUS] = function REQUEST_STK_SEND_ENVELOPE_WITH_STATUS(length, options) {
   if (options.rilRequestError) {
     this.acknowledgeGsmSms(false, PDU_FCS_UNSPECIFIED);
     return;
   }
 
+  let Buf = this.context.Buf;
   let sw1 = Buf.readInt32();
   let sw2 = Buf.readInt32();
   if ((sw1 == ICC_STATUS_SAT_BUSY) && (sw2 === 0x00)) {
     this.acknowledgeGsmSms(false, PDU_FCS_USAT_BUSY);
     return;
   }
 
   let success = ((sw1 == ICC_STATUS_NORMAL_ENDING) && (sw2 === 0x00))
@@ -6096,31 +6198,31 @@ RilObject.prototype[REQUEST_STK_SEND_ENV
 };
 RilObject.prototype[REQUEST_VOICE_RADIO_TECH] = function REQUEST_VOICE_RADIO_TECH(length, options) {
   if (options.rilRequestError) {
     if (DEBUG) {
       debug("Error when getting voice radio tech: " + options.rilRequestError);
     }
     return;
   }
-  let radioTech = Buf.readInt32List();
+  let radioTech = this.context.Buf.readInt32List();
   this._processRadioTech(radioTech[0]);
 };
 RilObject.prototype[REQUEST_GET_UNLOCK_RETRY_COUNT] = function REQUEST_GET_UNLOCK_RETRY_COUNT(length, options) {
   options.success = (options.rilRequestError === 0);
   if (!options.success) {
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
   }
-  options.retryCount = length ? Buf.readInt32List()[0] : -1;
+  options.retryCount = length ? this.context.Buf.readInt32List()[0] : -1;
   this.sendChromeMessage(options);
 };
 RilObject.prototype[RIL_REQUEST_GPRS_ATTACH] = null;
 RilObject.prototype[RIL_REQUEST_GPRS_DETACH] = null;
 RilObject.prototype[UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED] = function UNSOLICITED_RESPONSE_RADIO_STATE_CHANGED() {
-  let radioState = Buf.readInt32();
+  let radioState = this.context.Buf.readInt32();
   let newState;
   if (radioState == RADIO_STATE_UNAVAILABLE) {
     newState = GECKO_RADIOSTATE_UNAVAILABLE;
   } else if (radioState == RADIO_STATE_OFF) {
     newState = GECKO_RADIOSTATE_OFF;
   } else {
     newState = GECKO_RADIOSTATE_READY;
   }
@@ -6198,17 +6300,17 @@ RilObject.prototype[UNSOLICITED_RESPONSE
   this.getCurrentCalls();
 };
 RilObject.prototype[UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED] = function UNSOLICITED_RESPONSE_VOICE_NETWORK_STATE_CHANGED() {
   if (DEBUG) debug("Network state changed, re-requesting phone state and ICC status");
   this.getICCStatus();
   this.requestNetworkInfo();
 };
 RilObject.prototype[UNSOLICITED_RESPONSE_NEW_SMS] = function UNSOLICITED_RESPONSE_NEW_SMS(length) {
-  let [message, result] = GsmPDUHelper.processReceivedSms(length);
+  let [message, result] = this.context.GsmPDUHelper.processReceivedSms(length);
 
   if (message) {
     result = this._processSmsMultipart(message);
   }
 
   if (result == PDU_FCS_RESERVED || result == MOZ_FCS_WAIT_FOR_EXPLICIT_ACK) {
     return;
   }
@@ -6216,45 +6318,45 @@ RilObject.prototype[UNSOLICITED_RESPONSE
   // Not reserved FCS values, send ACK now.
   this.acknowledgeGsmSms(result == PDU_FCS_OK, result);
 };
 RilObject.prototype[UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT] = function UNSOLICITED_RESPONSE_NEW_SMS_STATUS_REPORT(length) {
   let result = this._processSmsStatusReport(length);
   this.acknowledgeGsmSms(result == PDU_FCS_OK, result);
 };
 RilObject.prototype[UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM] = function UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM(length) {
-  let recordNumber = Buf.readInt32List()[0];
-
-  SimRecordHelper.readSMS(
+  let recordNumber = this.context.Buf.readInt32List()[0];
+
+  this.context.SimRecordHelper.readSMS(
     recordNumber,
     function onsuccess(message) {
       if (message && message.simStatus === 3) { //New Unread SMS
         this._processSmsMultipart(message);
       }
     }.bind(this),
     function onerror(errorMsg) {
       if (DEBUG) {
         debug("Failed to Read NEW SMS on SIM #" + recordNumber + ", errorMsg: " + errorMsg);
       }
     });
 };
 RilObject.prototype[UNSOLICITED_ON_USSD] = function UNSOLICITED_ON_USSD() {
-  let [typeCode, message] = Buf.readStringList();
+  let [typeCode, message] = this.context.Buf.readStringList();
   if (DEBUG) {
     debug("On USSD. Type Code: " + typeCode + " Message: " + message);
   }
 
   this._ussdSession = (typeCode != "0" && typeCode != "2");
 
   this.sendChromeMessage({rilMessageType: "USSDReceived",
                           message: message,
                           sessionEnded: !this._ussdSession});
 };
 RilObject.prototype[UNSOLICITED_NITZ_TIME_RECEIVED] = function UNSOLICITED_NITZ_TIME_RECEIVED() {
-  let dateString = Buf.readString();
+  let dateString = this.context.Buf.readString();
 
   // The data contained in the NITZ message is
   // in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt"
   // for example: 12/02/16,03:36:08-20,00,310410
   // See also bug 714352 - Listen for NITZ updates from rild.
 
   if (DEBUG) debug("DateTimeZone string " + dateString);
 
@@ -6292,16 +6394,17 @@ RilObject.prototype[UNSOLICITED_SIGNAL_S
 RilObject.prototype[UNSOLICITED_DATA_CALL_LIST_CHANGED] = function UNSOLICITED_DATA_CALL_LIST_CHANGED(length) {
   if (this.v5Legacy) {
     this.getDataCallList();
     return;
   }
   this[REQUEST_DATA_CALL_LIST](length, {rilRequestError: ERROR_SUCCESS});
 };
 RilObject.prototype[UNSOLICITED_SUPP_SVC_NOTIFICATION] = function UNSOLICITED_SUPP_SVC_NOTIFICATION(length) {
+  let Buf = this.context.Buf;
   let info = {};
   info.notificationType = Buf.readInt32();
   info.code = Buf.readInt32();
   info.index = Buf.readInt32();
   info.type = Buf.readInt32();
   info.number = Buf.readString();
 
   this._processSuppSvcNotification(info);
@@ -6315,16 +6418,17 @@ RilObject.prototype[UNSOLICITED_STK_PROA
 };
 RilObject.prototype[UNSOLICITED_STK_EVENT_NOTIFY] = function UNSOLICITED_STK_EVENT_NOTIFY() {
   this.processStkProactiveCommand();
 };
 RilObject.prototype[UNSOLICITED_STK_CALL_SETUP] = null;
 RilObject.prototype[UNSOLICITED_SIM_SMS_STORAGE_FULL] = null;
 RilObject.prototype[UNSOLICITED_SIM_REFRESH] = null;
 RilObject.prototype[UNSOLICITED_CALL_RING] = function UNSOLICITED_CALL_RING() {
+  let Buf = this.context.Buf;
   let info = {rilMessageType: "callRing"};
   let isCDMA = false; //XXX TODO hard-code this for now
   if (isCDMA) {
     info.isPresent = Buf.readInt32();
     info.signalType = Buf.readInt32();
     info.alertPitch = Buf.readInt32();
     info.signal = Buf.readInt32();
   }
@@ -6333,17 +6437,17 @@ RilObject.prototype[UNSOLICITED_CALL_RIN
   // details once we get a call state changed notification and can then
   // dispatch DOM events etc.
   this.sendChromeMessage(info);
 };
 RilObject.prototype[UNSOLICITED_RESPONSE_SIM_STATUS_CHANGED] = function UNSOLICITED_RESPONSE_SIM_STATUS_CHANGED() {
   this.getICCStatus();
 };
 RilObject.prototype[UNSOLICITED_RESPONSE_CDMA_NEW_SMS] = function UNSOLICITED_RESPONSE_CDMA_NEW_SMS(length) {
-  let [message, result] = CdmaPDUHelper.processReceivedSms(length);
+  let [message, result] = this.context.CdmaPDUHelper.processReceivedSms(length);
 
   if (message) {
     if (message.teleservice === PDU_CDMA_MSG_TELESERIVCIE_ID_WAP) {
       result = this._processCdmaSmsWapPush(message);
     } else if (message.subMsgType === PDU_CDMA_MSG_TYPE_DELIVER_ACK) {
       result = this._processCdmaSmsStatusReport(message);
     } else {
       result = this._processSmsMultipart(message);
@@ -6355,17 +6459,18 @@ RilObject.prototype[UNSOLICITED_RESPONSE
   }
 
   // Not reserved FCS values, send ACK now.
   this.acknowledgeCdmaSms(result == PDU_FCS_OK, result);
 };
 RilObject.prototype[UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS] = function UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS(length) {
   let message;
   try {
-    message = GsmPDUHelper.readCbMessage(Buf.readInt32());
+    message =
+      this.context.GsmPDUHelper.readCbMessage(this.context.Buf.readInt32());
   } catch (e) {
     if (DEBUG) {
       debug("Failed to parse Cell Broadcast message: " + JSON.stringify(e));
     }
     return;
   }
 
   message = this._processReceivedSmsCbPage(message);
@@ -6377,52 +6482,53 @@ RilObject.prototype[UNSOLICITED_RESPONSE
   this.sendChromeMessage(message);
 };
 RilObject.prototype[UNSOLICITED_CDMA_RUIM_SMS_STORAGE_FULL] = null;
 RilObject.prototype[UNSOLICITED_RESTRICTED_STATE_CHANGED] = null;
 RilObject.prototype[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE] = function UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE() {
   this._handleChangedEmergencyCbMode(true);
 };
 RilObject.prototype[UNSOLICITED_CDMA_CALL_WAITING] = function UNSOLICITED_CDMA_CALL_WAITING(length) {
+  let Buf = this.context.Buf;
   let call = {};
   call.number              = Buf.readString();
   call.numberPresentation  = Buf.readInt32();
   call.name                = Buf.readString();
   call.namePresentation    = Buf.readInt32();
   call.isPresent           = Buf.readInt32();
   call.signalType          = Buf.readInt32();
   call.alertPitch          = Buf.readInt32();
   call.signal              = Buf.readInt32();
   this.sendChromeMessage({rilMessageType: "cdmaCallWaiting",
                           number: call.number});
 };
 RilObject.prototype[UNSOLICITED_CDMA_OTA_PROVISION_STATUS] = function UNSOLICITED_CDMA_OTA_PROVISION_STATUS() {
-  let status = Buf.readInt32List()[0];
+  let status = this.context.Buf.readInt32List()[0];
   this.sendChromeMessage({rilMessageType: "otastatuschange",
                           status: status});
 };
 RilObject.prototype[UNSOLICITED_CDMA_INFO_REC] = function UNSOLICITED_CDMA_INFO_REC(length) {
-  let record = CdmaPDUHelper.decodeInformationRecord();
+  let record = this.context.CdmaPDUHelper.decodeInformationRecord();
   record.rilMessageType = "cdma-info-rec-received";
   this.sendChromeMessage(record);
 };
 RilObject.prototype[UNSOLICITED_OEM_HOOK_RAW] = null;
 RilObject.prototype[UNSOLICITED_RINGBACK_TONE] = null;
 RilObject.prototype[UNSOLICITED_RESEND_INCALL_MUTE] = null;
 RilObject.prototype[UNSOLICITED_EXIT_EMERGENCY_CALLBACK_MODE] = function UNSOLICITED_EXIT_EMERGENCY_CALLBACK_MODE() {
   this._handleChangedEmergencyCbMode(false);
 };
 RilObject.prototype[UNSOLICITED_RIL_CONNECTED] = function UNSOLICITED_RIL_CONNECTED(length) {
   // Prevent response id collision between UNSOLICITED_RIL_CONNECTED and
   // UNSOLICITED_VOICE_RADIO_TECH_CHANGED for Akami on gingerbread branch.
   if (!length) {
     return;
   }
 
-  let version = Buf.readInt32List()[0];
+  let version = this.context.Buf.readInt32List()[0];
   this.v5Legacy = (version < 5);
   if (DEBUG) {
     debug("Detected RIL version " + version);
     debug("this.v5Legacy is " + this.v5Legacy);
   }
 
   this.initRILState();
   // Always ensure that we are not in emergency callback mode when init.
@@ -6434,27 +6540,29 @@ RilObject.prototype[UNSOLICITED_RIL_CONN
 /**
  * This object exposes the functionality to parse and serialize PDU strings
  *
  * A PDU is a string containing a series of hexadecimally encoded octets
  * or nibble-swapped binary-coded decimals (BCDs). It contains not only the
  * message text but information about the sender, the SMS service center,
  * timestamp, etc.
  */
-function GsmPDUHelperObject() {
+function GsmPDUHelperObject(aContext) {
+  this.context = aContext;
 }
 GsmPDUHelperObject.prototype = {
+  context: null,
 
   /**
    * Read one character (2 bytes) from a RIL string and decode as hex.
    *
    * @return the nibble as a number.
    */
   readHexNibble: function() {
-    let nibble = Buf.readUint16();
+    let nibble = this.context.Buf.readUint16();
     if (nibble >= 48 && nibble <= 57) {
       nibble -= 48; // ASCII '0'..'9'
     } else if (nibble >= 65 && nibble <= 70) {
       nibble -= 55; // ASCII 'A'..'F'
     } else if (nibble >= 97 && nibble <= 102) {
       nibble -= 87; // ASCII 'a'..'f'
     } else {
       throw "Found invalid nibble during PDU parsing: " +
@@ -6471,17 +6579,17 @@ GsmPDUHelperObject.prototype = {
    */
   writeHexNibble: function(nibble) {
     nibble &= 0x0f;
     if (nibble < 10) {
       nibble += 48; // ASCII '0'
     } else {
       nibble += 55; // ASCII 'A'
     }
-    Buf.writeUint16(nibble);
+    this.context.Buf.writeUint16(nibble);
   },
 
   /**
    * Read a hex-encoded octet (two nibbles).
    *
    * @return the octet as a number.
    */
   readHexOctet: function() {
@@ -6612,16 +6720,17 @@ GsmPDUHelperObject.prototype = {
    * @param data
    *        Data to write (as a string or a number)
    */
   writeSwappedNibbleBCD: function(data) {
     data = data.toString();
     if (data.length % 2) {
       data += "F";
     }
+    let Buf = this.context.Buf;
     for (let i = 0; i < data.length; i += 2) {
       Buf.writeUint16(data.charCodeAt(i + 1));
       Buf.writeUint16(data.charCodeAt(i));
     }
   },
 
   /**
    * Write numerical data as swapped nibble BCD.
@@ -6630,16 +6739,17 @@ GsmPDUHelperObject.prototype = {
    * @param data
    *        Data to write (as a string or a number)
    */
   writeSwappedNibbleBCDNum: function(data) {
     data = data.toString();
     if (data.length % 2) {
       data = "0" + data;
     }
+    let Buf = this.context.Buf;
     for (let i = 0; i < data.length; i += 2) {
       Buf.writeUint16(data.charCodeAt(i + 1));
       Buf.writeUint16(data.charCodeAt(i));
     }
   },
 
   /**
    * Read user data, convert to septets, look up relevant characters in a
@@ -7325,17 +7435,17 @@ GsmPDUHelperObject.prototype = {
    *
    * @param msg
    *        message object for output.
    */
   readExtraParams: function(msg) {
     // Because each PDU octet is converted to two UCS2 char2, we should always
     // get even messageStringLength in this#_processReceivedSms(). So, we'll
     // always need two delimitors at the end.
-    if (Buf.getReadAvailable() <= 4) {
+    if (this.context.Buf.getReadAvailable() <= 4) {
       return;
     }
 
     // TP-Parameter-Indicator
     let pi;
     do {
       // `The most significant bit in octet 1 and any other TP-PI octets which
       // may be added later is reserved as an extension bit which when set to a
@@ -7438,16 +7548,18 @@ GsmPDUHelperObject.prototype = {
    * @return Message parsed or null for invalid message.
    */
   processReceivedSms: function(length) {
     if (!length) {
       if (DEBUG) debug("Received empty SMS!");
       return [null, PDU_FCS_UNSPECIFIED];
     }
 
+    let Buf = this.context.Buf;
+
     // An SMS is a string, but we won't read it as such, so let's read the
     // string length and then defer to PDU parsing helper.
     let messageStringLength = Buf.readInt32();
     if (DEBUG) debug("Got new SMS, length " + messageStringLength);
     let message = this.readMessage();
     if (DEBUG) debug("Got new SMS: " + JSON.stringify(message));
 
     // Read string delimiters. See Buf.readString().
@@ -7461,19 +7573,21 @@ GsmPDUHelperObject.prototype = {
     if (message.epid == PDU_PID_SHORT_MESSAGE_TYPE_0) {
       // `A short message type 0 indicates that the ME must acknowledge receipt
       // of the short message but shall discard its contents.` ~ 3GPP TS 23.040
       // 9.2.3.9
       return [null, PDU_FCS_OK];
     }
 
     if (message.messageClass == GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]) {
+      let RIL = this.context.RIL;
       switch (message.epid) {
         case PDU_PID_ANSI_136_R_DATA:
         case PDU_PID_USIM_DATA_DOWNLOAD:
+          let ICCUtilsHelper = this.context.ICCUtilsHelper;
           if (ICCUtilsHelper.isICCServiceAvailable("DATA_DOWNLOAD_SMS_PP")) {
             // `If the service "data download via SMS Point-to-Point" is
             // allocated and activated in the (U)SIM Service Table, ... then the
             // ME shall pass the message transparently to the UICC using the
             // ENVELOPE (SMS-PP DOWNLOAD).` ~ 3GPP TS 31.111 7.1.1.1
             RIL.dataDownloadViaSMSPP(message);
 
             // `the ME shall not display the message, or alert the user of a
@@ -7588,16 +7702,17 @@ GsmPDUHelperObject.prototype = {
    *        Table index used for escaped 7-bit encoded character lookup.
    * @param requestStatusReport
    *        Request status report.
    */
   writeMessage: function(options) {
     if (DEBUG) {
       debug("writeMessage: " + JSON.stringify(options));
     }
+    let Buf = this.context.Buf;
     let address = options.number;
     let body = options.body;
     let dcs = options.dcs;
     let userDataHeaderLength = options.userDataHeaderLength;
     let encodedBodyLength = options.encodedBodyLength;
     let langIndex = options.langIndex;
     let langShiftIndex = options.langShiftIndex;
 
@@ -7742,31 +7857,33 @@ GsmPDUHelperObject.prototype = {
    * Read GSM CBS message serial number.
    *
    * @param msg
    *        message object for output.
    *
    * @see 3GPP TS 23.041 section 9.4.1.2.1
    */
   readCbSerialNumber: function(msg) {
+    let Buf = this.context.Buf;
     msg.serial = Buf.readUint8() << 8 | Buf.readUint8();
     msg.geographicalScope = (msg.serial >>> 14) & 0x03;
     msg.messageCode = (msg.serial >>> 4) & 0x03FF;
     msg.updateNumber = msg.serial & 0x0F;
   },
 
   /**
    * Read GSM CBS message message identifier.
    *
    * @param msg
    *        message object for output.
    *
    * @see 3GPP TS 23.041 section 9.4.1.2.2
    */
   readCbMessageIdentifier: function(msg) {
+    let Buf = this.context.Buf;
     msg.messageId = Buf.readUint8() << 8 | Buf.readUint8();
 
     if ((msg.format != CB_FORMAT_ETWS)
         && (msg.messageId >= CB_GSM_MESSAGEID_ETWS_BEGIN)
         && (msg.messageId <= CB_GSM_MESSAGEID_ETWS_END)) {
       // `In the case of transmitting CBS message for ETWS, a part of
       // Message Code can be used to command mobile terminals to activate
       // emergency user alert and message popup in order to alert the users.`
@@ -7786,17 +7903,17 @@ GsmPDUHelperObject.prototype = {
    * Read CBS Data Coding Scheme.
    *
    * @param msg
    *        message object for output.
    *
    * @see 3GPP TS 23.038 section 5.
    */
   readCbDataCodingScheme: function(msg) {
-    let dcs = Buf.readUint8();
+    let dcs = this.context.Buf.readUint8();
     if (DEBUG) debug("PDU: read CBS dcs: " + dcs);
 
     let language = null, hasLanguageIndicator = false;
     // `Any reserved codings shall be assumed to be the GSM 7bit default
     // alphabet.`
     let encoding = PDU_DCS_MSG_CODING_7BITS_ALPHABET;
     let messageClass = PDU_DCS_MSG_CLASS_NORMAL;
 
@@ -7865,17 +7982,17 @@ GsmPDUHelperObject.prototype = {
    * Read GSM CBS message page parameter.
    *
    * @param msg
    *        message object for output.
    *
    * @see 3GPP TS 23.041 section 9.4.1.2.4
    */
   readCbPageParameter: function(msg) {
-    let octet = Buf.readUint8();
+    let octet = this.context.Buf.readUint8();
     msg.pageIndex = (octet >>> 4) & 0x0F;
     msg.numPages = octet & 0x0F;
     if (!msg.pageIndex || !msg.numPages) {
       // `If a mobile receives the code 0000 in either the first field or the
       // second field then it shall treat the CBS message exactly the same as a
       // CBS message with page parameter 0001 0001 (i.e. a single page message).`
       msg.pageIndex = msg.numPages = 1;
     }
@@ -7885,16 +8002,17 @@ GsmPDUHelperObject.prototype = {
    * Read ETWS Primary Notification message warning type.
    *
    * @param msg
    *        message object for output.
    *
    * @see 3GPP TS 23.041 section 9.3.24
    */
   readCbWarningType: function(msg) {
+    let Buf = this.context.Buf;
     let word = Buf.readUint8() << 8 | Buf.readUint8();
     msg.etws = {
       warningType:        (word >>> 9) & 0x7F,
       popup:              word & 0x80 ? true : false,
       emergencyUserAlert: word & 0x100 ? true : false
     };
   },
 
@@ -7904,16 +8022,17 @@ GsmPDUHelperObject.prototype = {
    * @param msg
    *        message object for output.
    * @param length
    *        length of cell broadcast data to read in octets.
    *
    * @see 3GPP TS 23.041 section 9.3.19
    */
   readGsmCbData: function(msg, length) {
+    let Buf = this.context.Buf;
     let bufAdapter = {
       readHexOctet: function() {
         return Buf.readUint8();
       }
     };
 
     msg.body = null;
     msg.data = null;
@@ -8237,19 +8356,22 @@ BitBufferHelperObject.prototype = {
 
 /**
  * Helper for CDMA PDU
  *
  * Currently, some function are shared with GsmPDUHelper, they should be
  * moved from GsmPDUHelper to a common object shared among GsmPDUHelper and
  * CdmaPDUHelper.
  */
-function CdmaPDUHelperObject() {
+function CdmaPDUHelperObject(aContext) {
+  this.context = aContext;
 }
 CdmaPDUHelperObject.prototype = {
+  context: null,
+
   //       1..........C
   // Only "1234567890*#" is defined in C.S0005-D v2.0
   dtmfChars: ".1234567890*#...",
 
   /**
    * Entry point for SMS encoding, the options object is made compatible
    * with existing writeMessage() of GsmPDUHelper, but less key is used.
    *
@@ -8316,21 +8438,21 @@ CdmaPDUHelperObject.prototype = {
 
     encodeResult = null;
   },
 
   /**
    * Data writters
    */
   writeInt: function(value) {
-    Buf.writeInt32(value);
+    this.context.Buf.writeInt32(value);
   },
 
   writeByte: function(value) {
-    Buf.writeInt32(value & 0xFF);
+    this.context.Buf.writeInt32(value & 0xFF);
   },
 
   /**
    * Transform GSM DCS to CDMA encoding.
    */
   gsmDcsToCdmaEncoding: function(encoding) {
     switch (encoding) {
       case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
@@ -8413,17 +8535,17 @@ CdmaPDUHelperObject.prototype = {
    *        Reference number of concatenated SMS message
    * @param segmentMaxSeq
    *        Total number of concatenated SMS message
    * @param segmentSeq
    *        Sequence number of concatenated SMS message
    */
   encodeUserData: function(options) {
     let userDataBuffer = [];
-    BitBufferHelper.startWrite(userDataBuffer);
+    this.context.BitBufferHelper.startWrite(userDataBuffer);
 
     // Message Identifier
     this.encodeUserDataMsgId(options);
 
     // User Data
     this.encodeUserDataMsg(options);
 
     // Reply Option
@@ -8433,16 +8555,17 @@ CdmaPDUHelperObject.prototype = {
   },
 
   /**
    * User data subparameter encoder : Message Identifier
    *
    * @see 3GGP2 C.S0015-B 2.0, 4.5.1 Message Identifier
    */
   encodeUserDataMsgId: function(options) {
+    let BitBufferHelper = this.context.BitBufferHelper;
     BitBufferHelper.writeBits(PDU_CDMA_MSG_USERDATA_MSG_ID, 8);
     BitBufferHelper.writeBits(3, 8);
     BitBufferHelper.writeBits(PDU_CDMA_MSG_TYPE_SUBMIT, 4);
     BitBufferHelper.writeBits(1, 16); // TODO: How to get message ID?
     if (options.segmentMaxSeq > 1) {
       BitBufferHelper.writeBits(1, 1);
     } else {
       BitBufferHelper.writeBits(0, 1);
@@ -8452,16 +8575,17 @@ CdmaPDUHelperObject.prototype = {
   },
 
   /**
    * User data subparameter encoder : User Data
    *
    * @see 3GGP2 C.S0015-B 2.0, 4.5.2 User Data
    */
   encodeUserDataMsg: function(options) {
+    let BitBufferHelper = this.context.BitBufferHelper;
     BitBufferHelper.writeBits(PDU_CDMA_MSG_USERDATA_BODY, 8);
     // Reserve space for length
     BitBufferHelper.writeBits(0, 8);
     let lengthPosition = BitBufferHelper.getWriteBufferSize();
 
     BitBufferHelper.writeBits(options.encoding, 5);
 
     // Add user data header for message segement
@@ -8555,16 +8679,17 @@ CdmaPDUHelperObject.prototype = {
 
   /**
    * User data subparameter encoder : Reply Option
    *
    * @see 3GGP2 C.S0015-B 2.0, 4.5.11 Reply Option
    */
   encodeUserDataReplyOption: function(options) {
     if (options.requestStatusReport) {
+      let BitBufferHelper = this.context.BitBufferHelper;
       BitBufferHelper.writeBits(PDU_CDMA_MSG_USERDATA_REPLY_OPTION, 8);
       BitBufferHelper.writeBits(1, 8);
       BitBufferHelper.writeBits(0, 1); // USER_ACK_REQ
       BitBufferHelper.writeBits(1, 1); // DAK_REQ
       BitBufferHelper.flushWithPadding();
     }
   },
 
@@ -8690,21 +8815,21 @@ CdmaPDUHelperObject.prototype = {
 
     return [message, PDU_FCS_OK];
   },
 
   /**
    * Data readers
    */
   readInt: function() {
-    return Buf.readInt32();
+    return this.context.Buf.readInt32();
   },
 
   readByte: function() {
-    return (Buf.readInt32() & 0xFF);
+    return (this.context.Buf.readInt32() & 0xFF);
   },
 
   /**
    * Decode CDMA address data into address string
    *
    * @see 3GGP2 C.S0015-B 2.0, 3.4.3.3 Address Parameters
    *
    * Required key in addrInfo
@@ -8741,17 +8866,17 @@ CdmaPDUHelperObject.prototype = {
       let id = this.readByte(),
           length = this.readByte(),
           userDataBuffer = [];
 
       for (let i = 0; i < length; i++) {
           userDataBuffer.push(this.readByte());
       }
 
-      BitBufferHelper.startRead(userDataBuffer);
+      this.context.BitBufferHelper.startRead(userDataBuffer);
 
       switch (id) {
         case PDU_CDMA_MSG_USERDATA_MSG_ID:
           message[id] = this.decodeUserDataMsgId();
           break;
         case PDU_CDMA_MSG_USERDATA_BODY:
           message[id] = this.decodeUserDataMsg(message[PDU_CDMA_MSG_USERDATA_MSG_ID].userHeader);
           break;
@@ -8779,32 +8904,34 @@ CdmaPDUHelperObject.prototype = {
 
   /**
    * User data subparameter decoder: Message Identifier
    *
    * @see 3GGP2 C.S0015-B 2.0, 4.5.1 Message Identifier
    */
   decodeUserDataMsgId: function() {
     let result = {};
+    let BitBufferHelper = this.context.BitBufferHelper;
     result.msgType = BitBufferHelper.readBits(4);
     result.msgId = BitBufferHelper.readBits(16);
     result.userHeader = BitBufferHelper.readBits(1);
 
     return result;
   },
 
   /**
    * Decode user data header, we only care about segment information
    * on CDMA.
    *
    * This function is mostly copied from gsmPduHelper.readUserDataHeader() but
    * change the read function, because CDMA user header decoding is't byte-wise
    * aligned.
    */
   decodeUserDataHeader: function(encoding) {
+    let BitBufferHelper = this.context.BitBufferHelper;
     let header = {},
         headerSize = BitBufferHelper.readBits(8),
         userDataHeaderSize = headerSize + 1,
         headerPaddingBits = 0;
 
     // Calculate header size
     if (encoding === PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
       // Length is in 7-bit
@@ -8951,16 +9078,17 @@ CdmaPDUHelperObject.prototype = {
         return PDU_DCS_MSG_CODING_16BITS_ALPHABET;
     }
     return null;
   },
 
   decodeCdmaPDUMsg: function(encoding, msgType, msgBodySize) {
     const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
     const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
+    let BitBufferHelper = this.context.BitBufferHelper;
     let result = "";
     let msgDigit;
     switch (encoding) {
       case PDU_CDMA_MSG_CODING_OCTET:         // TODO : Require Test
         while(msgBodySize > 0) {
           msgDigit = String.fromCharCode(BitBufferHelper.readBits(8));
           result += msgDigit;
           msgBodySize--;
@@ -9083,16 +9211,17 @@ CdmaPDUHelperObject.prototype = {
   },
 
   /**
    * User data subparameter decoder : User Data
    *
    * @see 3GGP2 C.S0015-B 2.0, 4.5.2 User Data
    */
   decodeUserDataMsg: function(hasUserHeader) {
+    let BitBufferHelper = this.context.BitBufferHelper;
     let result = {},
         encoding = BitBufferHelper.readBits(5),
         msgType;
 
     if(encoding === PDU_CDMA_MSG_CODING_IS_91) {
       msgType = BitBufferHelper.readBits(8);
     }
     result.encoding = this.getCdmaMsgEncoding(encoding);
@@ -9126,16 +9255,17 @@ CdmaPDUHelperObject.prototype = {
   },
 
   /**
    * User data subparameter decoder : Time Stamp
    *
    * @see 3GGP2 C.S0015-B 2.0, 4.5.4 Message Center Time Stamp
    */
   decodeUserDataTimestamp: function() {
+    let BitBufferHelper = this.context.BitBufferHelper;
     let year = this.decodeBcd(BitBufferHelper.readBits(8)),
         month = this.decodeBcd(BitBufferHelper.readBits(8)) - 1,
         date = this.decodeBcd(BitBufferHelper.readBits(8)),
         hour = this.decodeBcd(BitBufferHelper.readBits(8)),
         min = this.decodeBcd(BitBufferHelper.readBits(8)),
         sec = this.decodeBcd(BitBufferHelper.readBits(8));
 
     if (year >= 96 && year <= 99) {
@@ -9150,43 +9280,44 @@ CdmaPDUHelperObject.prototype = {
   },
 
   /**
    * User data subparameter decoder : Reply Option
    *
    * @see 3GGP2 C.S0015-B 2.0, 4.5.11 Reply Option
    */
   decodeUserDataReplyOption: function() {
-    let replyAction = BitBufferHelper.readBits(4),
+    let replyAction = this.context.BitBufferHelper.readBits(4),
         result = { userAck: (replyAction & 0x8) ? true : false,
                    deliverAck: (replyAction & 0x4) ? true : false,
                    readAck: (replyAction & 0x2) ? true : false,
                    report: (replyAction & 0x1) ? true : false
                  };
 
     return result;
   },
 
   /**
    * User data subparameter decoder : Language Indicator
    *
    * @see 3GGP2 C.S0015-B 2.0, 4.5.14 Language Indicator
    */
   decodeLanguageIndicator: function() {
-    let language = BitBufferHelper.readBits(8);
+    let language = this.context.BitBufferHelper.readBits(8);
     let result = CB_CDMA_LANG_GROUP[language];
     return result;
   },
 
   /**
    * User data subparameter decoder : Call-Back Number
    *
    * @see 3GGP2 C.S0015-B 2.0, 4.5.15 Call-Back Number
    */
   decodeUserDataCallbackNumber: function() {
+    let BitBufferHelper = this.context.BitBufferHelper;
     let digitMode = BitBufferHelper.readBits(1);
     if (digitMode) {
       let numberType = BitBufferHelper.readBits(3),
           numberPlan = BitBufferHelper.readBits(4);
     }
     let numberFields = BitBufferHelper.readBits(8),
         result = "";
     for (let i = 0; i < numberFields; i++) {
@@ -9203,28 +9334,30 @@ CdmaPDUHelperObject.prototype = {
   },
 
   /**
    * User data subparameter decoder : Message Status
    *
    * @see 3GGP2 C.S0015-B 2.0, 4.5.21 Message Status
    */
   decodeUserDataMsgStatus: function() {
+    let BitBufferHelper = this.context.BitBufferHelper;
     let result = {
       errorClass: BitBufferHelper.readBits(2),
       msgStatus: BitBufferHelper.readBits(6)
     };
 
     return result;
   },
 
   /**
    * Decode information record parcel.
    */
   decodeInformationRecord: function() {
+    let Buf = this.context.Buf;
     let record = {};
     let numOfRecords = Buf.readInt32();
 
     let type;
     for (let i = 0; i < numOfRecords; i++) {
       type = Buf.readInt32();
 
       switch (type) {
@@ -9327,27 +9460,32 @@ CdmaPDUHelperObject.prototype = {
 
     return record;
   }
 };
 
 /**
  * Helper for processing ICC PDUs.
  */
-function ICCPDUHelperObject() {
+function ICCPDUHelperObject(aContext) {
+  this.context = aContext;
 }
 ICCPDUHelperObject.prototype = {
+  context: null,
+
   /**
    * Read GSM 8-bit unpacked octets,
    * which are default 7-bit alphabets with bit 8 set to 0.
    *
    * @param numOctets
    *        Number of octets to be read.
    */
   read8BitUnpackedToString: function(numOctets) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     let ret = "";
     let escapeFound = false;
     let i;
     const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
     const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
 
     for(i = 0; i < numOctets; i++) {
       let octet = GsmPDUHelper.readHexOctet();
@@ -9373,31 +9511,34 @@ ICCPDUHelperObject.prototype = {
         }
       } else if (octet == PDU_NL_EXTENDED_ESCAPE) {
         escapeFound = true;
       } else {
         ret += langTable[octet];
       }
     }
 
+    let Buf = this.context.Buf;
     Buf.seekIncoming((numOctets - i) * Buf.PDU_HEX_OCTET_SIZE);
     return ret;
   },
 
   /**
    * Write GSM 8-bit unpacked octets.
    *
    * @param numOctets   Number of total octets to be writen, including trailing
    *                    0xff.
    * @param str         String to be written. Could be null.
    */
   writeStringTo8BitUnpacked: function(numOctets, str) {
     const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
     const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT];
 
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     // If the character is GSM extended alphabet, two octets will be written.
     // So we need to keep track of number of octets to be written.
     let i, j;
     let len = str ? str.length : 0;
     for (i = 0, j = 0; i < len && j < numOctets; i++) {
       let c = str.charAt(i);
       let octet = langTable.indexOf(c);
 
@@ -9430,16 +9571,19 @@ ICCPDUHelperObject.prototype = {
    *
    * @see TS 101.221, Annex A.
    * @param scheme
    *        Coding scheme for UCS2 on UICC. One of 0x80, 0x81 or 0x82.
    * @param numOctets
    *        Number of octets to be read as UCS2 string.
    */
   readICCUCS2String: function(scheme, numOctets) {
+    let Buf = this.context.Buf;
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     let str = "";
     switch (scheme) {
       /**
        * +------+---------+---------+---------+---------+------+------+
        * | 0x80 | Ch1_msb | Ch1_lsb | Ch2_msb | Ch2_lsb | 0xff | 0xff |
        * +------+---------+---------+---------+---------+------+------+
        */
       case 0x80:
@@ -9523,16 +9667,17 @@ ICCPDUHelperObject.prototype = {
   },
 
   /**
    * Read Alpha Id and Dialling number from TS TS 151.011 clause 10.5.1
    *
    * @param recordSize  The size of linear fixed record.
    */
   readAlphaIdDiallingNumber: function(recordSize) {
+    let Buf = this.context.Buf;
     let length = Buf.readInt32();
 
     let alphaLen = recordSize - ADN_FOOTER_SIZE_BYTES;
     let alphaId = this.readAlphaIdentifier(alphaLen);
 
     let number = this.readNumberWithLength();
 
     // Skip 2 unused octets, CCP and EXT1.
@@ -9550,16 +9695,19 @@ ICCPDUHelperObject.prototype = {
   /**
    * Write Alpha Identifier and Dialling number from TS 151.011 clause 10.5.1
    *
    * @param recordSize  The size of linear fixed record.
    * @param alphaId     Alpha Identifier to be written.
    * @param number      Dialling Number to be written.
    */
   writeAlphaIdDiallingNumber: function(recordSize, alphaId, number) {
+    let Buf = this.context.Buf;
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     // Write String length
     let strLen = recordSize * 2;
     Buf.writeInt32(strLen);
 
     let alphaLen = recordSize - ADN_FOOTER_SIZE_BYTES;
     this.writeAlphaIdentifier(alphaLen, alphaId);
     this.writeNumberWithLength(number);
 
@@ -9585,22 +9733,23 @@ ICCPDUHelperObject.prototype = {
    */
   readAlphaIdentifier: function(numOctets) {
     if (numOctets === 0) {
       return "";
     }
 
     let temp;
     // Read the 1st octet to determine the encoding.
-    if ((temp = GsmPDUHelper.readHexOctet()) == 0x80 ||
+    if ((temp = this.context.GsmPDUHelper.readHexOctet()) == 0x80 ||
          temp == 0x81 ||
          temp == 0x82) {
       numOctets--;
       return this.readICCUCS2String(temp, numOctets);
     } else {
+      let Buf = this.context.Buf;
       Buf.seekIncoming(-1 * Buf.PDU_HEX_OCTET_SIZE);
       return this.read8BitUnpackedToString(numOctets);
     }
   },
 
   /**
    * Write Alpha Identifier.
    *
@@ -9613,19 +9762,21 @@ ICCPDUHelperObject.prototype = {
    * Unused octets will be written as 0xff.
    */
   writeAlphaIdentifier: function(numOctets, alphaId) {
     if (numOctets === 0) {
       return;
     }
 
     // If alphaId is empty or it's of GSM 8 bit.
-    if (!alphaId || ICCUtilsHelper.isGsm8BitAlphabet(alphaId)) {
+    if (!alphaId || this.context.ICCUtilsHelper.isGsm8BitAlphabet(alphaId)) {
       this.writeStringTo8BitUnpacked(numOctets, alphaId);
     } else {
+      let GsmPDUHelper = this.context.GsmPDUHelper;
+
       // Currently only support UCS2 coding scheme 0x80.
       GsmPDUHelper.writeHexOctet(0x80);
       numOctets--;
       // Now the alphaId is UCS2 string, each character will take 2 octets.
       if (alphaId.length * 2 > numOctets) {
         alphaId = alphaId.substring(0, Math.floor(numOctets / 2));
       }
       GsmPDUHelper.writeUCS2String(alphaId);
@@ -9657,16 +9808,18 @@ ICCPDUHelperObject.prototype = {
    * "number of useful semi-octets within the Address-Value field".
    */
   readDiallingNumber: function(len) {
     if (DEBUG) debug("PDU: Going to read Dialling number: " + len);
     if (len === 0) {
       return "";
     }
 
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     // TOA = TON + NPI
     let toa = GsmPDUHelper.readHexOctet();
 
     let number = GsmPDUHelper.readSwappedNibbleBcdString(len - 1);
     if (number.length <= 0) {
       if (DEBUG) debug("No number provided");
       return "";
     }
@@ -9677,43 +9830,48 @@ ICCPDUHelperObject.prototype = {
   },
 
   /**
    * Write Dialling Number.
    *
    * @param number  The Dialling number
    */
   writeDiallingNumber: function(number) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     let toa = PDU_TOA_ISDN; // 81
     if (number[0] == '+') {
       toa = PDU_TOA_INTERNATIONAL | PDU_TOA_ISDN; // 91
       number = number.substring(1);
     }
     GsmPDUHelper.writeHexOctet(toa);
     GsmPDUHelper.writeSwappedNibbleBCD(number);
   },
 
   readNumberWithLength: function() {
+    let Buf = this.context.Buf;
     let number;
-    let numLen = GsmPDUHelper.readHexOctet();
+    let numLen = this.context.GsmPDUHelper.readHexOctet();
     if (numLen != 0xff) {
       if (numLen > ADN_MAX_BCD_NUMBER_BYTES) {
         throw new Error("invalid length of BCD number/SSC contents - " + numLen);
       }
 
       number = this.readDiallingNumber(numLen);
       Buf.seekIncoming((ADN_MAX_BCD_NUMBER_BYTES - numLen) * Buf.PDU_HEX_OCTET_SIZE);
     } else {
       Buf.seekIncoming(ADN_MAX_BCD_NUMBER_BYTES * Buf.PDU_HEX_OCTET_SIZE);
     }
 
     return number;
   },
 
   writeNumberWithLength: function(number) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     if (number) {
       let numStart = number[0] == "+" ? 1 : 0;
       number = number.substring(0, numStart) +
                number.substring(numStart)
                      .replace(/[^0-9*#,]/g, "")
                      .replace(/\*/g, "a")
                      .replace(/\#/g, "b")
                      .replace(/\,/g, "c");
@@ -9736,19 +9894,22 @@ ICCPDUHelperObject.prototype = {
       // +1 for numLen
       for (let i = 0; i < ADN_MAX_BCD_NUMBER_BYTES + 1; i++) {
         GsmPDUHelper.writeHexOctet(0xff);
       }
     }
   }
 };
 
-function StkCommandParamsFactoryObject() {
+function StkCommandParamsFactoryObject(aContext) {
+  this.context = aContext;
 }
 StkCommandParamsFactoryObject.prototype = {
+  context: null,
+
   createParam: function(cmdDetails, ctlvs) {
     let method = this[cmdDetails.typeOfCommand];
     if (typeof method != "function") {
       if (DEBUG) {
         debug("Unknown proactive command " + cmdDetails.typeOfCommand.toString(16));
       }
       return null;
     }
@@ -9763,43 +9924,43 @@ StkCommandParamsFactoryObject.prototype 
    * @param ctlvs
    *        The all TLVs in this proactive command.
    */
   processRefresh: function(cmdDetails, ctlvs) {
     let refreshType = cmdDetails.commandQualifier;
     switch (refreshType) {
       case STK_REFRESH_FILE_CHANGE:
       case STK_REFRESH_NAA_INIT_AND_FILE_CHANGE:
-        let ctlv = StkProactiveCmdHelper.searchForTag(
+        let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
           COMPREHENSIONTLV_TAG_FILE_LIST, ctlvs);
         if (ctlv) {
           let list = ctlv.value.fileList;
           if (DEBUG) {
             debug("Refresh, list = " + list);
           }
-          ICCRecordHelper.fetchICCRecords();
+          this.context.ICCRecordHelper.fetchICCRecords();
         }
         break;
     }
     return null;
   },
 
   /**
    * Construct a param for Poll Interval.
    *
    * @param cmdDetails
    *        The value object of CommandDetails TLV.
    * @param ctlvs
    *        The all TLVs in this proactive command.
    */
   processPollInterval: function(cmdDetails, ctlvs) {
-    let ctlv = StkProactiveCmdHelper.searchForTag(
+    let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
         COMPREHENSIONTLV_TAG_DURATION, ctlvs);
     if (!ctlv) {
-      RIL.sendStkTerminalResponse({
+      this.context.RIL.sendStkTerminalResponse({
         command: cmdDetails,
         resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
       throw new Error("Stk Poll Interval: Required value missing : Duration");
     }
 
     return ctlv.value;
   },
 
@@ -9819,20 +9980,20 @@ StkCommandParamsFactoryObject.prototype 
    * Construct a param for Set Up Event list.
    *
    * @param cmdDetails
    *        The value object of CommandDetails TLV.
    * @param ctlvs
    *        The all TLVs in this proactive command.
    */
   processSetUpEventList: function(cmdDetails, ctlvs) {
-    let ctlv = StkProactiveCmdHelper.searchForTag(
+    let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
         COMPREHENSIONTLV_TAG_EVENT_LIST, ctlvs);
     if (!ctlv) {
-      RIL.sendStkTerminalResponse({
+      this.context.RIL.sendStkTerminalResponse({
         command: cmdDetails,
         resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
       throw new Error("Stk Event List: Required value missing : Event List");
     }
 
     return ctlv.value || {eventList: null};
   },
 
@@ -9840,33 +10001,34 @@ StkCommandParamsFactoryObject.prototype 
    * Construct a param for Select Item.
    *
    * @param cmdDetails
    *        The value object of CommandDetails TLV.
    * @param ctlvs
    *        The all TLVs in this proactive command.
    */
   processSelectItem: function(cmdDetails, ctlvs) {
+    let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
     let menu = {};
 
     let ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ALPHA_ID, ctlvs);
     if (ctlv) {
       menu.title = ctlv.value.identifier;
     }
 
     menu.items = [];
     for (let i = 0; i < ctlvs.length; i++) {
       let ctlv = ctlvs[i];
       if (ctlv.tag == COMPREHENSIONTLV_TAG_ITEM) {
         menu.items.push(ctlv.value);
       }
     }
 
     if (menu.items.length === 0) {
-      RIL.sendStkTerminalResponse({
+      this.context.RIL.sendStkTerminalResponse({
         command: cmdDetails,
         resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
       throw new Error("Stk Menu: Required value missing : items");
     }
 
     ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ITEM_ID, ctlvs);
     if (ctlv) {
       menu.defaultItem = ctlv.value.identifier - 1;
@@ -9884,21 +10046,22 @@ StkCommandParamsFactoryObject.prototype 
     if (ctlv) {
       menu.nextActionList = ctlv.value;
     }
 
     return menu;
   },
 
   processDisplayText: function(cmdDetails, ctlvs) {
+    let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
     let textMsg = {};
 
     let ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_TEXT_STRING, ctlvs);
     if (!ctlv) {
-      RIL.sendStkTerminalResponse({
+      this.context.RIL.sendStkTerminalResponse({
         command: cmdDetails,
         resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
       throw new Error("Stk Display Text: Required value missing : Text String");
     }
     textMsg.text = ctlv.value.textString;
 
     ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_IMMEDIATE_RESPONSE, ctlvs);
     if (ctlv) {
@@ -9921,34 +10084,36 @@ StkCommandParamsFactoryObject.prototype 
     }
 
     return textMsg;
   },
 
   processSetUpIdleModeText: function(cmdDetails, ctlvs) {
     let textMsg = {};
 
-    let ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_TEXT_STRING, ctlvs);
+    let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
+        COMPREHENSIONTLV_TAG_TEXT_STRING, ctlvs);
     if (!ctlv) {
-      RIL.sendStkTerminalResponse({
+      this.context.RIL.sendStkTerminalResponse({
         command: cmdDetails,
         resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
       throw new Error("Stk Set Up Idle Text: Required value missing : Text String");
     }
     textMsg.text = ctlv.value.textString;
 
     return textMsg;
   },
 
   processGetInkey: function(cmdDetails, ctlvs) {
+    let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
     let input = {};
 
     let ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_TEXT_STRING, ctlvs);
     if (!ctlv) {
-      RIL.sendStkTerminalResponse({
+      this.context.RIL.sendStkTerminalResponse({
         command: cmdDetails,
         resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
       throw new Error("Stk Get InKey: Required value missing : Text String");
     }
     input.text = ctlv.value.textString;
 
     // duration
     ctlv = StkProactiveCmdHelper.searchForTag(
@@ -9980,21 +10145,22 @@ StkCommandParamsFactoryObject.prototype 
     if (cmdDetails.commandQualifier & 0x80) {
       input.isHelpAvailable = true;
     }
 
     return input;
   },
 
   processGetInput: function(cmdDetails, ctlvs) {
+    let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
     let input = {};
 
     let ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_TEXT_STRING, ctlvs);
     if (!ctlv) {
-      RIL.sendStkTerminalResponse({
+      this.context.RIL.sendStkTerminalResponse({
         command: cmdDetails,
         resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
       throw new Error("Stk Get Input: Required value missing : Text String");
     }
     input.text = ctlv.value.textString;
 
     ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_RESPONSE_LENGTH, ctlvs);
     if (ctlv) {
@@ -10033,66 +10199,69 @@ StkCommandParamsFactoryObject.prototype 
     }
 
     return input;
   },
 
   processEventNotify: function(cmdDetails, ctlvs) {
     let textMsg = {};
 
-    let ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ALPHA_ID, ctlvs);
+    let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
+        COMPREHENSIONTLV_TAG_ALPHA_ID, ctlvs);
     if (!ctlv) {
-      RIL.sendStkTerminalResponse({
+      this.context.RIL.sendStkTerminalResponse({
         command: cmdDetails,
         resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
       throw new Error("Stk Event Notfiy: Required value missing : Alpha ID");
     }
     textMsg.text = ctlv.value.identifier;
 
     return textMsg;
   },
 
   processSetupCall: function(cmdDetails, ctlvs) {
+    let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
     let call = {};
     let iter = Iterator(ctlvs);
 
     let ctlv = StkProactiveCmdHelper.searchForNextTag(COMPREHENSIONTLV_TAG_ALPHA_ID, iter);
     if (ctlv) {
       call.confirmMessage = ctlv.value.identifier;
     }
 
     ctlv = StkProactiveCmdHelper.searchForNextTag(COMPREHENSIONTLV_TAG_ALPHA_ID, iter);
     if (ctlv) {
       call.callMessage = ctlv.value.identifier;
     }
 
     ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ADDRESS, ctlvs);
     if (!ctlv) {
-      RIL.sendStkTerminalResponse({
+      this.context.RIL.sendStkTerminalResponse({
         command: cmdDetails,
         resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
       throw new Error("Stk Set Up Call: Required value missing : Adress");
     }
     call.address = ctlv.value.number;
 
     // see 3GPP TS 31.111 section 6.4.13
     ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_DURATION, ctlvs);
     if (ctlv) {
       call.duration = ctlv.value;
     }
 
     return call;
   },
 
   processLaunchBrowser: function(cmdDetails, ctlvs) {
+    let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
     let browser = {};
 
     let ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_URL, ctlvs);
     if (!ctlv) {
-      RIL.sendStkTerminalResponse({
+      this.context.RIL.sendStkTerminalResponse({
         command: cmdDetails,
         resultCode: STK_RESULT_REQUIRED_VALUES_MISSING});
       throw new Error("Stk Launch Browser: Required value missing : URL");
     }
     browser.url = ctlv.value.url;
 
     ctlv = StkProactiveCmdHelper.searchForTag(COMPREHENSIONTLV_TAG_ALPHA_ID, ctlvs);
     if (ctlv) {
@@ -10100,16 +10269,17 @@ StkCommandParamsFactoryObject.prototype 
     }
 
     browser.mode = cmdDetails.commandQualifier & 0x03;
 
     return browser;
   },
 
   processPlayTone: function(cmdDetails, ctlvs) {
+    let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
     let playTone = {};
 
     let ctlv = StkProactiveCmdHelper.searchForTag(
         COMPREHENSIONTLV_TAG_ALPHA_ID, ctlvs);
     if (ctlv) {
       playTone.text = ctlv.value.identifier;
     }
 
@@ -10141,16 +10311,17 @@ StkCommandParamsFactoryObject.prototype 
   processProvideLocalInfo: function(cmdDetails, ctlvs) {
     let provideLocalInfo = {
       localInfoType: cmdDetails.commandQualifier
     };
     return provideLocalInfo;
   },
 
   processTimerManagement: function(cmdDetails, ctlvs) {
+    let StkProactiveCmdHelper = this.context.StkProactiveCmdHelper;
     let timer = {
       timerAction: cmdDetails.commandQualifier
     };
 
     let ctlv = StkProactiveCmdHelper.searchForTag(
         COMPREHENSIONTLV_TAG_TIMER_IDENTIFIER, ctlvs);
     if (ctlv) {
       timer.timerId = ctlv.value.timerId;
@@ -10171,17 +10342,17 @@ StkCommandParamsFactoryObject.prototype 
     * @param cmdDetails
     *        The value object of CommandDetails TLV.
     * @param ctlvs
     *        The all TLVs in this proactive command.
     */
   processBipMessage: function(cmdDetails, ctlvs) {
     let bipMsg = {};
 
-    let ctlv = StkProactiveCmdHelper.searchForTag(
+    let ctlv = this.context.StkProactiveCmdHelper.searchForTag(
         COMPREHENSIONTLV_TAG_ALPHA_ID, ctlvs);
     if (ctlv) {
       bipMsg.text = ctlv.value.identifier;
     }
 
     return bipMsg;
   }
 };
@@ -10250,25 +10421,29 @@ StkCommandParamsFactoryObject.prototype[
 };
 StkCommandParamsFactoryObject.prototype[STK_CMD_RECEIVE_DATA] = function STK_CMD_RECEIVE_DATA(cmdDetails, ctlvs) {
   return this.processBipMessage(cmdDetails, ctlvs);
 };
 StkCommandParamsFactoryObject.prototype[STK_CMD_SEND_DATA] = function STK_CMD_SEND_DATA(cmdDetails, ctlvs) {
   return this.processBipMessage(cmdDetails, ctlvs);
 };
 
-function StkProactiveCmdHelperObject() {
+function StkProactiveCmdHelperObject(aContext) {
+  this.context = aContext;
 }
 StkProactiveCmdHelperObject.prototype = {
+  context: null,
+
   retrieve: function(tag, length) {
-    let method = StkProactiveCmdHelper[tag];
+    let method = this[tag];
     if (typeof method != "function") {
       if (DEBUG) {
         debug("Unknown comprehension tag " + tag.toString(16));
       }
+      let Buf = this.context.Buf;
       Buf.seekIncoming(length * Buf.PDU_HEX_OCTET_SIZE);
       return null;
     }
     return method.call(this, length);
   },
 
   /**
    * Command Details.
@@ -10276,16 +10451,17 @@ StkProactiveCmdHelperObject.prototype = 
    * | Byte | Description         | Length |
    * |  1   | Command details Tag |   1    |
    * |  2   | Length = 03         |   1    |
    * |  3   | Command number      |   1    |
    * |  4   | Type of Command     |   1    |
    * |  5   | Command Qualifier   |   1    |
    */
   retrieveCommandDetails: function(length) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let cmdDetails = {
       commandNumber: GsmPDUHelper.readHexOctet(),
       typeOfCommand: GsmPDUHelper.readHexOctet(),
       commandQualifier: GsmPDUHelper.readHexOctet()
     };
     return cmdDetails;
   },
 
@@ -10294,16 +10470,17 @@ StkProactiveCmdHelperObject.prototype = 
    *
    * | Byte | Description            | Length |
    * |  1   | Device Identity Tag    |   1    |
    * |  2   | Length = 02            |   1    |
    * |  3   | Source device Identity |   1    |
    * |  4   | Destination device Id  |   1    |
    */
   retrieveDeviceId: function(length) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let deviceId = {
       sourceId: GsmPDUHelper.readHexOctet(),
       destinationId: GsmPDUHelper.readHexOctet()
     };
     return deviceId;
   },
 
   /**
@@ -10312,31 +10489,32 @@ StkProactiveCmdHelperObject.prototype = 
    * | Byte         | Description            | Length |
    * |  1           | Alpha Identifier Tag   |   1    |
    * | 2 ~ (Y-1)+2  | Length (X)             |   Y    |
    * | (Y-1)+3 ~    | Alpha identfier        |   X    |
    * | (Y-1)+X+2    |                        |        |
    */
   retrieveAlphaId: function(length) {
     let alphaId = {
-      identifier: ICCPDUHelper.readAlphaIdentifier(length)
+      identifier: this.context.ICCPDUHelper.readAlphaIdentifier(length)
     };
     return alphaId;
   },
 
   /**
    * Duration.
    *
    * | Byte | Description           | Length |
    * |  1   | Response Length Tag   |   1    |
    * |  2   | Lenth = 02            |   1    |
    * |  3   | Time unit             |   1    |
    * |  4   | Time interval         |   1    |
    */
   retrieveDuration: function(length) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let duration = {
       timeUnit: GsmPDUHelper.readHexOctet(),
       timeInterval: GsmPDUHelper.readHexOctet(),
     };
     return duration;
   },
 
   /**
@@ -10346,17 +10524,17 @@ StkProactiveCmdHelperObject.prototype = 
    * |  1           | Alpha Identifier Tag   |   1    |
    * | 2 ~ (Y-1)+2  | Length (X)             |   Y    |
    * | (Y-1)+3      | TON and NPI            |   1    |
    * | (Y-1)+4 ~    | Dialling number        |   X    |
    * | (Y-1)+X+2    |                        |        |
    */
   retrieveAddress: function(length) {
     let address = {
-      number : ICCPDUHelper.readDiallingNumber(length)
+      number : this.context.ICCPDUHelper.readDiallingNumber(length)
     };
     return address;
   },
 
   /**
    * Text String.
    *
    * | Byte         | Description        | Length |
@@ -10367,27 +10545,29 @@ StkProactiveCmdHelperObject.prototype = 
    * | (Y-1)+X+2    |                    |        |
    */
   retrieveTextString: function(length) {
     if (!length) {
       // null string.
       return {textString: null};
     }
 
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let text = {
       codingScheme: GsmPDUHelper.readHexOctet()
     };
 
     length--; // -1 for the codingScheme.
     switch (text.codingScheme & 0x0f) {
       case STK_TEXT_CODING_GSM_7BIT_PACKED:
         text.textString = GsmPDUHelper.readSeptetsToString(length * 8 / 7, 0, 0, 0);
         break;
       case STK_TEXT_CODING_GSM_8BIT:
-        text.textString = ICCPDUHelper.read8BitUnpackedToString(length);
+        text.textString =
+          this.context.ICCPDUHelper.read8BitUnpackedToString(length);
         break;
       case STK_TEXT_CODING_UCS2:
         text.textString = GsmPDUHelper.readUCS2String(length);
         break;
     }
     return text;
   },
 
@@ -10396,17 +10576,17 @@ StkProactiveCmdHelperObject.prototype = 
    *
    * | Byte | Description     | Length |
    * |  1   | Tone Tag        |   1    |
    * |  2   | Lenth = 01      |   1    |
    * |  3   | Tone            |   1    |
    */
   retrieveTone: function(length) {
     let tone = {
-      tone: GsmPDUHelper.readHexOctet(),
+      tone: this.context.GsmPDUHelper.readHexOctet(),
     };
     return tone;
   },
 
   /**
    * Item.
    *
    * | Byte         | Description            | Length |
@@ -10420,47 +10600,48 @@ StkProactiveCmdHelperObject.prototype = 
     // TS 102.223 ,clause 6.6.7 SET-UP MENU
     // If the "Item data object for item 1" is a null data object
     // (i.e. length = '00' and no value part), this is an indication to the ME
     // to remove the existing menu from the menu system in the ME.
     if (!length) {
       return null;
     }
     let item = {
-      identifier: GsmPDUHelper.readHexOctet(),
-      text: ICCPDUHelper.readAlphaIdentifier(length - 1)
+      identifier: this.context.GsmPDUHelper.readHexOctet(),
+      text: this.context.ICCPDUHelper.readAlphaIdentifier(length - 1)
     };
     return item;
   },
 
   /**
    * Item Identifier.
    *
    * | Byte | Description               | Length |
    * |  1   | Item Identifier Tag       |   1    |
    * |  2   | Lenth = 01                |   1    |
    * |  3   | Identifier of Item chosen |   1    |
    */
   retrieveItemId: function(length) {
     let itemId = {
-      identifier: GsmPDUHelper.readHexOctet()
+      identifier: this.context.GsmPDUHelper.readHexOctet()
     };
     return itemId;
   },
 
   /**
    * Response Length.
    *
    * | Byte | Description                | Length |
    * |  1   | Response Length Tag        |   1    |
    * |  2   | Lenth = 02                 |   1    |
    * |  3   | Minimum length of response |   1    |
    * |  4   | Maximum length of response |   1    |
    */
   retrieveResponseLength: function(length) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let rspLength = {
       minLength : GsmPDUHelper.readHexOctet(),
       maxLength : GsmPDUHelper.readHexOctet()
     };
     return rspLength;
   },
 
   /**
@@ -10469,23 +10650,23 @@ StkProactiveCmdHelperObject.prototype = 
    * | Byte         | Description            | Length |
    * |  1           | File List Tag          |   1    |
    * | 2 ~ (Y-1)+2  | Length (X)             |   Y    |
    * | (Y-1)+3      | Number of files        |   1    |
    * | (Y-1)+4 ~    | Files                  |   X    |
    * | (Y-1)+X+2    |                        |        |
    */
   retrieveFileList: function(length) {
-    let num = GsmPDUHelper.readHexOctet();
+    let num = this.context.GsmPDUHelper.readHexOctet();
     let fileList = "";
     length--; // -1 for the num octet.
     for (let i = 0; i < 2 * length; i++) {
       // Didn't use readHexOctet here,
       // otherwise 0x00 will be "0", not "00"
-      fileList += String.fromCharCode(Buf.readUint16());
+      fileList += String.fromCharCode(this.context.Buf.readUint16());
     }
     return {
       fileList: fileList
     };
   },
 
   /**
    * Default Text.
@@ -10501,16 +10682,17 @@ StkProactiveCmdHelperObject.prototype = 
    */
   retrieveEventList: function(length) {
     if (!length) {
       // null means an indication to ME to remove the existing list of events
       // in ME.
       return null;
     }
 
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let eventList = [];
     for (let i = 0; i < length; i++) {
       eventList.push(GsmPDUHelper.readHexOctet());
     }
     return {
       eventList: eventList
     };
   },
@@ -10520,32 +10702,33 @@ StkProactiveCmdHelperObject.prototype = 
    *
    * | Byte  | Description          | Length |
    * |  1    | Timer Identifier Tag |   1    |
    * |  2    | Length = 01          |   1    |
    * |  3    | Timer Identifier     |   1    |
    */
   retrieveTimerId: function(length) {
     let id = {
-      timerId: GsmPDUHelper.readHexOctet()
+      timerId: this.context.GsmPDUHelper.readHexOctet()
     };
     return id;
   },
 
   /**
    * Timer Value.
    *
    * | Byte  | Description          | Length |
    * |  1    | Timer Value Tag      |   1    |
    * |  2    | Length = 03          |   1    |
    * |  3    | Hour                 |   1    |
    * |  4    | Minute               |   1    |
    * |  5    | Second               |   1    |
    */
   retrieveTimerValue: function(length) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let value = {
       timerValue: (GsmPDUHelper.readSwappedNibbleBcdNum(1) * 60 * 60) +
                   (GsmPDUHelper.readSwappedNibbleBcdNum(1) * 60) +
                   (GsmPDUHelper.readSwappedNibbleBcdNum(1))
     };
     return value;
   },
 
@@ -10565,16 +10748,17 @@ StkProactiveCmdHelperObject.prototype = 
    *
    * | Byte      | Description         | Length |
    * |  1        | URL Tag             |   1    |
    * | 2 ~ (Y+1) | Length(X)           |   Y    |
    * | (Y+2) ~   | URL                 |   X    |
    * | (Y+1+X)   |                     |        |
    */
   retrieveUrl: function(length) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let s = "";
     for (let i = 0; i < length; i++) {
       s += String.fromCharCode(GsmPDUHelper.readHexOctet());
     }
     return {url: s};
   },
 
   /**
@@ -10582,16 +10766,17 @@ StkProactiveCmdHelperObject.prototype = 
    *
    * | Byte  | Description      | Length |
    * |  1    | Next Action tag  |   1    |
    * |  1    | Length(X)        |   1    |
    * |  3~   | Next Action List |   X    |
    * | 3+X-1 |                  |        |
    */
   retrieveNextActionList: function(length) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let nextActionList = [];
     for (let i = 0; i < length; i++) {
       nextActionList.push(GsmPDUHelper.readHexOctet());
     }
     return nextActionList;
   },
 
   searchForTag: function(tag, ctlvs) {
@@ -10658,23 +10843,28 @@ StkProactiveCmdHelperObject.prototype[CO
 };
 StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_URL] = function COMPREHENSIONTLV_TAG_URL(length) {
   return this.retrieveUrl(length);
 };
 StkProactiveCmdHelperObject.prototype[COMPREHENSIONTLV_TAG_NEXT_ACTION_IND] = function COMPREHENSIONTLV_TAG_NEXT_ACTION_IND(length) {
   return this.retrieveNextActionList(length);
 };
 
-function ComprehensionTlvHelperObject() {
+function ComprehensionTlvHelperObject(aContext) {
+  this.context = aContext;
 }
 ComprehensionTlvHelperObject.prototype = {
+  context: null,
+
   /**
    * Decode raw data to a Comprehension-TLV.
    */
   decode: function() {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     let hlen = 0; // For header(tag field + length field) length.
     let temp = GsmPDUHelper.readHexOctet();
     hlen++;
 
     // TS 101.220, clause 7.1.1
     let tag, cr;
     switch (temp) {
       // TS 101.220, clause 7.1.1
@@ -10738,17 +10928,17 @@ ComprehensionTlvHelperObject.prototype =
       }
     } else {
       throw new Error("Invalid octet in Comprehension TLV :" + temp);
     }
 
     let ctlv = {
       tag: tag,
       length: length,
-      value: StkProactiveCmdHelper.retrieve(tag, length),
+      value: this.context.StkProactiveCmdHelper.retrieve(tag, length),
       cr: cr,
       hlen: hlen
     };
     return ctlv;
   },
 
   decodeChunks: function(length) {
     let chunks = [];
@@ -10763,16 +10953,18 @@ ComprehensionTlvHelperObject.prototype =
   },
 
   /**
    * Write Location Info Comprehension TLV.
    *
    * @param loc location Information.
    */
   writeLocationInfoTlv: function(loc) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_LOCATION_INFO |
                                COMPREHENSIONTLV_FLAG_CR);
     GsmPDUHelper.writeHexOctet(loc.gsmCellId > 0xffff ? 9 : 7);
     // From TS 11.14, clause 12.19
     // "The mobile country code (MCC), the mobile network code (MNC),
     // the location area code (LAC) and the cell ID are
     // coded as in TS 04.08."
     // And from TS 04.08 and TS 24.008,
@@ -10822,16 +11014,18 @@ ComprehensionTlvHelperObject.prototype =
 
   /**
    * Given a geckoError string, this function translates it into cause value
    * and write the value into buffer.
    *
    * @param geckoError Error string that is passed to gecko.
    */
   writeCauseTlv: function(geckoError) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     let cause = -1;
     for (let errorNo in RIL_ERROR_TO_GECKO_ERROR) {
       if (geckoError == RIL_ERROR_TO_GECKO_ERROR[errorNo]) {
         cause = errorNo;
         break;
       }
     }
     cause = (cause == -1) ? ERROR_SUCCESS : cause;
@@ -10846,22 +11040,26 @@ ComprehensionTlvHelperObject.prototype =
     // TS 04.08, clause 10.5.4.11: ext bit = 1 + 7 bits for cause.
     // +-----------------+----------------------------------+
     // | Ext = 1 (1 bit) |          Cause (7 bits)          |
     // +-----------------+----------------------------------+
     GsmPDUHelper.writeHexOctet(0x80 | cause);
   },
 
   writeDateTimeZoneTlv: function(date) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_DATE_TIME_ZONE);
     GsmPDUHelper.writeHexOctet(7);
     GsmPDUHelper.writeTimestamp(date);
   },
 
   writeLanguageTlv: function(language) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_LANGUAGE);
     GsmPDUHelper.writeHexOctet(2);
 
     // ISO 639-1, Alpha-2 code
     // TS 123.038, clause 6.2.1, GSM 7 bit Default Alphabet
     GsmPDUHelper.writeHexOctet(
       PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT].indexOf(language[0]));
     GsmPDUHelper.writeHexOctet(
@@ -10870,16 +11068,18 @@ ComprehensionTlvHelperObject.prototype =
 
   /**
    * Write Timer Value Comprehension TLV.
    *
    * @param seconds length of time during of the timer.
    * @param cr Comprehension Required or not
    */
   writeTimerValueTlv: function(seconds, cr) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     GsmPDUHelper.writeHexOctet(COMPREHENSIONTLV_TAG_TIMER_VALUE |
                                (cr ? COMPREHENSIONTLV_FLAG_CR : 0));
     GsmPDUHelper.writeHexOctet(3);
 
     // TS 102.223, clause 8.38
     // +----------------+------------------+-------------------+
     // | hours (1 byte) | minutes (1 btye) | secounds (1 byte) |
     // +----------------+------------------+-------------------+
@@ -10896,16 +11096,18 @@ ComprehensionTlvHelperObject.prototype =
     } else if (length >= 0x80) {
       return 2; // 0x81, len
     } else {
       return 1; // len
     }
   },
 
   writeLength: function(length) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     // TS 101.220 clause 7.1.2, Length Encoding.
     // Length   |  Byte 1  | Byte 2 | Byte 3 | Byte 4 |
     // 0 - 127  |  00 - 7f | N/A    | N/A    | N/A    |
     // 128-255  |  81      | 80 - ff| N/A    | N/A    |
     // 256-65535|  82      | 0100 - ffff     | N/A    |
     // 65536-   |  83      |     010000 - ffffff      |
     // 16777215
     if (length < 0x80) {
@@ -10923,26 +11125,31 @@ ComprehensionTlvHelperObject.prototype =
       GsmPDUHelper.writeHexOctet((length >> 8) & 0xff);
       GsmPDUHelper.writeHexOctet(length & 0xff);
     } else {
       throw new Error("Invalid length value :" + length);
     }
   },
 };
 
-function BerTlvHelperObject() {
+function BerTlvHelperObject(aContext) {
+  this.context = aContext;
 }
 BerTlvHelperObject.prototype = {
+  context: null,
+
   /**
    * Decode Ber TLV.
    *
    * @param dataLen
    *        The length of data in bytes.
    */
   decode: function(dataLen) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     let hlen = 0;
     let tag = GsmPDUHelper.readHexOctet();
     hlen++;
 
     // The length is coded onto 1 or 2 bytes.
     // Length    | Byte 1                | Byte 2
     // 0 - 127   | length ('00' to '7f') | N/A
     // 128 - 255 | '81'                  | length ('80' to 'ff')
@@ -10993,24 +11200,25 @@ BerTlvHelperObject.prototype = {
 
   /**
    * Process the value part for proactive command TLV.
    *
    * @param length
    *        The length of data in bytes.
    */
   processProactiveCommand: function(length) {
-    let ctlvs = ComprehensionTlvHelper.decodeChunks(length);
+    let ctlvs = this.context.ComprehensionTlvHelper.decodeChunks(length);
     return ctlvs;
   },
 
   /**
    * Decode raw data to a Ber-TLV.
    */
   decodeInnerTlv: function() {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let tag = GsmPDUHelper.readHexOctet();
     let length = GsmPDUHelper.readHexOctet();
     return {
       tag: tag,
       length: length,
       value: this.retrieve(tag, length)
     };
   },
@@ -11031,32 +11239,34 @@ BerTlvHelperObject.prototype = {
   },
 
   retrieve: function(tag, length) {
     let method = this[tag];
     if (typeof method != "function") {
       if (DEBUG) {
         debug("Unknown Ber tag : 0x" + tag.toString(16));
       }
+      let Buf = this.context.Buf;
       Buf.seekIncoming(length * Buf.PDU_HEX_OCTET_SIZE);
       return null;
     }
     return method.call(this, length);
   },
 
   /**
    * File Size Data.
    *
    * | Byte        | Description                                | Length |
    * |  1          | Tag                                        |   1    |
    * |  2          | Length                                     |   1    |
    * |  3 to X+24  | Number of allocated data bytes in the file |   X    |
    * |             | , excluding structural information         |        |
    */
   retrieveFileSizeData: function(length) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let fileSizeData = 0;
     for (let i = 0; i < length; i++) {
       fileSizeData = fileSizeData << 8;
       fileSizeData += GsmPDUHelper.readHexOctet();
     }
 
     return {fileSizeData: fileSizeData};
   },
@@ -11068,16 +11278,17 @@ BerTlvHelperObject.prototype = {
    * |  1      | Tag                   |   1    |
    * |  2      | Length                |   1    |
    * |  3      | File descriptor byte  |   1    |
    * |  4      | Data coding byte      |   1    |
    * |  5 ~ 6  | Record length         |   2    |
    * |  7      | Number of records     |   1    |
    */
   retrieveFileDescriptor: function(length) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let fileDescriptorByte = GsmPDUHelper.readHexOctet();
     let dataCodingByte = GsmPDUHelper.readHexOctet();
     // See TS 102 221 Table 11.5, we only care the least 3 bits for the
     // structure of file.
     let fileStructure = fileDescriptorByte & 0x07;
 
     let fileDescriptor = {
       fileStructure: fileStructure
@@ -11098,16 +11309,17 @@ BerTlvHelperObject.prototype = {
    * File identifier.
    *
    * | Byte    | Description      | Length |
    * |  1      | Tag              |   1    |
    * |  2      | Length           |   1    |
    * |  3 ~ 4  | File identifier  |   2    |
    */
   retrieveFileIdentifier: function(length) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     return {fileId : (GsmPDUHelper.readHexOctet() << 8) +
                       GsmPDUHelper.readHexOctet()};
   },
 
   searchForNextTag: function(tag, iter) {
     for (let [index, tlv] in iter) {
       if (tlv.tag === tag) {
         return tlv;
@@ -11130,19 +11342,22 @@ BerTlvHelperObject.prototype[BER_FCP_FIL
 };
 BerTlvHelperObject.prototype[BER_FCP_FILE_IDENTIFIER_TAG] = function BER_FCP_FILE_IDENTIFIER_TAG(length) {
   return this.retrieveFileIdentifier(length);
 };
 
 /**
  * ICC Helper for getting EF path.
  */
-function ICCFileHelperObject() {
+function ICCFileHelperObject(aContext) {
+  this.context = aContext;
 }
 ICCFileHelperObject.prototype = {
+  context: null,
+
   /**
    * This function handles only EFs that are common to RUIM, SIM, USIM
    * and other types of ICC cards.
    */
   getCommonEFPath: function(fileId) {
     switch (fileId) {
       case ICC_EF_ICCID:
         return EF_PATH_MF_SIM;
@@ -11231,87 +11446,91 @@ ICCFileHelperObject.prototype = {
    * Helper function for getting the pathId for the specific ICC record
    * depeding on which type of ICC card we are using.
    *
    * @param fileId
    *        File id.
    * @return The pathId or null in case of an error or invalid input.
    */
   getEFPath: function(fileId) {
-    if (RIL.appType == null) {
+    let appType = this.context.RIL.appType;
+    if (appType == null) {
       return null;
     }
 
     let path = this.getCommonEFPath(fileId);
     if (path) {
       return path;
     }
 
-    switch (RIL.appType) {
+    switch (appType) {
       case CARD_APPTYPE_SIM:
         return this.getSimEFPath(fileId);
       case CARD_APPTYPE_USIM:
         return this.getUSimEFPath(fileId);
       case CARD_APPTYPE_RUIM:
         return this.getRuimEFPath(fileId);
       default:
         return null;
     }
   }
 };
 
 /**
  * Helper for ICC IO functionalities.
  */
-function ICCIOHelperObject() {
+function ICCIOHelperObject(aContext) {
+  this.context = aContext;
 }
 ICCIOHelperObject.prototype = {
+  context: null,
+
   /**
    * Load EF with type 'Linear Fixed'.
    *
    * @param fileId
    *        The file to operate on, one of the ICC_EF_* constants.
    * @param recordNumber [optional]
    *        The number of the record shall be loaded.
    * @param recordSize [optional]
    *        The size of the record.
    * @param callback [optional]
    *        The callback function shall be called when the record(s) is read.
    * @param onerror [optional]
    *        The callback function shall be called when failure.
    */
   loadLinearFixedEF: function(options) {
     let cb;
-    function readRecord(options) {
+    let readRecord = (function(options) {
       options.command = ICC_COMMAND_READ_RECORD;
       options.p1 = options.recordNumber || 1; // Record number
       options.p2 = READ_RECORD_ABSOLUTE_MODE;
       options.p3 = options.recordSize;
       options.callback = cb || options.callback;
-      RIL.iccIO(options);
-    }
+      this.context.RIL.iccIO(options);
+    }).bind(this);
 
     options.type = EF_TYPE_LINEAR_FIXED;
-    options.pathId = ICCFileHelper.getEFPath(options.fileId);
+    options.pathId = this.context.ICCFileHelper.getEFPath(options.fileId);
     if (options.recordSize) {
       readRecord(options);
       return;
     }
 
     cb = options.callback;
-    options.callback = readRecord.bind(this);
+    options.callback = readRecord;
     this.getResponse(options);
   },
 
   /**
    * Load next record from current record Id.
    */
   loadNextRecord: function(options) {
     options.p1++;
-    RIL.iccIO(options);
+    this.context.RIL.iccIO(options);
   },
 
   /**
    * Update EF with type 'Linear Fixed'.
    *
    * @param fileId
    *        The file to operate on, one of the ICC_EF_* constants.
    * @param recordNumber
@@ -11327,25 +11546,25 @@ ICCIOHelperObject.prototype = {
    */
   updateLinearFixedEF: function(options) {
     if (!options.fileId || !options.recordNumber) {
       throw new Error("Unexpected fileId " + options.fileId +
                       " or recordNumber " + options.recordNumber);
     }
 
     options.type = EF_TYPE_LINEAR_FIXED;
-    options.pathId = ICCFileHelper.getEFPath(options.fileId);
+    options.pathId = this.context.ICCFileHelper.getEFPath(options.fileId);
     let cb = options.callback;
     options.callback = function callback(options) {
       options.callback = cb;
       options.command = ICC_COMMAND_UPDATE_RECORD;
       options.p1 = options.recordNumber;
       options.p2 = READ_RECORD_ABSOLUTE_MODE;
       options.p3 = options.recordSize;
-      RIL.iccIO(options);
+      this.context.RIL.iccIO(options);
     }.bind(this);
     this.getResponse(options);
   },
 
   /**
    * Load EF with type 'Transparent'.
    *
    * @param fileId
@@ -11357,54 +11576,56 @@ ICCIOHelperObject.prototype = {
    */
   loadTransparentEF: function(options) {
     options.type = EF_TYPE_TRANSPARENT;
     let cb = options.callback;
     options.callback = function callback(options) {
       options.callback = cb;
       options.command = ICC_COMMAND_READ_BINARY;
       options.p3 = options.fileSize;
-      RIL.iccIO(options);
+      this.context.RIL.iccIO(options);
     }.bind(this);
     this.getResponse(options);
   },
 
   /**
    * Use ICC_COMMAND_GET_RESPONSE to query the EF.
    *
    * @param fileId
    *        The file to operate on, one of the ICC_EF_* constants.
    */
   getResponse: function(options) {
     options.command = ICC_COMMAND_GET_RESPONSE;
-    options.pathId = options.pathId || ICCFileHelper.getEFPath(options.fileId);
+    options.pathId = options.pathId ||
+                     this.context.ICCFileHelper.getEFPath(options.fileId);
     if (!options.pathId) {
       throw new Error("Unknown pathId for " + options.fileId.toString(16));
     }
     options.p1 = 0; // For GET_RESPONSE, p1 = 0
     options.p2 = 0; // For GET_RESPONSE, p2 = 0
     options.p3 = GET_RESPONSE_EF_SIZE_BYTES;
-    RIL.iccIO(options);
+    this.context.RIL.iccIO(options);
   },
 
   /**
    * Process ICC I/O response.
    */
   processICCIO: function(options) {
     let func = this[options.command];
     func.call(this, options);
   },
 
   /**
    * Process a ICC_COMMAND_GET_RESPONSE type command for REQUEST_SIM_IO.
    */
   processICCIOGetResponse: function(options) {
+    let Buf = this.context.Buf;
     let strLen = Buf.readInt32();
 
-    let peek = GsmPDUHelper.readHexOctet();
+    let peek = this.context.GsmPDUHelper.readHexOctet();
     Buf.seekIncoming(-1 * Buf.PDU_HEX_OCTET_SIZE);
     if (peek === BER_FCP_TEMPLATE_TAG) {
       this.processUSimGetResponse(options, strLen / 2);
     } else {
       this.processSimGetResponse(options);
     }
     Buf.readStringDelimiter(strLen);
 
@@ -11412,16 +11633,18 @@ ICCIOHelperObject.prototype = {
       options.callback(options);
     }
   },
 
   /**
    * Helper function for processing USIM get response.
    */
   processUSimGetResponse: function(options, octetLen) {
+    let BerTlvHelper = this.context.BerTlvHelper;
+
     let berTlv = BerTlvHelper.decode(octetLen);
     // See TS 102 221 Table 11.4 for the content order of getResponse.
     let iter = Iterator(berTlv.value);
     let tlv = BerTlvHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG,
                                             iter);
     if (!tlv || (tlv.value.fileStructure !== UICC_EF_STRUCTURE[options.type])) {
       throw new Error("Expected EF type " + UICC_EF_STRUCTURE[options.type] +
                       " but read " + tlv.value.fileStructure);
@@ -11445,16 +11668,19 @@ ICCIOHelperObject.prototype = {
     }
     options.fileSize = tlv.value.fileSizeData;
   },
 
   /**
    * Helper function for processing SIM get response.
    */
   processSimGetResponse: function(options) {
+    let Buf = this.context.Buf;
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     // The format is from TS 51.011, clause 9.2.1
 
     // Skip RFU, data[0] data[1].
     Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
 
     // File size, data[2], data[3]
     options.fileSize = (GsmPDUHelper.readHexOctet() << 8) |
                         GsmPDUHelper.readHexOctet();
@@ -11557,65 +11783,77 @@ ICCIOHelperObject.prototype[ICC_COMMAND_
 ICCIOHelperObject.prototype[ICC_COMMAND_UPDATE_BINARY] = null;
 ICCIOHelperObject.prototype[ICC_COMMAND_UPDATE_RECORD] = function ICC_COMMAND_UPDATE_RECORD(options) {
   this.processICCIOUpdateRecord(options);
 };
 
 /**
  * Helper for ICC records.
  */
-function ICCRecordHelperObject() {
+function ICCRecordHelperObject(aContext) {
+  this.context = aContext;
 }
 ICCRecordHelperObject.prototype = {
+  context: null,
+
   /**
    * Fetch ICC records.
    */
   fetchICCRecords: function() {
-    switch (RIL.appType) {
+    switch (this.context.RIL.appType) {
       case CARD_APPTYPE_SIM:
       case CARD_APPTYPE_USIM:
-        SimRecordHelper.fetchSimRecords();
+        this.context.SimRecordHelper.fetchSimRecords();
         break;
       case CARD_APPTYPE_RUIM:
-        RuimRecordHelper.fetchRuimRecords();
+        this.context.RuimRecordHelper.fetchRuimRecords();
         break;
     }
   },
 
   /**
    * Read the ICCID.
    */
   readICCID: function() {
     function callback() {
+      let Buf = this.context.Buf;
+      let RIL = this.context.RIL;
+
       let strLen = Buf.readInt32();
       let octetLen = strLen / 2;
-      RIL.iccInfo.iccid = GsmPDUHelper.readSwappedNibbleBcdString(octetLen);
+      RIL.iccInfo.iccid =
+        this.context.GsmPDUHelper.readSwappedNibbleBcdString(octetLen);
       Buf.readStringDelimiter(strLen);
 
       if (DEBUG) debug("ICCID: " + RIL.iccInfo.iccid);
       if (RIL.iccInfo.iccid) {
-        ICCUtilsHelper.handleICCInfoChange();
+        this.context.ICCUtilsHelper.handleICCInfoChange();
         RIL.reportStkServiceIsRunning();
       }
     }
 
-    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_ICCID,
-                                   callback: callback.bind(this)});
+    this.context.ICCIOHelper.loadTransparentEF({
+      fileId: ICC_EF_ICCID,
+      callback: callback.bind(this)
+    });
   },
 
   /**
    * Read ICC ADN like EF, i.e. EF_ADN, EF_FDN.
    *
    * @param fileId      EF id of the ADN or FDN.
    * @param onsuccess   Callback to be called when success.
    * @param onerror     Callback to be called when error.
    */
   readADNLike: function(fileId, onsuccess, onerror) {
+    let ICCIOHelper = this.context.ICCIOHelper;
+
     function callback(options) {
-      let contact = ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
+      let contact =
+        this.context.ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
       if (contact) {
         contact.recordId = options.p1;
         contacts.push(contact);
       }
 
       if (options.p1 < options.totalRecords) {
         ICCIOHelper.loadNextRecord(options);
       } else {
@@ -11642,48 +11880,56 @@ ICCRecordHelperObject.prototype = {
    * @param fileId      EF id of the ADN or FDN.
    * @param contact     The contact will be updated. (Shall have recordId property)
    * @param pin2        PIN2 is required when updating ICC_EF_FDN.
    * @param onsuccess   Callback to be called when success.
    * @param onerror     Callback to be called when error.
    */
   updateADNLike: function(fileId, contact, pin2, onsuccess, onerror) {
     function dataWriter(recordSize) {
-      ICCPDUHelper.writeAlphaIdDiallingNumber(recordSize,
-                                              contact.alphaId,
-                                              contact.number);
+      this.context.ICCPDUHelper.writeAlphaIdDiallingNumber(recordSize,
+                                                           contact.alphaId,
+                                                           contact.number);
     }
 
     function callback(options) {
       if (onsuccess) {
         onsuccess();
       }
     }
 
     if (!contact || !contact.recordId) {
       let error = onerror || debug;
       error(GECKO_ERROR_INVALID_PARAMETER);
       return;
     }
 
-    ICCIOHelper.updateLinearFixedEF({fileId: fileId,
-                                     recordNumber: contact.recordId,
-                                     dataWriter: dataWriter.bind(this),
-                                     pin2: pin2,
-                                     callback: callback.bind(this),
-                                     onerror: onerror});
+    this.context.ICCIOHelper.updateLinearFixedEF({
+      fileId: fileId,
+      recordNumber: contact.recordId,
+      dataWriter: dataWriter.bind(this),
+      pin2: pin2,
+      callback: callback.bind(this),
+      onerror: onerror
+    });
   },
 
   /**
    * Read USIM/RUIM Phonebook.
    *
    * @param onsuccess   Callback to be called when success.
    * @param onerror     Callback to be called when error.
    */
   readPBR: function(onsuccess, onerror) {
+    let Buf = this.context.Buf;
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+    let ICCIOHelper = this.context.ICCIOHelper;
+    let ICCUtilsHelper = this.context.ICCUtilsHelper;
+    let RIL = this.context.RIL;
+
     function callback(options) {
       let strLen = Buf.readInt32();
       let octetLen = strLen / 2, readLen = 0;
 
       let pbrTlvs = [];
       while (readLen < octetLen) {
         let tag = GsmPDUHelper.readHexOctet();
         if (tag == 0xff) {
@@ -11746,64 +11992,72 @@ ICCRecordHelperObject.prototype = {
    *
    * @param fileId       EF id of the IAP.
    * @param recordNumber The number of the record shall be loaded.
    * @param onsuccess    Callback to be called when success.
    * @param onerror      Callback to be called when error.
    */
   readIAP: function(fileId, recordNumber, onsuccess, onerror) {
     function callback(options) {
+      let Buf = this.context.Buf;
       let strLen = Buf.readInt32();
       let octetLen = strLen / 2;
       this._iapRecordSize = options.recordSize;
 
-      let iap = GsmPDUHelper.readHexOctetArray(octetLen);
+      let iap = this.context.GsmPDUHelper.readHexOctetArray(octetLen);
       Buf.readStringDelimiter(strLen);
 
       if (onsuccess) {
         onsuccess(iap);
       }
     }
 
-    ICCIOHelper.loadLinearFixedEF({fileId: fileId,
-                                   recordNumber: recordNumber,
-                                   recordSize: this._iapRecordSize,
-                                   callback: callback.bind(this),
-                                   onerror: onerror});
+    this.context.ICCIOHelper.loadLinearFixedEF({
+      fileId: fileId,
+      recordNumber: recordNumber,
+      recordSize: this._iapRecordSize,
+      callback: callback.bind(this),
+      onerror: onerror
+    });
   },
 
   /**
    * Update USIM/RUIM Phonebook EF_IAP.
    *
    * @see TS 131.102, clause 4.4.2.13
    *
    * @param fileId       EF id of the IAP.
    * @param recordNumber The identifier of the record shall be updated.
    * @param iap          The IAP value to be written.
    * @param onsuccess    Callback to be called when success.
    * @param onerror      Callback to be called when error.
    */
   updateIAP: function(fileId, recordNumber, iap, onsuccess, onerror) {
     let dataWriter = function dataWriter(recordSize) {
+      let Buf = this.context.Buf;
+      let GsmPDUHelper = this.context.GsmPDUHelper;
+
       // Write String length
       let strLen = recordSize * 2;
       Buf.writeInt32(strLen);
 
       for (let i = 0; i < iap.length; i++) {
         GsmPDUHelper.writeHexOctet(iap[i]);
       }
 
       Buf.writeStringDelimiter(strLen);
     }.bind(this);
 
-    ICCIOHelper.updateLinearFixedEF({fileId: fileId,
-                                     recordNumber: recordNumber,
-                                     dataWriter: dataWriter,
-                                     callback: onsuccess,
-                                     onerror: onerror});
+    this.context.ICCIOHelper.updateLinearFixedEF({
+      fileId: fileId,
+      recordNumber: recordNumber,
+      dataWriter: dataWriter,
+      callback: onsuccess,
+      onerror: onerror
+    });
   },
 
   /**
    * Cache EF_Email record size.
    */
   _emailRecordSize: null,
 
   /**
@@ -11814,16 +12068,19 @@ ICCRecordHelperObject.prototype = {
    * @param fileId       EF id of the EMAIL.
    * @param fileType     The type of the EMAIL, one of the ICC_USIM_TYPE* constants.
    * @param recordNumber The number of the record shall be loaded.
    * @param onsuccess    Callback to be called when success.
    * @param onerror      Callback to be called when error.
    */
   readEmail: function(fileId, fileType, recordNumber, onsuccess, onerror) {
     function callback(options) {
+      let Buf = this.context.Buf;
+      let ICCPDUHelper = this.context.ICCPDUHelper;
+
       let strLen = Buf.readInt32();
       let octetLen = strLen / 2;
       let email = null;
       this._emailRecordSize = options.recordSize;
 
       // Read contact's email
       //
       // | Byte     | Description                 | Length | M/O
@@ -11843,21 +12100,23 @@ ICCRecordHelperObject.prototype = {
 
       Buf.readStringDelimiter(strLen);
 
       if (onsuccess) {
         onsuccess(email);
       }
     }
 
-    ICCIOHelper.loadLinearFixedEF({fileId: fileId,
-                                   recordNumber: recordNumber,
-                                   recordSize: this._emailRecordSize,
-                                   callback: callback.bind(this),
-                                   onerror: onerror});
+    this.context.ICCIOHelper.loadLinearFixedEF({
+      fileId: fileId,
+      recordNumber: recordNumber,
+      recordSize: this._emailRecordSize,
+      callback: callback.bind(this),
+      onerror: onerror
+    });
   },
 
   /**
    * Update USIM/RUIM Phonebook EF_EMAIL.
    *
    * @see TS 131.102, clause 4.4.2.13
    *
    * @param pbr          Phonebook Reference File.
@@ -11866,36 +12125,42 @@ ICCRecordHelperObject.prototype = {
    * @param adnRecordId  The record Id of ADN, only needed if the fileType of Email is TYPE2.
    * @param onsuccess    Callback to be called when success.
    * @param onerror      Callback to be called when error.
    */
   updateEmail: function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) {
     let fileId = pbr[USIM_PBR_EMAIL].fileId;
     let fileType = pbr[USIM_PBR_EMAIL].fileType;
     let dataWriter = function dataWriter(recordSize) {
+      let Buf = this.context.Buf;
+      let GsmPDUHelper = this.context.GsmPDUHelper;
+      let ICCPDUHelper = this.context.ICCPDUHelper;
+
       // Write String length
       let strLen = recordSize * 2;
       Buf.writeInt32(strLen);
 
       if (fileType == ICC_USIM_TYPE1_TAG) {
         ICCPDUHelper.writeStringTo8BitUnpacked(recordSize, email);
       } else {
         ICCPDUHelper.writeStringTo8BitUnpacked(recordSize - 2, email);
         GsmPDUHelper.writeHexOctet(pbr.adn.sfi || 0xff);
         GsmPDUHelper.writeHexOctet(adnRecordId);
       }
 
       Buf.writeStringDelimiter(strLen);
     }.bind(this);
 
-    ICCIOHelper.updateLinearFixedEF({fileId: fileId,
-                                     recordNumber: recordNumber,
-                                     dataWriter: dataWriter,
-                                     callback: onsuccess,
-                                     onerror: onerror});
+    this.context.ICCIOHelper.updateLinearFixedEF({
+      fileId: fileId,
+      recordNumber: recordNumber,
+      dataWriter: dataWriter,
+      callback: onsuccess,
+      onerror: onerror
+    });
  },
 
   /**
    * Cache EF_ANR record size.
    */
   _anrRecordSize: null,
 
   /**
@@ -11906,24 +12171,25 @@ ICCRecordHelperObject.prototype = {
    * @param fileId       EF id of the ANR.
    * @param fileType     One of the ICC_USIM_TYPE* constants.
    * @param recordNumber The number of the record shall be loaded.
    * @param onsuccess    Callback to be called when success.
    * @param onerror      Callback to be called when error.
    */
   readANR: function(fileId, fileType, recordNumber, onsuccess, onerror) {
     function callback(options) {
+      let Buf = this.context.Buf;
       let strLen = Buf.readInt32();
       let number = null;
       this._anrRecordSize = options.recordSize;
 
       // Skip EF_AAS Record ID.
       Buf.seekIncoming(1 * Buf.PDU_HEX_OCTET_SIZE);
 
-      number = ICCPDUHelper.readNumberWithLength();
+      number = this.context.ICCPDUHelper.readNumberWithLength();
 
       // Skip 2 unused octets, CCP and EXT1.
       Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
 
       // For Type 2 there are two extra octets.
       if (fileType == ICC_USIM_TYPE2_TAG) {
         // Skip 2 unused octets, ADN SFI and Record Identifier.
         Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
@@ -11931,21 +12197,23 @@ ICCRecordHelperObject.prototype = {
 
       Buf.readStringDelimiter(strLen);
 
       if (onsuccess) {
         onsuccess(number);
       }
     }
 
-    ICCIOHelper.loadLinearFixedEF({fileId: fileId,
-                                   recordNumber: recordNumber,
-                                   recordSize: this._anrRecordSize,
-                                   callback: callback.bind(this),
-                                   onerror: onerror});
+    this.context.ICCIOHelper.loadLinearFixedEF({
+      fileId: fileId,
+      recordNumber: recordNumber,
+      recordSize: this._anrRecordSize,
+      callback: callback.bind(this),
+      onerror: onerror
+    });
   },
 
   /**
    * Update USIM/RUIM Phonebook EF_ANR.
    *
    * @see TS 131.102, clause 4.4.2.9
    *
    * @param pbr          Phonebook Reference File.
@@ -11954,54 +12222,64 @@ ICCRecordHelperObject.prototype = {
    * @param adnRecordId  The record Id of ADN, only needed if the fileType of Email is TYPE2.
    * @param onsuccess    Callback to be called when success.
    * @param onerror      Callback to be called when error.
    */
   updateANR: function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) {
     let fileId = pbr[USIM_PBR_ANR0].fileId;
     let fileType = pbr[USIM_PBR_ANR0].fileType;
     let dataWriter = function dataWriter(recordSize) {
+      let Buf = this.context.Buf;
+      let GsmPDUHelper = this.context.GsmPDUHelper;
+
       // Write String length
       let strLen = recordSize * 2;
       Buf.writeInt32(strLen);
 
       // EF_AAS record Id. Unused for now.
       GsmPDUHelper.writeHexOctet(0xff);
 
-      ICCPDUHelper.writeNumberWithLength(number);
+      this.context.ICCPDUHelper.writeNumberWithLength(number);
 
       // Write unused octets 0xff, CCP and EXT1.
       GsmPDUHelper.writeHexOctet(0xff);
       GsmPDUHelper.writeHexOctet(0xff);
 
       // For Type 2 there are two extra octets.
       if (fileType == ICC_USIM_TYPE2_TAG) {
         GsmPDUHelper.writeHexOctet(pbr.adn.sfi || 0xff);
         GsmPDUHelper.writeHexOctet(adnRecordId);
       }
 
       Buf.writeStringDelimiter(strLen);
     }.bind(this);
 
-    ICCIOHelper.updateLinearFixedEF({fileId: fileId,
-                                     recordNumber: recordNumber,
-                                     dataWriter: dataWriter,
-                                     callback: onsuccess,
-                                     onerror: onerror});
+    this.context.ICCIOHelper.updateLinearFixedEF({
+      fileId: fileId,
+      recordNumber: recordNumber,
+      dataWriter: dataWriter,
+      callback: onsuccess,
+      onerror: onerror
+    });
   },
 
   /**
    * Find free record id.
    *
    * @param fileId      EF id.
    * @param onsuccess   Callback to be called when success.
    * @param onerror     Callback to be called when error.
    */
   findFreeRecordId: function(fileId, onsuccess, onerror) {
+    let ICCIOHelper = this.context.ICCIOHelper;
+
     function callback(options) {
+      let Buf = this.context.Buf;
+      let GsmPDUHelper = this.context.GsmPDUHelper;
+
       let strLen = Buf.readInt32();
       let octetLen = strLen / 2;
       let readLen = 0;
 
       while (readLen < octetLen) {
         let octet = GsmPDUHelper.readHexOctet();
         readLen++;
         if (octet != 0xff) {
@@ -12036,151 +12314,177 @@ ICCRecordHelperObject.prototype = {
                                    callback: callback.bind(this),
                                    onerror: onerror});
   },
 };
 
 /**
  * Helper for (U)SIM Records.
  */
-function SimRecordHelperObject() {
+function SimRecordHelperObject(aContext) {
+  this.context = aContext;
 }
 SimRecordHelperObject.prototype = {
+  context: null,
+
   /**
    * Fetch (U)SIM records.
    */
   fetchSimRecords: function() {
-    RIL.getIMSI();
+    this.context.RIL.getIMSI();
     this.readAD();
     this.readSST();
   },
 
   /**
    * Read EF_phase.
    * This EF is only available in SIM.
    */
   readSimPhase: function() {
     function callback() {
+      let Buf = this.context.Buf;
       let strLen = Buf.readInt32();
 
+      let GsmPDUHelper = this.context.GsmPDUHelper;
       let phase = GsmPDUHelper.readHexOctet();
       // If EF_phase is coded '03' or greater, an ME supporting STK shall
       // perform the PROFILE DOWNLOAD procedure.
       if (RILQUIRKS_SEND_STK_PROFILE_DOWNLOAD &&
           phase >= ICC_PHASE_2_PROFILE_DOWNLOAD_REQUIRED) {
-        RIL.sendStkTerminalProfile(STK_SUPPORTED_TERMINAL_PROFILE);
+        this.context.RIL.sendStkTerminalProfile(STK_SUPPORTED_TERMINAL_PROFILE);
       }
 
       Buf.readStringDelimiter(strLen);
     }
 
-    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_PHASE,
-                                   callback: callback.bind(this)});
+    this.context.ICCIOHelper.loadTransparentEF({
+      fileId: ICC_EF_PHASE,
+      callback: callback.bind(this)
+    });
   },
 
   /**
    * Read the MSISDN from the (U)SIM.
    */
   readMSISDN: function() {
     function callback(options) {
-      let contact = ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
+      let RIL = this.context.RIL;
+
+      let contact =
+        this.context.ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
       if (!contact ||
           (RIL.iccInfo.msisdn !== undefined &&
            RIL.iccInfo.msisdn === contact.number)) {
         return;
       }
       RIL.iccInfo.msisdn = contact.number;
       if (DEBUG) debug("MSISDN: " + RIL.iccInfo.msisdn);
-      ICCUtilsHelper.handleICCInfoChange();
-    }
-
-    ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_MSISDN,
-                                   callback: callback.bind(this)});
+      this.context.ICCUtilsHelper.handleICCInfoChange();
+    }
+
+    this.context.ICCIOHelper.loadLinearFixedEF({
+      fileId: ICC_EF_MSISDN,
+      callback: callback.bind(this)
+    });
   },
 
   /**
    * Read the AD (Administrative Data) from the (U)SIM.
    */
   readAD: function() {
     function callback() {
+      let Buf = this.context.Buf;
       let strLen = Buf.readInt32();
       // Each octet is encoded into two chars.
       let octetLen = strLen / 2;
-      let ad = GsmPDUHelper.readHexOctetArray(octetLen);
+      let ad = this.context.GsmPDUHelper.readHexOctetArray(octetLen);
       Buf.readStringDelimiter(strLen);
 
       if (DEBUG) {
         let str = "";
         for (let i = 0; i < ad.length; i++) {
           str += ad[i] + ", ";
         }
         debug("AD: " + str);
       }
 
+      let ICCUtilsHelper = this.context.ICCUtilsHelper;
+      let RIL = this.context.RIL;
       // The 4th byte of the response is the length of MNC.
       let mccMnc = ICCUtilsHelper.parseMccMncFromImsi(RIL.iccInfoPrivate.imsi,
                                                       ad && ad[3]);
       if (mccMnc) {
         RIL.iccInfo.mcc = mccMnc.mcc;
         RIL.iccInfo.mnc = mccMnc.mnc;
         ICCUtilsHelper.handleICCInfoChange();
       }
     }
 
-    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_AD,
-                                   callback: callback.bind(this)});
+    this.context.ICCIOHelper.loadTransparentEF({
+      fileId: ICC_EF_AD,
+      callback: callback.bind(this)
+    });
   },
 
   /**
    * Read the SPN (Service Provider Name) from the (U)SIM.
    */
   readSPN: function() {
     function callback() {
+      let Buf = this.context.Buf;
       let strLen = Buf.readInt32();
       // Each octet is encoded into two chars.
       let octetLen = strLen / 2;
-      let spnDisplayCondition = GsmPDUHelper.readHexOctet();
+      let spnDisplayCondition = this.context.GsmPDUHelper.readHexOctet();
       // Minus 1 because the first octet is used to store display condition.
-      let spn = ICCPDUHelper.readAlphaIdentifier(octetLen - 1);
+      let spn = this.context.ICCPDUHelper.readAlphaIdentifier(octetLen - 1);
       Buf.readStringDelimiter(strLen);
 
       if (DEBUG) {
         debug("SPN: spn = " + spn +
               ", spnDisplayCondition = " + spnDisplayCondition);
       }
 
+      let RIL = this.context.RIL;
       RIL.iccInfoPrivate.spnDisplayCondition = spnDisplayCondition;
       RIL.iccInfo.spn = spn;
+      let ICCUtilsHelper = this.context.ICCUtilsHelper;
       ICCUtilsHelper.updateDisplayCondition();
       ICCUtilsHelper.handleICCInfoChange();
     }
 
-    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_SPN,
-                                   callback: callback.bind(this)});
+    this.context.ICCIOHelper.loadTransparentEF({
+      fileId: ICC_EF_SPN,
+      callback: callback.bind(this)
+    });
   },
 
   /**
    * Read the (U)SIM Service Table from the (U)SIM.
    */
   readSST: function() {
     function callback() {
+      let Buf = this.context.Buf;
+      let RIL = this.context.RIL;
+
       let strLen = Buf.readInt32();
       // Each octet is encoded into two chars.
       let octetLen = strLen / 2;
-      let sst = GsmPDUHelper.readHexOctetArray(octetLen);
+      let sst = this.context.GsmPDUHelper.readHexOctetArray(octetLen);
       Buf.readStringDelimiter(strLen);
       RIL.iccInfoPrivate.sst = sst;
       if (DEBUG) {
         let str = "";
         for (let i = 0; i < sst.length; i++) {
           str += sst[i] + ", ";
         }
         debug("SST: " + str);
       }
 
+      let ICCUtilsHelper = this.context.ICCUtilsHelper;
       if (ICCUtilsHelper.isICCServiceAvailable("MSISDN")) {
         if (DEBUG) debug("MSISDN: MSISDN is available");
         this.readMSISDN();
       } else {
         if (DEBUG) debug("MSISDN: MSISDN service is not available");
       }
 
       // Fetch SPN and PLMN list, if some of them are available.
@@ -12240,56 +12544,65 @@ SimRecordHelperObject.prototype = {
         this.readCBMIR();
       } else {
         RIL.cellBroadcastConfigs.CBMIR = null;
       }
       RIL._mergeAllCellBroadcastConfigs();
     }
 
     // ICC_EF_UST has the same value with ICC_EF_SST.
-    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_SST,
-                                   callback: callback.bind(this)});
+    this.context.ICCIOHelper.loadTransparentEF({
+      fileId: ICC_EF_SST,
+      callback: callback.bind(this)
+    });
   },
 
   /**
    * Read (U)SIM MBDN. (Mailbox Dialling Number)
    *
    * @see TS 131.102, clause 4.2.60
    */
   readMBDN: function() {
     function callback(options) {
-      let contact = ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
+      let RIL = this.context.RIL;
+      let contact =
+        this.context.ICCPDUHelper.readAlphaIdDiallingNumber(options.recordSize);
       if (!contact ||
           (RIL.iccInfoPrivate.mbdn !== undefined &&
            RIL.iccInfoPrivate.mbdn === contact.number)) {
         return;
       }
       RIL.iccInfoPrivate.mbdn = contact.number;
       if (DEBUG) {
         debug("MBDN, alphaId="+contact.alphaId+" number="+contact.number);
       }
       contact.rilMessageType = "iccmbdn";
       RIL.sendChromeMessage(contact);
     }
 
-    ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_MBDN,
-                                   callback: callback.bind(this)});
+    this.context.ICCIOHelper.loadLinearFixedEF({
+      fileId: ICC_EF_MBDN,
+      callback: callback.bind(this)
+    });
   },
 
   /**
    * Read ICC MWIS. (Message Waiting Indication Status)
    *
    * @see TS 31.102, clause 4.2.63 for USIM and TS 51.011, clause 10.3.45 for SIM.
    */
   readMWIS: function() {
     function callback(options) {
+      let Buf = this.context.Buf;
+      let RIL = this.context.RIL;
+
       let strLen = Buf.readInt32();
       // Each octet is encoded into two chars.
       let octetLen = strLen / 2;
-      let mwis = GsmPDUHelper.readHexOctetArray(octetLen);
+      let mwis = this.context.GsmPDUHelper.readHexOctetArray(octetLen);
       Buf.readStringDelimiter(strLen);
       if (!mwis) {
         return;
       }
       RIL.iccInfoPrivate.mwis = mwis; //Keep raw MWIS for updateMWIS()
 
       let mwi = {};
       // b8 b7 B6 b5 b4 b3 b2 b1   4.2.63, TS 31.102 version 11.6.0
@@ -12315,68 +12628,80 @@ SimRecordHelperObject.prototype = {
       } else {
         mwi.msgCount = 0;
       }
 
       RIL.sendChromeMessage({ rilMessageType: "iccmwis",
                               mwi: mwi });
     }
 
-    ICCIOHelper.loadLinearFixedEF({ fileId: ICC_EF_MWIS,
-                                    recordNumber: 1, // Get 1st Subscriber Profile.
-                                    callback: callback });
+    this.context.ICCIOHelper.loadLinearFixedEF({
+      fileId: ICC_EF_MWIS,
+      recordNumber: 1, // Get 1st Subscriber Profile.
+      callback: callback.bind(this)
+    });
   },
 
   /**
    * Update ICC MWIS. (Message Waiting Indication Status)
    *
    * @see TS 31.102, clause 4.2.63 for USIM and TS 51.011, clause 10.3.45 for SIM.
    */
   updateMWIS: function(mwi) {
+    let RIL = this.context.RIL;
     if (!RIL.iccInfoPrivate.mwis) {
       return;
     }
 
     function dataWriter(recordSize) {
       let mwis = RIL.iccInfoPrivate.mwis;
 
       let msgCount =
           (mwi.msgCount === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) ? 0 : mwi.msgCount;
 
       [mwis[0], mwis[1]] = (mwi.active) ? [(mwis[0] | 0x01), msgCount]
                                         : [(mwis[0] & 0xFE), 0];
 
       let strLen = recordSize * 2;
+      let Buf = this.context.Buf;
       Buf.writeInt32(strLen);
 
+      let GsmPDUHelper = this.context.GsmPDUHelper;
       for (let i = 0; i < mwis.length; i++) {
         GsmPDUHelper.writeHexOctet(mwis[i]);
       }
 
       Buf.writeStringDelimiter(strLen);
     }
 
-    ICCIOHelper.updateLinearFixedEF({ fileId: ICC_EF_MWIS,
-                                      recordNumber: 1, // Update 1st Subscriber Profile.
-                                      dataWriter: dataWriter });
+    this.context.ICCIOHelper.updateLinearFixedEF({
+      fileId: ICC_EF_MWIS,
+      recordNumber: 1, // Update 1st Subscriber Profile.
+      dataWriter: dataWriter.bind(this)
+    });
   },
 
   /**
    * Read the SPDI (Service Provider Display Information) from the (U)SIM.
    *
    * See TS 131.102 section 4.2.66 for USIM and TS 51.011 section 10.3.50
    * for SIM.
    */
   readSPDI: function() {
     function callback() {
+      let Buf = this.context.Buf;
       let strLen = Buf.readInt32();
       let octetLen = strLen / 2;
       let readLen = 0;
       let endLoop = false;
+
+      let RIL = this.context.RIL;
       RIL.iccInfoPrivate.SPDI = null;
+
+      let GsmPDUHelper = this.context.GsmPDUHelper;
       while ((readLen < octetLen) && !endLoop) {
         let tlvTag = GsmPDUHelper.readHexOctet();
         let tlvLen = GsmPDUHelper.readHexOctet();
         readLen += 2; // For tag and length fields.
         switch (tlvTag) {
         case SPDI_TAG_SPDI:
           // The value part itself is a TLV.
           continue;
@@ -12394,35 +12719,42 @@ SimRecordHelperObject.prototype = {
         }
       }
 
       // Consume unread octets.
       Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
       Buf.readStringDelimiter(strLen);
 
       if (DEBUG) debug("SPDI: " + JSON.stringify(RIL.iccInfoPrivate.SPDI));
+      let ICCUtilsHelper = this.context.ICCUtilsHelper;
       if (ICCUtilsHelper.updateDisplayCondition()) {
         ICCUtilsHelper.handleICCInfoChange();
       }
     }
 
     // PLMN List is Servive 51 in USIM, EF_SPDI
-    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_SPDI,
-                                   callback: callback.bind(this)});
+    this.context.ICCIOHelper.loadTransparentEF({
+      fileId: ICC_EF_SPDI,
+      callback: callback.bind(this)
+    });
   },
 
   _readCbmiHelper: function(which) {
+    let RIL = this.context.RIL;
+
     function callback() {
+      let Buf = this.context.Buf;
       let strLength = Buf.readInt32();
 
       // Each Message Identifier takes two octets and each octet is encoded
       // into two chars.
       let numIds = strLength / 4, list = null;
       if (numIds) {
         list = [];
+        let GsmPDUHelper = this.context.GsmPDUHelper;
         for (let i = 0, id; i < numIds; i++) {
           id = GsmPDUHelper.readHexOctet() << 8 | GsmPDUHelper.readHexOctet();
           // `Unused entries shall be set to 'FF FF'.`
           if (id != 0xFFFF) {
             list.push(id);
             list.push(id + 1);
           }
         }
@@ -12438,19 +12770,21 @@ SimRecordHelperObject.prototype = {
     }
 
     function onerror() {
       RIL.cellBroadcastConfigs[which] = null;
       RIL._mergeAllCellBroadcastConfigs();
     }
 
     let fileId = GLOBAL["ICC_EF_" + which];
-    ICCIOHelper.loadTransparentEF({fileId: fileId,
-                                   callback: callback.bind(this),
-                                   onerror: onerror.bind(this)});
+    this.context.ICCIOHelper.loadTransparentEF({
+      fileId: fileId,
+      callback: callback.bind(this),
+      onerror: onerror.bind(this)
+    });
   },
 
   /**
    * Read EFcbmi (Cell Broadcast Message Identifier selection)
    *
    * @see 3GPP TS 31.102 v110.02.0 section 4.2.14 EFcbmi
    * @see 3GPP TS 51.011 v5.0.0 section 10.3.13 EFcbmi
    */
@@ -12470,24 +12804,28 @@ SimRecordHelperObject.prototype = {
 
   /**
    * Read EFcbmir (Cell Broadcast Message Identifier Range selection)
    *
    * @see 3GPP TS 31.102 v110.02.0 section 4.2.22 EFcbmir
    * @see 3GPP TS 51.011 v5.0.0 section 10.3.28 EFcbmir
    */
   readCBMIR: function() {
+    let RIL = this.context.RIL;
+
     function callback() {
+      let Buf = this.context.Buf;
       let strLength = Buf.readInt32();
 
       // Each Message Identifier range takes four octets and each octet is
       // encoded into two chars.
       let numIds = strLength / 8, list = null;
       if (numIds) {
         list = [];
+        let GsmPDUHelper = this.context.GsmPDUHelper;
         for (let i = 0, from, to; i < numIds; i++) {
           // `Bytes one and two of each range identifier equal the lower value
           // of a cell broadcast range, bytes three and four equal the upper
           // value of a cell broadcast range.`
           from = GsmPDUHelper.readHexOctet() << 8 | GsmPDUHelper.readHexOctet();
           to = GsmPDUHelper.readHexOctet() << 8 | GsmPDUHelper.readHexOctet();
           // `Unused entries shall be set to 'FF FF'.`
           if ((from != 0xFFFF) && (to != 0xFFFF)) {
@@ -12506,30 +12844,36 @@ SimRecordHelperObject.prototype = {
       RIL._mergeAllCellBroadcastConfigs();
     }
 
     function onerror() {
       RIL.cellBroadcastConfigs.CBMIR = null;
       RIL._mergeAllCellBroadcastConfigs();
     }
 
-    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_CBMIR,
-                                   callback: callback.bind(this),
-                                   onerror: onerror.bind(this)});
+    this.context.ICCIOHelper.loadTransparentEF({
+      fileId: ICC_EF_CBMIR,
+      callback: callback.bind(this),
+      onerror: onerror.bind(this)
+    });
   },
 
   /**
    * Read OPL (Operator PLMN List) from (U)SIM.
    *
    * See 3GPP TS 31.102 Sec. 4.2.59 for USIM
    *     3GPP TS 51.011 Sec. 10.3.42 for SIM.
    */
   readOPL: function() {
+    let ICCIOHelper = this.context.ICCIOHelper;
     let opl = [];
     function callback(options) {
+      let Buf = this.context.Buf;
+      let GsmPDUHelper = this.context.GsmPDUHelper;
+
       let strLen = Buf.readInt32();
       // The first 7 bytes are LAI (for UMTS) and the format of LAI is defined
       // in 3GPP TS 23.003, Sec 4.1
       //    +-------------+---------+
       //    | Octet 1 - 3 | MCC/MNC |
       //    +-------------+---------+
       //    | Octet 4 - 7 |   LAC   |
       //    +-------------+---------+
@@ -12573,37 +12917,40 @@ SimRecordHelperObject.prototype = {
       } else {
         Buf.seekIncoming(5 * Buf.PDU_HEX_OCTET_SIZE);
       }
       Buf.readStringDelimiter(strLen);
 
       if (options.p1 < options.totalRecords) {
         ICCIOHelper.loadNextRecord(options);
       } else {
-        RIL.iccInfoPrivate.OPL = opl;
+        this.context.RIL.iccInfoPrivate.OPL = opl;
       }
     }
 
     ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_OPL,
                                    callback: callback.bind(this)});
   },
 
   /**
    * Read PNN (PLMN Network Name) from (U)SIM.
    *
    * See 3GPP TS 31.102 Sec. 4.2.58 for USIM
    *     3GPP TS 51.011 Sec. 10.3.41 for SIM.
    */
   readPNN: function() {
+    let ICCIOHelper = this.context.ICCIOHelper;
     function callback(options) {
       let pnnElement;
+      let Buf = this.context.Buf;
       let strLen = Buf.readInt32();
       let octetLen = strLen / 2;
       let readLen = 0;
 
+      let GsmPDUHelper = this.context.GsmPDUHelper;
       while (readLen < octetLen) {
         let tlvTag = GsmPDUHelper.readHexOctet();
 
         if (tlvTag == 0xFF) {
           // Unused byte
           readLen++;
           Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
           break;
@@ -12638,17 +12985,17 @@ SimRecordHelperObject.prototype = {
       if (pnnElement && options.p1 < options.totalRecords) {
         ICCIOHelper.loadNextRecord(options);
       } else {
         if (DEBUG) {
           for (let i = 0; i < pnn.length; i++) {
             debug("PNN: [" + i + "]: " + JSON.stringify(pnn[i]));
           }
         }
-        RIL.iccInfoPrivate.PNN = pnn;
+        this.context.RIL.iccInfoPrivate.PNN = pnn;
       }
     }
 
     let pnn = [];
     ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_PNN,
                                    callback: callback.bind(this)});
   },
 
@@ -12660,16 +13007,17 @@ SimRecordHelperObject.prototype = {
    *
    *  @param length The number of PLMN records.
    *  @return An array of string corresponding to the PLMNs.
    */
   readPLMNEntries: function(length) {
     let plmnList = [];
     // Each PLMN entry has 3 bytes.
     if (DEBUG) debug("readPLMNEntries: PLMN entries length = " + length);
+    let GsmPDUHelper = this.context.GsmPDUHelper;
     let index = 0;
     while (index < length) {
       // Unused entries will be 0xFFFFFF, according to EF_SPDI
       // specs (TS 131 102, section 4.2.66)
       try {
         let plmn = [GsmPDUHelper.readHexOctet(),
                     GsmPDUHelper.readHexOctet(),
                     GsmPDUHelper.readHexOctet()];
@@ -12723,24 +13071,26 @@ SimRecordHelperObject.prototype = {
    * Read the SMS from the ICC.
    *
    * @param recordNumber The number of the record shall be loaded.
    * @param onsuccess    Callback to be called when success.
    * @param onerror      Callback to be called when error.
    */
   readSMS: function(recordNumber, onsuccess, onerror) {
     function callback(options) {
+      let Buf = this.context.Buf;
       let strLen = Buf.readInt32();
 
       // TS 51.011, 10.5.3 EF_SMS
       // b3 b2 b1
       //  0  0  1 message received by MS from network; message read
       //  0  1  1 message received by MS from network; message to be read
       //  1  1  1 MS originating message; message to be sent
       //  1  0  1 MS originating message; message sent to the network:
+      let GsmPDUHelper = this.context.GsmPDUHelper;
       let status = GsmPDUHelper.readHexOctet();
 
       let message = GsmPDUHelper.readMessage();
       message.simStatus = status;
 
       // Consumes the remaining buffer
       Buf.seekIncoming(Buf.getReadAvailable() - Buf.PDU_HEX_OCTET_SIZE);
 
@@ -12748,59 +13098,69 @@ SimRecordHelperObject.prototype = {
 
       if (message) {
         onsuccess(message);
       } else {
         onerror("Failed to decode SMS on SIM #" + recordNumber);
       }
     }
 
-    ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_SMS,
-                                   recordNumber: recordNumber,
-                                   callback: callback,
-                                   onerror: onerror});
-  },
-};
-
-function RuimRecordHelperObject() {
+    this.context.ICCIOHelper.loadLinearFixedEF({
+      fileId: ICC_EF_SMS,
+      recordNumber: recordNumber,
+      callback: callback.bind(this),
+      onerror: onerror
+    });
+  },
+};
+
+function RuimRecordHelperObject(aContext) {
+  this.context = aContext;
 }
 RuimRecordHelperObject.prototype = {
+  context: null,
+
   fetchRuimRecords: function() {
     this.getIMSI_M();
     this.readCST();
     this.readCDMAHome();
-    RIL.getCdmaSubscription();
+    this.context.RIL.getCdmaSubscription();
   },
 
   /**
    * Get IMSI_M from CSIM/RUIM.
    * See 3GPP2 C.S0065 Sec. 5.2.2
    */
   getIMSI_M: function() {
     function callback() {
+      let Buf = this.context.Buf;
       let strLen = Buf.readInt32();
-      let encodedImsi = GsmPDUHelper.readHexOctetArray(strLen / 2);
+      let encodedImsi = this.context.GsmPDUHelper.readHexOctetArray(strLen / 2);
       Buf.readStringDelimiter(strLen);
 
       if ((encodedImsi[CSIM_IMSI_M_PROGRAMMED_BYTE] & 0x80)) { // IMSI_M programmed
+        let RIL = this.context.RIL;
         RIL.iccInfoPrivate.imsi = this.decodeIMSI(encodedImsi);
         RIL.sendChromeMessage({rilMessageType: "iccimsi",
                                imsi: RIL.iccInfoPrivate.imsi});
 
+        let ICCUtilsHelper = this.context.ICCUtilsHelper;
         let mccMnc = ICCUtilsHelper.parseMccMncFromImsi(RIL.iccInfoPrivate.imsi);
         if (mccMnc) {
           RIL.iccInfo.mcc = mccMnc.mcc;
           RIL.iccInfo.mnc = mccMnc.mnc;
           ICCUtilsHelper.handleICCInfoChange();
         }
       }
     }
 
-    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_CSIM_IMSI_M,
-                                   callback: callback.bind(this)});
+    this.context.ICCIOHelper.loadTransparentEF({
+      fileId: ICC_EF_CSIM_IMSI_M,
+      callback: callback.bind(this)
+    });
   },
 
   /**
    * Decode IMSI from IMSI_M
    * See 3GPP2 C.S0005 Sec. 2.3.1
    * +---+---------+------------+---+--------+---------+---+---------+--------+
    * |RFU|   MCC   | programmed |RFU|  MNC   |  MIN1   |RFU|   MIN2  |  CLASS |
    * +---+---------+------------+---+--------+---------+---+---------+--------+
@@ -12864,17 +13224,22 @@ RuimRecordHelperObject.prototype = {
     return s;
   },
 
   /**
    * Read CDMAHOME for CSIM.
    * See 3GPP2 C.S0023 Sec. 3.4.8.
    */
   readCDMAHome: function() {
+    let ICCIOHelper = this.context.ICCIOHelper;
+
     function callback(options) {
+      let Buf = this.context.Buf;
+      let GsmPDUHelper = this.context.GsmPDUHelper;
+
       let strLen = Buf.readInt32();
       let tempOctet = GsmPDUHelper.readHexOctet();
       cdmaHomeSystemId.push(((GsmPDUHelper.readHexOctet() & 0x7f) << 8) | tempOctet);
       tempOctet = GsmPDUHelper.readHexOctet();
       cdmaHomeNetworkId.push(((GsmPDUHelper.readHexOctet() & 0xff) << 8) | tempOctet);
 
       // Consuming the last octet: band class.
       Buf.seekIncoming(Buf.PDU_HEX_OCTET_SIZE);
@@ -12882,17 +13247,17 @@ RuimRecordHelperObject.prototype = {
       Buf.readStringDelimiter(strLen);
       if (options.p1 < options.totalRecords) {
         ICCIOHelper.loadNextRecord(options);
       } else {
         if (DEBUG) {
           debug("CDMAHome system id: " + JSON.stringify(cdmaHomeSystemId));
           debug("CDMAHome network id: " + JSON.stringify(cdmaHomeNetworkId));
         }
-        RIL.cdmaHome = {
+        this.context.RIL.cdmaHome = {
           systemId: cdmaHomeSystemId,
           networkId: cdmaHomeNetworkId
         };
       }
     }
 
     let cdmaHomeSystemId = [], cdmaHomeNetworkId = [];
     ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_CSIM_CDMAHOME,
@@ -12900,42 +13265,51 @@ RuimRecordHelperObject.prototype = {
   },
 
   /**
    * Read CDMA Service Table.
    * See 3GPP2 C.S0023 Sec. 3.4.18
    */
   readCST: function() {
     function callback() {
+      let Buf = this.context.Buf;
+      let RIL = this.context.RIL;
+
       let strLen = Buf.readInt32();
       // Each octet is encoded into two chars.
-      RIL.iccInfoPrivate.cst = GsmPDUHelper.readHexOctetArray(strLen / 2);
+      RIL.iccInfoPrivate.cst =
+        this.context.GsmPDUHelper.readHexOctetArray(strLen / 2);
       Buf.readStringDelimiter(strLen);
 
       if (DEBUG) {
         let str = "";
         for (let i = 0; i < RIL.iccInfoPrivate.cst.length; i++) {
           str += RIL.iccInfoPrivate.cst[i] + ", ";
         }
         debug("CST: " + str);
       }
 
-      if (ICCUtilsHelper.isICCServiceAvailable("SPN")) {
+      if (this.context.ICCUtilsHelper.isICCServiceAvailable("SPN")) {
         if (DEBUG) debug("SPN: SPN is available");
         this.readSPN();
       }
     }
-    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_CSIM_CST,
-                                   callback: callback.bind(this)});
+    this.context.ICCIOHelper.loadTransparentEF({
+      fileId: ICC_EF_CSIM_CST,
+      callback: callback.bind(this)
+    });
   },
 
   readSPN: function() {
     function callback() {
+      let Buf = this.context.Buf;
       let strLen = Buf.readInt32();
       let octetLen = strLen / 2;
+
+      let GsmPDUHelper = this.context.GsmPDUHelper;
       let displayCondition = GsmPDUHelper.readHexOctet();
       let codingScheme = GsmPDUHelper.readHexOctet();
       // Skip one octet: language indicator.
       Buf.seekIncoming(Buf.PDU_HEX_OCTET_SIZE);
       let readLen = 3;
 
       // SPN String ends up with 0xff.
       let userDataBuffer = [];
@@ -12944,63 +13318,71 @@ RuimRecordHelperObject.prototype = {
         let octet = GsmPDUHelper.readHexOctet();
         readLen++;
         if (octet == 0xff) {
           break;
         }
         userDataBuffer.push(octet);
       }
 
-      BitBufferHelper.startRead(userDataBuffer);
-
+      this.context.BitBufferHelper.startRead(userDataBuffer);
+
+      let CdmaPDUHelper = this.context.CdmaPDUHelper;
       let msgLen;
       switch (CdmaPDUHelper.getCdmaMsgEncoding(codingScheme)) {
       case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
         msgLen = Math.floor(userDataBuffer.length * 8 / 7);
         break;
       case PDU_DCS_MSG_CODING_8BITS_ALPHABET:
         msgLen = userDataBuffer.length;
         break;
       case PDU_DCS_MSG_CODING_16BITS_ALPHABET:
         msgLen = Math.floor(userDataBuffer.length / 2);
         break;
       }
 
+      let RIL = this.context.RIL;
       RIL.iccInfo.spn = CdmaPDUHelper.decodeCdmaPDUMsg(codingScheme, null, msgLen);
       if (DEBUG) {
         debug("CDMA SPN: " + RIL.iccInfo.spn +
               ", Display condition: " + displayCondition);
       }
       RIL.iccInfoPrivate.spnDisplayCondition = displayCondition;
       Buf.seekIncoming((octetLen - readLen) * Buf.PDU_HEX_OCTET_SIZE);
       Buf.readStringDelimiter(strLen);
     }
 
-    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_CSIM_SPN,
-                                   callback: callback.bind(this)});
+    this.context.ICCIOHelper.loadTransparentEF({
+      fileId: ICC_EF_CSIM_SPN,
+      callback: callback.bind(this)
+    });
   }
 };
 
 /**
  * Helper functions for ICC utilities.
  */
-function ICCUtilsHelperObject() {
+function ICCUtilsHelperObject(aContext) {
+  this.context = aContext;
 }
 ICCUtilsHelperObject.prototype = {
+  context: null,
+
   /**
    * Get network names by using EF_OPL and EF_PNN
    *
    * @See 3GPP TS 31.102 sec. 4.2.58 and sec. 4.2.59 for USIM,
    *      3GPP TS 51.011 sec. 10.3.41 and sec. 10.3.42 for SIM.
    *
    * @param mcc   The mobile country code of the network.
    * @param mnc   The mobile network code of the network.
    * @param lac   The location area code of the network.
    */
   getNetworkNameFromICC: function(mcc, mnc, lac) {
+    let RIL = this.context.RIL;
     let iccInfoPriv = RIL.iccInfoPrivate;
     let iccInfo = RIL.iccInfo;
     let pnnEntry;
 
     if (!mcc || !mnc || !lac) {
       return null;
     }
 
@@ -13059,16 +13441,18 @@ ICCUtilsHelperObject.prototype = {
 
   /**
    * This will compute the spnDisplay field of the network.
    * See TS 22.101 Annex A and TS 51.011 10.3.11 for details.
    *
    * @return True if some of iccInfo is changed in by this function.
    */
   updateDisplayCondition: function() {
+    let RIL = this.context.RIL;
+
     // If EFspn isn't existed in SIM or it haven't been read yet, we should
     // just set isDisplayNetworkNameRequired = true and
     // isDisplaySpnRequired = false
     let iccInfo = RIL.iccInfo;
     let iccInfoPriv = RIL.iccInfoPrivate;
     let displayCondition = iccInfoPriv.spnDisplayCondition;
     let origIsDisplayNetworkNameRequired = iccInfo.isDisplayNetworkNameRequired;
     let origIsDisplaySPNRequired = iccInfo.isDisplaySpnRequired;
@@ -13178,16 +13562,18 @@ ICCUtilsHelperObject.prototype = {
       debug("updateDisplayCondition: isDisplaySpnRequired = " + iccInfo.isDisplaySpnRequired);
     }
 
     return ((origIsDisplayNetworkNameRequired !== iccInfo.isDisplayNetworkNameRequired) ||
             (origIsDisplaySPNRequired !== iccInfo.isDisplaySpnRequired));
   },
 
   decodeSimTlvs: function(tlvsLen) {
+    let GsmPDUHelper = this.context.GsmPDUHelper;
+
     let index = 0;
     let tlvs = [];
     while (index < tlvsLen) {
       let simTlv = {
         tag : GsmPDUHelper.readHexOctet(),
         length : GsmPDUHelper.readHexOctet(),
       };
       simTlv.value = GsmPDUHelper.readHexOctetArray(simTlv.length);
@@ -13228,29 +13614,31 @@ ICCUtilsHelperObject.prototype = {
 
     return pbr;
   },
 
   /**
    * Update the ICC information to RadioInterfaceLayer.
    */
   handleICCInfoChange: function() {
+    let RIL = this.context.RIL;
     RIL.iccInfo.rilMessageType = "iccinfochange";
     RIL.sendChromeMessage(RIL.iccInfo);
   },
 
   /**
    * Get whether specificed (U)SIM service is available.
    *
    * @param geckoService
    *        Service name like "ADN", "BDN", etc.
    *
    * @return true if the service is enabled, false otherwise.
    */
   isICCServiceAvailable: function(geckoService) {
+    let RIL = this.context.RIL;
     let serviceTable = RIL._isCdma ? RIL.iccInfoPrivate.cst:
                                      RIL.iccInfoPrivate.sst;
     let index, bitmask;
     if (RIL.appType == CARD_APPTYPE_SIM || RIL.appType == CARD_APPTYPE_RUIM) {
       /**
        * Service id is valid in 1..N, and 2 bits are used to code each service.
        *
        * +----+--  --+----+----+
@@ -13362,44 +13750,50 @@ ICCUtilsHelperObject.prototype = {
 
     return { mcc: mcc, mnc: mnc};
   },
 };
 
 /**
  * Helper for ICC Contacts.
  */
-function ICCContactHelperObject() {
+function ICCContactHelperObject(aContext) {
+  this.context = aContext;
 }
 ICCContactHelperObject.prototype = {
+  context: null,
+
   /**
    * Helper function to check DF_PHONEBOOK.
    */
   hasDfPhoneBook: function(appType) {
     switch (appType) {
       case CARD_APPTYPE_SIM:
         return false;
       case CARD_APPTYPE_USIM:
         return true;
       case CARD_APPTYPE_RUIM:
+        let ICCUtilsHelper = this.context.ICCUtilsHelper;
         return ICCUtilsHelper.isICCServiceAvailable("ENHANCED_PHONEBOOK");
       default:
         return false;
     }
   },
 
   /**
    * Helper function to read ICC contacts.
    *
    * @param appType       One of CARD_APPTYPE_*.
    * @param contactType   "adn" or "fdn".
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   readICCContacts: function(appType, contactType, onsuccess, onerror) {
+    let ICCRecordHelper = this.context.ICCRecordHelper;
+
     switch (contactType) {
       case "adn":
         if (!this.hasDfPhoneBook(appType)) {
           ICCRecordHelper.readADNLike(ICC_EF_ADN, onsuccess, onerror);
         } else {
           this.readUSimContacts(onsuccess, onerror);
         }
         break;
@@ -13419,16 +13813,18 @@ ICCContactHelperObject.prototype = {
    * Helper function to find free contact record.
    *
    * @param appType       One of CARD_APPTYPE_*.
    * @param contactType   "adn" or "fdn".
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   findFreeICCContact: function(appType, contactType, onsuccess, onerror) {
+    let ICCRecordHelper = this.context.ICCRecordHelper;
+
     switch (contactType) {
       case "adn":
         if (!this.hasDfPhoneBook(appType)) {
           ICCRecordHelper.findFreeRecordId(ICC_EF_ADN, onsuccess.bind(null, 0), onerror);
         } else {
           let gotPbrCb = function gotPbrCb(pbrs) {
             this.findUSimFreeADNRecordId(pbrs, onsuccess, onerror);
           }.bind(this);
@@ -13451,16 +13847,18 @@ ICCContactHelperObject.prototype = {
    /**
     * Find free ADN record id in USIM.
     *
     * @param pbrs          All Phonebook Reference Files read.
     * @param onsuccess     Callback to be called when success.
     * @param onerror       Callback to be called when error.
     */
   findUSimFreeADNRecordId: function(pbrs, onsuccess, onerror) {
+    let ICCRecordHelper = this.context.ICCRecordHelper;
+
     (function findFreeRecordId(pbrIndex) {
       if (pbrIndex >= pbrs.length) {
         if (DEBUG) {
           debug(CONTACT_ERR_NO_FREE_RECORD_FOUND);
         }
         onerror(CONTACT_ERR_NO_FREE_RECORD_FOUND);
         return;
       }
@@ -13479,16 +13877,18 @@ ICCContactHelperObject.prototype = {
    * @param appType       One of CARD_APPTYPE_*.
    * @param contactType   "adn" or "fdn".
    * @param contact       The contact will be added.
    * @param pin2          PIN2 is required for FDN.
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   addICCContact: function(appType, contactType, contact, pin2, onsuccess, onerror) {
+    let ICCContactHelper = this.context.ICCContactHelper;
+
     let foundFreeCb = function foundFreeCb(pbrIndex, recordId) {
       contact.pbrIndex = pbrIndex;
       contact.recordId = recordId;
       ICCContactHelper.updateICCContact(appType, contactType, contact, pin2, onsuccess, onerror);
     };
 
     // Find free record first.
     ICCContactHelper.findFreeICCContact(appType, contactType, foundFreeCb, onerror);
@@ -13500,16 +13900,18 @@ ICCContactHelperObject.prototype = {
    * @param appType       One of CARD_APPTYPE_*.
    * @param contactType   "adn" or "fdn".
    * @param contact       The contact will be updated.
    * @param pin2          PIN2 is required for FDN.
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   updateICCContact: function(appType, contactType, contact, pin2, onsuccess, onerror) {
+    let ICCRecordHelper = this.context.ICCRecordHelper;
+
     switch (contactType) {
       case "adn":
         if (!this.hasDfPhoneBook(appType)) {
           ICCRecordHelper.updateADNLike(ICC_EF_ADN, contact, null, onsuccess, onerror);
         } else {
           this.updateUSimContact(contact, onsuccess, onerror);
         }
         break;
@@ -13535,17 +13937,17 @@ ICCContactHelperObject.prototype = {
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   readUSimContacts: function(onsuccess, onerror) {
     let gotPbrCb = function gotPbrCb(pbrs) {
       this.readAllPhonebookSets(pbrs, onsuccess, onerror);
     }.bind(this);
 
-    ICCRecordHelper.readPBR(gotPbrCb, onerror);
+    this.context.ICCRecordHelper.readPBR(gotPbrCb, onerror);
   },
 
   /**
    * Read all Phonebook sets.
    *
    * @param pbrs          All Phonebook Reference Files read.
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
@@ -13583,28 +13985,29 @@ ICCContactHelperObject.prototype = {
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   readPhonebookSet: function(pbr, onsuccess, onerror) {
     let gotAdnCb = function gotAdnCb(contacts) {
       this.readSupportedPBRFields(pbr, contacts, onsuccess, onerror);
     }.bind(this);
 
-    ICCRecordHelper.readADNLike(pbr.adn.fileId, gotAdnCb, onerror);
+    this.context.ICCRecordHelper.readADNLike(pbr.adn.fileId, gotAdnCb, onerror);
   },
 
   /**
    * Read supported Phonebook fields.
    *
    * @param pbr         Phone Book Reference file.
    * @param contacts    Contacts stored on ICC.
    * @param onsuccess   Callback to be called when success.
    * @param onerror     Callback to be called when error.
    */
   readSupportedPBRFields: function(pbr, contacts, onsuccess, onerror) {
+    let ICCContactHelper = this.context.ICCContactHelper;
     let fieldIndex = 0;
     (function readField() {
       let field = USIM_PBR_FIELDS[fieldIndex];
       fieldIndex += 1;
       if (!field) {
         if (onsuccess) {
           onsuccess(contacts);
         }
@@ -13627,16 +14030,17 @@ ICCContactHelperObject.prototype = {
   readPhonebookField: function(pbr, contacts, field, onsuccess, onerror) {
     if (!pbr[field]) {
       if (onsuccess) {
         onsuccess(contacts);
       }
       return;
     }
 
+    let ICCContactHelper = this.context.ICCContactHelper;
     (function doReadContactField(n) {
       if (n >= contacts.length) {
         // All contact's fields are read.
         if (onsuccess) {
           onsuccess(contacts);
         }
         return;
       }
@@ -13680,16 +14084,17 @@ ICCContactHelperObject.prototype = {
           }
         }
 
         if (onsuccess) {
           onsuccess();
         }
       }.bind(this);
 
+      let ICCRecordHelper = this.context.ICCRecordHelper;
       // Detect EF to be read, for anr, it could have anr0, anr1,...
       let ef = field.startsWith(USIM_PBR_ANR) ? USIM_PBR_ANR : field;
       switch (ef) {
         case USIM_PBR_EMAIL:
           ICCRecordHelper.readEmail(fileId, fileType, recordId, gotFieldCb, onerror);
           break;
         case USIM_PBR_ANR:
           ICCRecordHelper.readANR(fileId, fileType, recordId, gotFieldCb, onerror);
@@ -13731,17 +14136,18 @@ ICCContactHelperObject.prototype = {
         let indexInIAP = pbr[field].indexInIAP;
         let recordId = iap[indexInIAP];
 
         if (onsuccess) {
           onsuccess(recordId);
         }
       }.bind(this);
 
-      ICCRecordHelper.readIAP(pbr.iap.fileId, contact.recordId, gotIapCb, onerror);
+      this.context.ICCRecordHelper.readIAP(pbr.iap.fileId, contact.recordId,
+                                           gotIapCb, onerror);
     } else {
       if (DEBUG) {
         debug("USIM PBR files in Type 3 format are not supported.");
       }
       onerror(CONTACT_ERR_REQUEST_NOT_SUPPORTED);
     }
   },
 
@@ -13760,43 +14166,45 @@ ICCContactHelperObject.prototype = {
           debug(CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK);
         }
         onerror(CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK);
         return;
       }
       this.updatePhonebookSet(pbr, contact, onsuccess, onerror);
     }.bind(this);
 
-    ICCRecordHelper.readPBR(gotPbrCb, onerror);
+    this.context.ICCRecordHelper.readPBR(gotPbrCb, onerror);
   },
 
   /**
    * Update fields in Phonebook Reference File.
    *
    * @param pbr           Phonebook Reference File to be read.
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   updatePhonebookSet: function(pbr, contact, onsuccess, onerror) {
     let updateAdnCb = function() {
       this.updateSupportedPBRFields(pbr, contact, onsuccess, onerror);
     }.bind(this);
 
-    ICCRecordHelper.updateADNLike(pbr.adn.fileId, contact, null, updateAdnCb, onerror);
+    this.context.ICCRecordHelper.updateADNLike(pbr.adn.fileId, contact, null,
+                                               updateAdnCb, onerror);
   },
 
   /**
    * Update supported Phonebook fields.
    *
    * @param pbr         Phone Book Reference file.
    * @param contact     Contact to be updated.
    * @param onsuccess   Callback to be called when success.
    * @param onerror     Callback to be called when error.
    */
   updateSupportedPBRFields: function(pbr, contact, onsuccess, onerror) {
+    let ICCContactHelper = this.context.ICCContactHelper;
     let fieldIndex = 0;
     (function updateField() {
       let field = USIM_PBR_FIELDS[fieldIndex];
       fieldIndex += 1;
       if (!field) {
         if (onsuccess) {
           onsuccess();
         }
@@ -13840,16 +14248,18 @@ ICCContactHelperObject.prototype = {
    *
    * @param pbr           The phonebook reference file.
    * @param contact       The contact needs to be updated.
    * @param field         Phonebook field to be updated.
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   updateContactFieldType1: function(pbr, contact, field, onsuccess, onerror) {
+    let ICCRecordHelper = this.context.ICCRecordHelper;
+
     if (field === USIM_PBR_EMAIL) {
       ICCRecordHelper.updateEmail(pbr, contact.recordId, contact.email, null, onsuccess, onerror);
     } else if (field === USIM_PBR_ANR0) {
       let anr = Array.isArray(contact.anr) ? contact.anr[0] : null;
       ICCRecordHelper.updateANR(pbr, contact.recordId, anr, null, onsuccess, onerror);
     } else {
      if (DEBUG) {
        debug("Unsupported field :" + field);
@@ -13863,16 +14273,18 @@ ICCContactHelperObject.prototype = {
    *
    * @param pbr           The phonebook reference file.
    * @param contact       The contact needs to be updated.
    * @param field         Phonebook field to be updated.
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   updateContactFieldType2: function(pbr, contact, field, onsuccess, onerror) {
+    let ICCRecordHelper = this.context.ICCRecordHelper;
+
     // Case 1 : EF_IAP[adnRecordId] doesn't have a value(0xff)
     //   Find a free recordId for EF_field
     //   Update field with that free recordId.
     //   Update IAP.
     //
     // Case 2: EF_IAP[adnRecordId] has a value
     //   update EF_field[iap[field.indexInIAP]]
 
@@ -13915,16 +14327,18 @@ ICCContactHelperObject.prototype = {
    *
    * @param pbr           The phonebook reference file.
    * @param contact       The contact needs to be updated.
    * @param field         Phonebook field to be updated.
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    */
   addContactFieldType2: function(pbr, contact, field, onsuccess, onerror) {
+    let ICCRecordHelper = this.context.ICCRecordHelper;
+
     let successCb = function successCb(recordId) {
       let updateCb = function updateCb() {
         this.updateContactFieldIndexInIAP(pbr, contact.recordId, field, recordId, onsuccess, onerror);
       }.bind(this);
 
       if (field === USIM_PBR_EMAIL) {
         ICCRecordHelper.updateEmail(pbr, recordId, contact.email, contact.recordId, updateCb, onerror);
       } else if (field === USIM_PBR_ANR0) {
@@ -13949,51 +14363,51 @@ ICCContactHelperObject.prototype = {
    * @param recordNumber  The record identifier of EF_IAP.
    * @param field         Phonebook field.
    * @param value         The value of 'field' in IAP.
    * @param onsuccess     Callback to be called when success.
    * @param onerror       Callback to be called when error.
    *
    */
   updateContactFieldIndexInIAP: function(pbr, recordNumber, field, value, onsuccess, onerror) {
+    let ICCRecordHelper = this.context.ICCRecordHelper;
+
     let gotIAPCb = function gotIAPCb(iap) {
       iap[pbr[field].indexInIAP] = value;
       ICCRecordHelper.updateIAP(pbr.iap.fileId, recordNumber, iap, onsuccess, onerror);
     }.bind(this);
     ICCRecordHelper.readIAP(pbr.iap.fileId, recordNumber, gotIAPCb, onerror);
   },
 };
 
 /**
  * Global stuff.
  */
 
-// Initialize buffers. This is a separate function so that unit tests can
-// re-initialize the buffers at will.
-let Buf = new BufObject();
+let Buf = new BufObject(this);
 Buf.init();
 
-let RIL = new RilObject();
+let RIL = new RilObject(this);
 RIL.initRILState();
 
-let GsmPDUHelper = new GsmPDUHelperObject();
+let GsmPDUHelper = new GsmPDUHelperObject(this);
 let BitBufferHelper = new BitBufferHelperObject();
-let CdmaPDUHelper = new CdmaPDUHelperObject();
-let ICCPDUHelper = new ICCPDUHelperObject();
-let StkCommandParamsFactory = new StkCommandParamsFactoryObject();
-let StkProactiveCmdHelper = new StkProactiveCmdHelperObject();
-let ComprehensionTlvHelper = new ComprehensionTlvHelperObject();
-let BerTlvHelper = new BerTlvHelperObject();
-let ICCFileHelper = new ICCFileHelperObject();
-let ICCIOHelper = new ICCIOHelperObject();
-let ICCRecordHelper = new ICCRecordHelperObject();
-let SimRecordHelper = new SimRecordHelperObject();
-let RuimRecordHelper = new RuimRecordHelperObject();
-let ICCUtilsHelper = new ICCUtilsHelperObject();
-let ICCContactHelper = new ICCContactHelperObject();
+let CdmaPDUHelper = new CdmaPDUHelperObject(this);
+let ICCPDUHelper = new ICCPDUHelperObject(this);
+let StkCommandParamsFactory = new StkCommandParamsFactoryObject(this);
+let StkProactiveCmdHelper = new StkProactiveCmdHelperObject(this);
+let ComprehensionTlvHelper = new ComprehensionTlvHelperObject(this);
+let BerTlvHelper = new BerTlvHelperObject(this);
+let ICCFileHelper = new ICCFileHelperObject(this);
+let ICCIOHelper = new ICCIOHelperObject(this);
+let ICCRecordHelper = new ICCRecordHelperObject(this);
+let SimRecordHelper = new SimRecordHelperObject(this);
+let RuimRecordHelper = new RuimRecordHelperObject(this);
+let ICCUtilsHelper = new ICCUtilsHelperObject(this);
+let ICCContactHelper = new ICCContactHelperObject(this);
 
 function onRILMessage(/*unused*/aClientId, data) {
   Buf.processIncoming(data);
 }
 
 onmessage = function onmessage(event) {
   RIL.handleChromeMessage(event.data);
 };